我有一个函数f(char **p)
,我想用最简单的方法来调用它。
我尝试过
char ** p = {"a", "b"};
f(p);
并得到:
标量对象在初始化程序中需要一个元素
所以我将其更改为
char * p[2] = {"a", "b"};
f(p);
没问题[只需char * p[]
]也可以。
为什么不能像下面这样即时创建指针数组?
f({"a", "b"});
答案 0 :(得分:41)
这给出了警告:
char ** p = {"a", "b"};
因为p
不是数组。
这也不合法:
f({"a", "b"});
因为表达式中不允许使用花括号,但可以将其用作初始化程序。
可以像使用复合文字那样动态创建数组:
f((char *[]){"a", "b"});
您还可以使用复合文字来初始化临时文件:
char ** p = (char *[]){"a", "b"};
与第一条语句不同,这是有效的,因为文字是char *[2]
类型的数组,并且将衰减为char **
,可用于初始化此类型的变量。
有关复合文字的更多详细信息,请参见C standard的6.5.2.5节。
答案 1 :(得分:14)
此声明char ** p = {"a", "b"};
会触发警告,因为C不知道如何解释{
}
花括号的内容:
char**
表示它是单个指向字符的指针{
}
的内容指定了两项。您需要通过在花括号前面指定一个类型来告诉C您正在初始化一个指向带有匿名数组初始元素的指针的指针:
char ** p = (char*[]){"a", "b"}
此构造称为“复合文字”。它可以用于声明中,但也可以用作表达式。
注意:如果您打算将类似的数组传递给函数,则需要提供一种确定数组大小的方法。一种方法是传递NULL
来“终止”数组,如下所示:
void f(char **p) {
int i = 0;
while (*p) {
printf("%d:%s\n", i++, *p++);
}
}
int main(void) {
f((char*[]){"a", "b", NULL});
return 0;
}
答案 2 :(得分:5)
C99和更高版本添加了compound literals正是出于以下目的:动态创建数组和结构
示例:
struct foo {int a; char b[2];} structure;
structure = ((struct foo) {1, 'a', 0});
int *y = (int []) {1, 2, 3};
int *z = (int []) {1};
除了标准C99和更高版本之外,GCC还提供此功能作为扩展。
您可以的话
f((char *[]){"a","b"});
(char *[]){"a","b"}
是一个复合文字,它可以动态地创建一个指向char
的2个指针的数组。