Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用c标记粘贴来访问结构中的字段_C_Struct - Fatal编程技术网

使用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

我正在尝试使用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”不提供有效的预处理令牌

我想补充一点:

 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