C - 字符数组和字符指针

标签 c arrays pointers c-strings string-literals

为什么我无法定义 一个数组

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/

相关文章:

c - C 中半已知输入的指针与数组

c++ - 父进程发生了什么?

python - 在 Python 中访问静态 C 函数

C、无法正确打印结构体内部的数据

C到汇编的转换问题

c - 如何使用一维访问 C 中的二维数组

c - 查找重复项和次数

c - 对 Data.Vector 进行基准测试时的时间出人意料地低

只有指针才能保存 NULL 值吗?

c++ - 指向容器上的对象