动态使用c中的结构
Dynamically use a structure in c
在我的代码中有多个结构,如 structure_1、structure_2、structure_3 等。我正在尝试编写一个宏,使我能够 select正确的结构(select 的结构基于另一个值)。我不能透露确切的代码...但它类似于此
#include <stdio.h>
#define concat(X,Y) X##_##Y
#define typename(X){\
if(val==0)\
concat(X,1)\
else\
concat(X,2)\
}
int val;
typedef struct {
int x;
char c;
}structure_1;
typedef struct {
int y;
char c;
}structure_2;
int main() {
val = 0;
typename(structure) abc;
abc.x = 0;
printf("%d\n",abc.x);
}
这不起作用并且出现问题
24 11 E:\DEV\concat.c [Error] expected expression before 'structure_1'
3 22 E:\DEV\concat.c [Note] in definition of macro 'concat'
24 2 E:\DEV\concat.c [Note] in expansion of macro 'typename'
25 2 E:\DEV\concat.c [Error] 'abc' undeclared (first use in this function)
25 2 E:\DEV\concat.c [Note] each undeclared identifier is reported only once for each function it appears in
使用 if-else 语句是一种选择,但它必须在许多结构和许多地方完成,所以我想避免这种情况。请建议我做错了什么或任何其他方法。
您的宏不起作用的原因是它导致 if (val == 0) structure_1;
无法编译,因为您没有声明变量。 abc
部分没有注入到宏中,所以它只出现在处理过的宏扩展的末尾: abc
只被声明为 structure_2
.[=15= 的变量]
这很容易解决:您还必须将变量名作为宏的参数。这样做然后......现在很明显已经毁了,因为你的变量只存在于 if-else 块中,这是你不想要的。
此时应该很明显,这根本不是 C 的基本工作方式。泛型没有得到很好的支持,这是一件好事,因为泛型与 C 作为一种语言试图实现的目标无关。您应该问问自己,为什么要强制语言以这种方式运行。你这样做的意义何在?
无论如何,从某种意义上说,有一种方法可以解决这个问题:工会。联合允许您从本质上将不同类型组合成一种类型。这有一个明显的缺点,即强制从联合声明的变量始终是最大类型的大小。如果您从一个 1 字节的 char 和一个 100 字节的结构中创建联合,则声明的每个变量将始终占用 100 字节。另一方面,如果您将相同大小的结构拼凑在一起,则没有特别的惩罚。
一个简单的演示:
struct t {
union {
int x; float y;
};
};
int main() {
struct t a = {0};
printf("%d\n", a.x);
printf("%d\n", a.y);
printf("%d\n", sizeof(a)); // 4
return 0;
}
在我的代码中有多个结构,如 structure_1、structure_2、structure_3 等。我正在尝试编写一个宏,使我能够 select正确的结构(select 的结构基于另一个值)。我不能透露确切的代码...但它类似于此
#include <stdio.h>
#define concat(X,Y) X##_##Y
#define typename(X){\
if(val==0)\
concat(X,1)\
else\
concat(X,2)\
}
int val;
typedef struct {
int x;
char c;
}structure_1;
typedef struct {
int y;
char c;
}structure_2;
int main() {
val = 0;
typename(structure) abc;
abc.x = 0;
printf("%d\n",abc.x);
}
这不起作用并且出现问题
24 11 E:\DEV\concat.c [Error] expected expression before 'structure_1'
3 22 E:\DEV\concat.c [Note] in definition of macro 'concat'
24 2 E:\DEV\concat.c [Note] in expansion of macro 'typename'
25 2 E:\DEV\concat.c [Error] 'abc' undeclared (first use in this function)
25 2 E:\DEV\concat.c [Note] each undeclared identifier is reported only once for each function it appears in
使用 if-else 语句是一种选择,但它必须在许多结构和许多地方完成,所以我想避免这种情况。请建议我做错了什么或任何其他方法。
您的宏不起作用的原因是它导致 if (val == 0) structure_1;
无法编译,因为您没有声明变量。 abc
部分没有注入到宏中,所以它只出现在处理过的宏扩展的末尾: abc
只被声明为 structure_2
.[=15= 的变量]
这很容易解决:您还必须将变量名作为宏的参数。这样做然后......现在很明显已经毁了,因为你的变量只存在于 if-else 块中,这是你不想要的。
此时应该很明显,这根本不是 C 的基本工作方式。泛型没有得到很好的支持,这是一件好事,因为泛型与 C 作为一种语言试图实现的目标无关。您应该问问自己,为什么要强制语言以这种方式运行。你这样做的意义何在?
无论如何,从某种意义上说,有一种方法可以解决这个问题:工会。联合允许您从本质上将不同类型组合成一种类型。这有一个明显的缺点,即强制从联合声明的变量始终是最大类型的大小。如果您从一个 1 字节的 char 和一个 100 字节的结构中创建联合,则声明的每个变量将始终占用 100 字节。另一方面,如果您将相同大小的结构拼凑在一起,则没有特别的惩罚。
一个简单的演示:
struct t {
union {
int x; float y;
};
};
int main() {
struct t a = {0};
printf("%d\n", a.x);
printf("%d\n", a.y);
printf("%d\n", sizeof(a)); // 4
return 0;
}