使用c Token-Pasting访问struct中的字段

时间:2013-11-18 19:28:24

标签: c struct

我正在尝试使用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)定义

由于 莫蒂

3 个答案:

答案 0 :(得分:9)

您根本不需要令牌粘贴:

#define BUILD_FIELD(field) my_struct.field

根据gcc manual标记粘贴应该在连接后产生标识符或数字。错误是由于.a不是。

答案 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

它用于标记化。您的用例是“典型”宏变量替换。