在C

时间:2017-05-30 13:50:35

标签: c macros

我正在尝试下面的代码序列...我的目的是生成一个新的字符串,该字符串使用宏的输入参数作为数字,并在连接时将其视为int。但看起来它将它视为一个字符串。有没有办法实现这个目标?

typedef enum
{
    HELLO0BYE = 0,
    HELLO1BYE = 1,
    HELLO2BYE = 2,
    HELLO3BYE = 3,
    HELLO4BYE = 4,
    HELLO5BYE = 5,

} enum_test;

#define GEN_NEW(x) HELLO ##x## BYE
void main()
{
    enum_test input = 5;
    enum_test output;
    output = GEN_NEW(input);
}

理想情况下,我希望能够以算法的方式遍历枚举。

3 个答案:

答案 0 :(得分:2)

据我了解你的问题,不,你不能。但我怀疑我并不完全确定你要做什么。

宏已经过预处理。这意味着在代码编译之前宏将被替换。因此,当您使用GEN_NEW宏时,所有编译器都知道“数字”是它是一个字符串。因此,您无法将运行时变量传递给宏。

希望有所帮助。

答案 1 :(得分:1)

当编译器处理上面的代码时,我们得到以下输出:

# 1 "Test1.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "Test1.c"
typedef enum
{
    HELLO0BYE = 0,
    HELLO1BYE = 1,
    HELLO2BYE = 2,
    HELLO3BYE = 3,
    HELLO4BYE = 4,
    HELLO5BYE = 5,

} enum_test;


void main()
{
    enum_test input = 5;
    enum_test output;
    output = HELLOinputBYE;
}

当您查看上面的代码时,您可以看到以下行有错误:

output = HELLOinputBYE;

注意:要在预处理阶段后停止编译器使用&#39; -E&#39;开关。我在gcc编译器上使用了以下命令:

gcc -E -o TestPreprocessedFile.txt Test1.c

这里&#39; Test1.c&#39;是源文件和&#39; TestPreprocessedFile.txt&#39;是输出文件。

有关gcc编译器选项的更多信息,请参阅Options Controlling the Kind of Output

答案 2 :(得分:0)

我不知道你的实施的确切逻辑,所以我不会讨论。你可以用这个:

#define CONV2STRING(X) #X
#define TO_STRING(X) CONV2STRING(X)
#define EXPAND(Y) Y
#define MERGER( X, Y) X##Y
#define MERGE( X, Y) MERGER( X, Y)

#define SAY_HELLO HELLO
#define SAY_BYE BYE

typedef enum {
    HELLO0BYE = 0,
    HELLO1BYE = 1,
    HELLO2BYE = 2,
    HELLO3BYE = 3,
    HELLO4BYE = 4,
    HELLO5BYE = 5,
} enum_test;

const static struct {
    enum_test      value;
    const char *str;
} conversion [] = {
    {HELLO0BYE, "HELLO0BYE"},
    {HELLO1BYE, "HELLO1BYE"},
    {HELLO2BYE, "HELLO2BYE"},
    {HELLO3BYE, "HELLO3BYE"},
    {HELLO4BYE, "HELLO4BYE"},
    {HELLO5BYE, "HELLO5BYE"},
};

int StringToEnum (const char *str) {
     int j;
     for (j = 0;  j < sizeof (conversion) / sizeof (conversion[0]);  ++j)
         if (!strcmp (str, conversion[j].str))
             return conversion[j].value;
     return -1;
}

int main(int argc, char** argv)
{
    enum_test output;

    #define INPUT 5
    output = StringToEnum(TO_STRING (MERGE(MERGE( SAY_HELLO, EXPAND(INPUT)), SAY_BYE)));
    printf( "Macro Expansion : %s\n", TO_STRING (MERGE(MERGE( SAY_HELLO, EXPAND(INPUT)), SAY_BYE)));
    printf("output = %d\n", output);
    #undef INPUT

    #define INPUT 4
    output = StringToEnum(TO_STRING (MERGE(MERGE( SAY_HELLO, EXPAND(INPUT)), SAY_BYE)));
    printf( "Macro Expansion : %s\n", TO_STRING (MERGE(MERGE( SAY_HELLO, EXPAND(INPUT)), SAY_BYE)));
    printf("output = %d\n", output);
    #undef INPUT
}

注意:我发现从字符串到枚举here的优雅转换。