为什么我无法定义 一个数组
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);
最佳答案
回答第一个问题,如果我们使用单个深度指针,原理可能会更清楚。出于同样的原因,此代码是非法的:
int *ptr = { 1, 2, 3 };
在 C 中,大括号初始化列表不是对象(尤其不是数组)。它只能作为一个项目列表,在初始化对象时从中读取初始化器。
ptr
是一个对象,因此最多可以采用一个初始化器,并且该初始化器的预期形式是指针(1
不是)。
事实上这段代码在 C11 6.7.9/11 下是明确非法的:
The initializer for a scalar shall be a single expression, optionally enclosed in braces
但是,存在一个 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" };
关于C - 字符数组和字符指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30532077/