#define DEFAULT_XXX (NUM_1, NUM_2 ) \
{
.data_time = NUM_1, \
.data = NUM_2,
};
typedef struct DEFAULT_XXX_STRUCT {
int* data_time;
int* data;
} SomeSetting;
SomeSetting HAHASetting = DEFAULT_XXX(123,456) ;
我想问为什么这种定义可以初始化“ HAHASetting”对象。 特别是为什么我们只能在#define中使用.data和.data_time?
#define
对C语言一无所知。它仅将令牌替换为另一个令牌。简化它的工作就像替换文本一样。
这样的宏是我个人不喜欢的东西。
您的代码很糟糕,它必须看起来像这样(请参阅我添加的内容和删除的内容):
#define DEFAULT_XXX(NUM_1, NUM_2 ) \
{ \
.data_time = NUM_1, \
.data = NUM_2, \
}
typedef struct DEFAULT_XXX_STRUCT {
int* data_time;
int* data;
} SomeSetting;
SomeSetting HAHASetting = DEFAULT_XXX(123,456) ;
如果使用-E选项(gcc)进行编译,则会得到扩展的代码:
typedef struct DEFAULT_XXX_STRUCT {
int* data_time;
int* data;
} SomeSetting;
SomeSetting HAHASetting = { .data_time = 123, .data = 456, } ;
首先,提供的代码有误。我猜它看起来像这样,从您那里得到的:
#define DEFAULT_XXX( NUM_1, NUM_2 ) \
{ \
.data_time = NUM_1, \
.data = NUM_2 \
};
typedef struct DEFAULT_XXX_STRUCT {
int* data_time;
int* data;
} SomeSetting;
SomeSetting HAHASetting = DEFAULT_XXX(123,456) ;
请注意,属于\
宏的每一行之后都必须有一个#define
,但最后一行以;
结尾。 \
的作用是编译器将考虑宏的下一行。
如果忽略\
放在宏的另一部分之后的行中,这将是语法错误,编译器会在尝试进行编译时很快提示您。
没有全部 \
,您需要将整个宏写在一行中,例如:
#define DEFAULT_XXX( NUM_1, NUM_2 ) { .data_time = NUM_1, .data = NUM_2 };
[DEFAULT_XXX
必须后跟其列表( NUM_1, NUM_2 )
,不带空格。
[data_time
和data
都是指向int
的类型的指针,但是传递的值是int
的类型。
我想问为什么这种
#define
可以初始化(ialize)"HAHASetting"
对象?
#define
宏基本上用于替换文本,充当函数或用作本示例中提供的初始化程序(可能还有其他用途,但现在覆盖所有内容太多,因此也与回答您的问题无关)。 C预处理器是用于扩展宏并替换相应标记的处理器。
宏DEFAULT_XXX()
用于通过其列表中的给定值初始化结构成员data_time
和data
。
完成的预处理代码将等效于:
typedef struct DEFAULT_XXX_STRUCT {
int* data_time;
int* data;
} SomeSetting;
SomeSetting HAHASetting = { .data_time = 123, .data = 456 };
特别是为什么我们只能在
.data
中包含.data_time
和#define
?
.
运算符左侧的标识符是多余的,因为根据分配的编译器知道要寻址的对象。