为什么我无法定义 数组
char **pp={ "123", "456", "789" };
但我可以将它定义为char * [],并将其发送给一个将其作为char **接受的函数
char *pp[]={ "123", "456", "789" };
fun(pp);
void fun(char **pointerToPointer)
{
//++(**pointerToPointer);//error
printf("%s", *pointerToPointer);
}
//output::"123"
为什么我不能增加
++(**pointerToPointer);
答案 0 :(得分:2)
要回答第一个问题,如果我们使用单一深度的指针,原则可能会更清楚。出于同样的原因,此代码是非法的:
int *ptr = { 1, 2, 3 };
在C中,支撑的初始化列表不是对象(尤其不是数组)。它只能作为初始化对象时从中读取初始化程序的项目列表。
ptr
是一个对象,因此最多可以使用一个初始值设定项,并且该初始值设定项的预期形式是指针(1
不是)。
事实上,根据C11 6.7.9 / 11:
,此代码明显是非法的标量的初始值设定项应为单个表达式,可选择用大括号括起来
但是,有一个gcc错误/功能,它允许标量的多余初始值设定项并忽略它们。此外,某些编译器可能“有用”并且“仅”发出警告,并初始化ptr
以指向地址1
,无论在哪里。
“标量”表示不是结构或数组的对象。
从C99开始,你可以写:
int *ptr = (int []){1, 2, 3};
创建一个数组(使用与ptr
相同的存储持续时间)并在其第一个元素处指向ptr
。
这个数组是可变的;对于不可变的,请使用int const *ptr = (int const[]){1, 2, 3};
。
int
替换char *
,我们看到您可以写:
char **p = (char *[]){ "123", "456", "789" };
在这种情况下数组中的指针是可变的,但它们指向的东西(即字符串文字)仍然不是。
请注意,在处理字符串文字时应始终使用char const *
,因为它们不可变。字符串文字具有类型char [N]
的事实是从const
添加到C之前的历史宿醉。所以:
char const **pp = (char const *[]){ "123", "456", "789" };
或使用不可变的字符串指针:
char const *const *pp = (char const *const []){ "123", "456", "789" };
答案 1 :(得分:1)
此处char *pp[]={ "123", "456", "789" };
是正确的,因为:
char
指针时,它可以正常工作。但是在char **pp={ "123", "456", "789" };
由于 CoolGuy 说++(**pointerToPointer)
这是错误的,因为它访问了1
"123"
字符串,并尝试将1
的值更改为2
,因为这些是字符串文字,所以无法完成分配。您只能看到print的增量值:
printf("%c\n", **pointerToPointer+1);
这将提供输出:2
您可以通过评论中 CoolGuy 提供的解决方案来解决问题 -
char *pp[]={ "123", "456", "789" };
更改为char pp[][100]={ "123", "456", "789" };
void fun(char **pointerToPointer)
更改为void fun(char (*pointerToPointer)[100])
这是正确的,因为**pointerToPointer
的值正在变化。
这些是我的理由。而警告:
warning: excess elements in scalar initializer [enabled by default]
你可以看到here中的链接,这对我来说是最好的解释。