使用c标记粘贴来访问结构中的字段
我正在尝试使用c标记粘贴(##)访问结构字段,如下所示:使用c标记粘贴来访问结构中的字段,c,struct,C,Struct,我正在尝试使用c标记粘贴(##)访问结构字段,如下所示: 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”不提供有效的预处理令牌 我想补充一点: ty
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)定义它
谢谢
Moti您根本不需要粘贴令牌:
#define BUILD_FIELD(field) my_struct.field
根据标记,粘贴应在连接后生成标识符或数字。该错误是由于
.a
不是其中之一。所需的只是使用宏替换字符串字段。试试这个:
#定义构建字段(字段)我的结构字段
因此,以下代码将起作用:
#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;
}
它运行时与代码相同,没有使用##
字符串化。因此,我们的编译器之间显然有些不同。
无论如何,我希望我最初的断言没有增加太多的混乱。你的问题今天给了我一些教训。谢谢(+1)
处理您最近的帖子编辑:
首先,此修改将导致TMP_T中未知字段名的编译错误:
BUILD_FIELD(tmp_str, name) = 7;
这里是一个讨论预处理、编译和链接的(本次讨论最感兴趣的是预处理和编译部分)。除此之外,它还讨论了何时使用宏
此外,关于线路:
if((name == "a") || (name == "b"))
进行字符串比较时,不使用=
strcmp()
,甚至strstrstr()
都用于字符串比较。如果使用某些“结构”创建结构,则需要粘贴。例如:
typedef struct
{
int tmp_a;
int tmp_b;
} TMP_T;
#define BUILD_FIELD(field) my_struct.tmp_##field
它用于标记化。您的用例是“典型的”宏变量替换。。至少说说你为什么投反对票。如果有问题,我会解决。##
在C..@perreal中是非常合法的-我可以更正。(并且学到了一些我不知道的东西)我将修改我的帖子。谢谢你。@KristerAndersson-我真的不知道。我修改了我的帖子。谢谢你的链接:)谢谢你让我在##
上陷入困境。我以前从未用过它,但现在很可能会用。谢谢,事实上,我没有问正确的问题。我将该字段作为指向如下函数的指针:typedef struct{inta;intb;}TMP\T#定义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;}我现在很好奇。我按照答案中显示的方式运行代码,除了像OP一样使用##
之外。它没有引起错误。根据我在报纸上看到的,它不应该这样。那么,你能详细说明一下你所说的OP错误的原因吗?(错误的原因是.a也不是。)@Ryker,看看答案中的链接,它解释得很清楚。粘贴后,gcc希望有一个标识符或数字。您正在使用MS编译器进行编译,因此其行为可能会有所不同。在任何情况下,粘贴都是不必要的。@moti-你能把所有的内容都放在你原来的帖子里,加上一些格式,这样更容易阅读,地址也更清楚吗?这是完全错误的。你不能把宏和运行时的东西混在一起。宏处理在预处理之后结束,甚至在编译之前。也许你需要一种脚本语言。最后,您不能将字符串与==
进行比较。请在下面的我的答案中说明您上次编辑的内容。同意@perreal的两个观察结果。
typedef struct
{
int tmp_a;
int tmp_b;
} TMP_T;
#define BUILD_FIELD(field) my_struct.tmp_##field