在C中未正确替换宏的参数

在C中未正确替换宏的参数,c,macros,C,Macros,我正在尝试下面的代码序列。。。我的目的是生成一个新字符串,该字符串使用宏的输入参数作为数字,并在进行串联时将其视为int。但看起来像是把它当作一根绳子。有没有办法做到这一点 typedef enum { HELLO0BYE = 0, HELLO1BYE = 1, HELLO2BYE = 2, HELLO3BYE = 3, HELLO4BYE = 4, HELLO5BYE = 5, } enum_test; #define GEN_NEW(x)

我正在尝试下面的代码序列。。。我的目的是生成一个新字符串,该字符串使用宏的输入参数作为数字,并在进行串联时将其视为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);
}

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

我理解你的问题,不,你不能。但我怀疑我不完全确定你想做什么

宏是预处理的。这意味着在编译代码之前,宏已被替换。因此,当您使用GEN_NEW宏时,编译器只知道“number”是一个字符串。所以不能将运行时变量传递给宏


希望能有所帮助。

我理解你的问题,不,你不能。但我怀疑我不完全确定你想做什么

宏是预处理的。这意味着在编译代码之前,宏已被替换。因此,当您使用GEN_NEW宏时,编译器只知道“number”是一个字符串。所以不能将运行时变量传递给宏


希望有帮助。

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

# 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;
}
注意:要在预处理阶段后停止编译器,请使用“-E”开关。我在gcc编译器上使用了以下内容:

gcc -E -o TestPreprocessedFile.txt Test1.c
这里的“Test1.c”是源文件,“TestPreprocessedFile.txt”是输出文件


有关gcc编译器选项的更多信息,请参阅

当编译器处理上述代码时,我们将获得以下输出:

# 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;
}
注意:要在预处理阶段后停止编译器,请使用“-E”开关。我在gcc编译器上使用了以下内容:

gcc -E -o TestPreprocessedFile.txt Test1.c
这里的“Test1.c”是源文件,“TestPreprocessedFile.txt”是输出文件


有关gcc编译器选项的更多信息,请参阅

我不知道您的实现的确切逻辑,因此我将不进行讨论。您可以使用以下选项:

#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
}
#定义CONV2STRING(X)#X
#定义到_字符串(X)CONV2STRING(X)
#定义展开(Y)Y
#定义合并(X,Y)X##Y
#定义合并(X,Y)合并(X,Y)
#定义说你好
#定义说再见
类型定义枚举{
HELLO0BYE=0,
HELLO1BYE=1,
HELLO2BYE=2,
你好,再见,
HELLO4BYE=4,
HELLO5BYE=5,
}枚举检验;
常量静态结构{
枚举检验值;
常量字符*str;
}转换[]={
{HELLO0BYE,“HELLO0BYE”},
{HELLO1BYE,“HELLO1BYE”},
{HELLO2BYE,“HELLO2BYE”},
{HELLO3BYE,“HELLO3BYE”},
{HELLO4BYE,“HELLO4BYE”},
{HELLO5BYE,“HELLO5BYE”},
};
int StringToEnum(常量字符*str){
int j;
对于(j=0;j

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

我不知道您的实现的确切逻辑,因此我将不进行讨论。您可以使用以下选项:

#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
}
#定义CONV2STRING(X)#X
#定义到_字符串(X)CONV2STRING(X)
#定义展开(Y)Y
#定义合并(X,Y)X##Y
#定义合并(X,Y)合并(X,Y)
#定义说你好
#定义说再见
类型定义枚举{
HELLO0BYE=0,
HELLO1BYE=1,
HELLO2BYE=2,
你好,再见,
HELLO4BYE=4,
HELLO5BYE=5,
}枚举检验;
常量静态结构{
枚举检验值;
常量字符*str;
}转换[]={
{HELLO0BYE,“HELLO0BYE”},
{HELLO1BYE,“HELLO1BYE”},
{HELLO2BYE,“HELLO2BYE”},
{HELLO3BYE,“HELLO3BYE”},
{HELLO4BYE,“HELLO4BYE”},
{HELLO5BYE,“HELLO5BYE”},
};
int StringToEnum(常量字符*str){
int j;
对于(j=0;j

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

number
在预处理阶段没有值。它只是预处理器的一个标记。您可以添加所需输出的示例吗?请注意,
##
应该出现在到标识符之间,就像宏扩展中的标记一样。第一个
##
是错误的。每次尝试这样做时,请思考:什么代码将从预处理器传递到编译器?像预处理器一样思考@KAM在这种情况下,您应该更新您的问题以显示真正的问题。无论如何,正如其他人已经说过的:宏不是运行时工具。
number
在预处理
阶段上没有值。它只是预处理器的一个标记。您可以添加所需输出的示例吗?请注意,
##
应该出现在到标识符之间,就像宏扩展中的标记一样。第一个
##
是错误的