我正在尝试使用c令牌粘贴(##)来访问struct字段,如下所示:
typedef struct
{
int a;
int b;
} TMP_T;
#define BUILD_FIELD(field) my_struct.##field
int main()
{
TMP_T my_struct;
BUILD_FIELD(a) = 5;
return 0;
}
但在编译期间遇到以下错误: 错误:粘贴“。”并且“a”不提供有效的预处理令牌
我想补充一点:
typedef struct {
int a;
int b;
}TMP_T;
#define BUILD_FIELD(my_struct,field) my_struct.##field
void func(char* name)
{
TMP_T tmp_str;
if((name == "a") || (name == "b"))
{
BUILD_FIELD(tmp_str, name) = 7;
printf("%d \n", BUILD_FIELD(a) );
}
}
int main()
{
func("a");
return 1;
}
我应该如何使用宏来访问特定的结构和字段。可能吗?或者因为它是预编译的,所以无法为各种字段(a,b)定义
由于 莫蒂
答案 0 :(得分:9)
答案 1 :(得分:1)
所需的只是使用宏替换字符串field
。试试这个:
#define BUILD_FIELD(field) my_struct.field
。
因此以下代码将起作用:
#include <ansi_c.h>
typedef struct {
int a;
int b;
}TMP_T;
#define BUILD_FIELD(field) my_struct.field
int main(void)
{
TMP_T my_struct;
BUILD_FIELD(a) = 5;
printf("my_struct.a is %d\n",my_struct.a);
BUILD_FIELD(b) = 10;
printf("my_struct.b is %d\n",my_struct.b);
return 0;
}
顺便提一下 ,我还使用以下代码运行上述代码:(在阅读 Krister Andersson's link 之后强>)
#define BUILD_FIELD(field) my_struct.##field
它在不使用##
字符串化的情况下与代码运行相同。所以,我们的编译器之间显然存在一些不同之处
无论如何 ,我希望我原来的断言不会增加太多混乱。你的问题今天给我讲了几课。谢谢! (+1)
解决您最新的帖子编辑:
首先,此修改将导致TMP_T中未知字段名称的编译错误:
BUILD_FIELD(tmp_str, name) = 7;
这是一个讨论预处理,编译和链接的 good link (本次讨论最感兴趣的是预处理和编译部分)。除其他外,它讨论了何时使用宏。
另外,关于这一行:
if((name == "a") || (name == "b"))
进行字符串比较时,不使用==
。 strcmp()
,甚至strstr()
用于字符串比较。
答案 2 :(得分:0)
如果使用某种“结构”创建结构,则需要粘贴。例如:
typedef struct
{
int tmp_a;
int tmp_b;
} TMP_T;
#define BUILD_FIELD(field) my_struct.tmp_##field
它用于标记化。您的用例是“典型”宏变量替换。