Arrays 使用标量初始值设定项初始化字符串数组

Arrays 使用标量初始值设定项初始化字符串数组,arrays,c,string,initialization,Arrays,C,String,Initialization,我是C语言的新手,如果这个问题变得微不足道,那么很抱歉。我已经使用宏(目前)编写了一个项结构初始化,它接受一个方法和一个字符串数组作为方法参数。最后一个参数的初始化会引发有关标量初始值设定项中元素过多的警告 该项是一个包含名称、方法和方法参数的小结构。如您所见,最后一个字段被声明为字符串数组 //mcl\U项目的定义;又称作螨 结构mcl_项{ 字符*名称; void(*方法)(字符*参数[]); 字符**args; }; #定义mitem结构mcl\U项 //创建新的mitem(用户将使用it

我是C语言的新手,如果这个问题变得微不足道,那么很抱歉。我已经使用宏(目前)编写了一个项结构初始化,它接受一个方法和一个字符串数组作为方法参数。最后一个参数的初始化会引发有关标量初始值设定项中元素过多的警告

该项是一个包含名称、方法和方法参数的小结构。如您所见,最后一个字段被声明为字符串数组

//mcl\U项目的定义;又称作螨
结构mcl_项{
字符*名称;
void(*方法)(字符*参数[]);
字符**args;
};
#定义mitem结构mcl\U项
//创建新的mitem(用户将使用item和item0宏)
mitem new_mitem(字符名[MAX_STRLEN],void(*方法)(字符**),int n,字符*arg,…){
//返回没有参数分配的简单mitem
返回((米){
.name=名称,
.方法=方法,
.args=0
});
}
这就是我的宏的样子,在这里我也看到标量初始化应该工作:

//通过宏定义参数数量
#定义ARGSN(…)(int)(sizeof((char*){{uu_VA_ARGS})/sizeof(char*))
//重载new_mitem()以避免使用n参数存储生成的大小
#定义新对象(名称、方法等)\
新字符(名称、方法、ARGSN(uuu VA_ARGS_uuu),(字符*){uuuu VA_ARGS_uuu})
//用于创建带参数项的顶级宏
#定义项(名称、方法等)新项(名称、方法、参数)
//用于创建无参数项的顶级宏
#定义项0(名称、方法)新项(名称、方法、0)
然后在主程序内部初始化项目并访问它们

//项目使用的样板方法
void hello(char*args[]);
无效扩展(字符*参数[]);
int main(){
//初始化项目
mitem item1=项目(“延伸”和延伸“查理”、“三角”);
mitem item2=item0(“你好”、&hello);
//访问项目1
printf(“访问项目:%s\n”,项目1.name);
项目1.方法(项目1.参数);
//访问项目2
printf(“访问项:%s\n”,项2.name);
项目2.方法(项目2.参数);
返回(0);
}
//样板方法定义
void hello(字符*参数[]){
字符名[MAX_STRLEN]=“Bob”;
如果(!args[0]){
strcpy(名称,参数[0]);
}
printf(“你好%s!\n”,名称);
}
无效扩展(字符*参数[]){
你好(args);
printf(“欢迎%s.\n”,参数[1]);
}
带-E标志预编译的gcc响应:

<source>:43:91: warning: excess elements in scalar initializer
   43 |     struct mcl_item item1 = new_mitem("extend", &extend, (int)(sizeof((char *){"Charlie", "Delta"})/sizeof(char *)), (char *){"Charlie", "Delta"});
      |                                                                                           ^~~~~~~
<source>:43:91: note: (near initialization for '(anonymous)')
<source>:43:138: warning: excess elements in scalar initializer
   43 |     struct mcl_item item1 = new_mitem("extend", &extend, (int)(sizeof((char *){"Charlie", "Delta"})/sizeof(char *)), (char *){"Charlie", "Delta"});
      |                                                                                                                                          ^~~~~~~
<source>:43:138: note: (near initialization for '(anonymous)')
:43:91:警告:标量初始值设定项中的元素过多
43 | struct mcl_item item 1=新的字符(“扩展”、&extend,(int)(sizeof((char*){“Charlie”,“Delta”})/sizeof(char*),(char*){“Charlie”,“Delta”});
|                                                                                           ^~~~~~~
:43:91:注意:(接近对“(匿名)”的初始化)
:43:138:警告:标量初始值设定项中的元素过多
43 | struct mcl_item item 1=新的字符(“扩展”、&extend,(int)(sizeof((char*){“Charlie”,“Delta”})/sizeof(char*),(char*){“Charlie”,“Delta”});
|                                                                                                                                          ^~~~~~~
:43:138:注意:(接近“匿名”的初始化)
在使用时,
(char*){{uuu-VA\u-ARGS}
被替换为
(char*){“Charlie”,“Delta”}
。这意味着创建一个
字符*
,并用
“Charlie”
“Delta”
对其进行初始化。然而,
char*
是一回事(指向
char
的指针),而
的“Charlie”和
的“Delta”
是两件事。因此,编译器会警告您初始值设定项太多

您可以使用
(char*[]){{uu VA_ARGS}
创建指向
char*
的指针数组。当用作
sizeof
的操作数(或一元
&
的操作数)时,这将给出数组的大小,因此它将在
ARGSN
宏中工作。否则使用时,数组将自动转换为指向其第一个元素的指针,因此它可用于初始化
args
成员或其他
char**
对象


但是,您的
new_mitem
函数不接受
char**
参数,而是声明
char*arg,…
。您可以将其传递到
\uuu VA_ARGS\uuu
或将其更改为
char**arg
(没有
)并传递到
(char*[]){{uu VA_ARGS}
,请发布一个。是的,对不起。我想这就是您现在所需要的一切。只需使用-E选项并查看预处理的代码。然后开始修改宏直到,我看不出这个初始化有什么问题,为什么“Delta”错了:
struct mcl_item item1=new_mitem(“extend”,&extend,(int)(sizeof((char*){“Charlie”,“Delta”})/sizeof(char*),(char*){“Charlie”,“Delta”})
我现在直接将
\uu VA\u ARGS\uu
作为最后一个参数传递给
new\u mitem()
方法;我已经删除了
char*arg
参数,正如我在阅读
man3stdarg
时发现的那样,最后一个参数的类型并不重要。但我从最后一个参数得到的仍然是一个字符串
“Charlie”
。像
“Delta”
在初始化中没有效果。@DanielFreeman:如何处理变量参数是一个单独的问题。谢谢你指导我。你能帮我找出变量处理的错误吗?或者我应该为此启动一个新线程吗?我发布我的当前代码。好的。。我只需放弃所有的
va_arg
业务,使用简单的指针,就可以更轻松、更少烦人了。