gpt4 book ai didi

c - C/C++ 中的指针/数组语法 (char **p, *p[n])

转载 作者:太空狗 更新时间:2023-10-29 15:14:32 27 4
gpt4 key购买 nike

对于指针,我对何时使用 char ** 或 char * 或 *array[n] 等的声明和函数参数感到困惑。就像函数采用 (*array[n]) 参数一样,我传递给它一个**类型吗?

我尝试使用右-左规则并且知道 p 将是一个指向 char 的指针 (char **p),而 p 是一个包含 n 个指针的数组 (*p[n]),但是有人说 *p[n] 和 **p 本质上是等价的。是真的吗?

最佳答案

在正确的上下文中(即函数的参数),以下声明是等价的:

int main(int argc, char *argv[]);
int main(int argc, char **argv);
int main(int argc, char *argv[12]); // Very aconventional!

类似的注释适用于函数定义(它有一个用大括号括起来的 block 代替分号)。

在任何其他上下文中,符号之间存在重要差异。例如:

extern char *list1[];
extern char **list2;
extern char *list3[12];

第一个说某处有一个大小不确定的数组,其中包含“char *”值。第二个说在某个地方——可能在这里——有一个包含指向 char 指针的指针的值。第三个表示某处 - 可能在这里 - 有一个 12 个字符指针的数组。

然而,所有三个列表都可以以某种相同的方式引用 - 假设它们实际上已经被定义和初始化。

list1[0][0] = '1';
list2[0][0] = '2';
list3[0][0] = '3';

此外,如果将它们传递给这样的函数:

function(list1, list2, list3);

那么函数可以声明为:

void function(char **list1, char **list2, char **list3);

数组(list1, list3)从数组衰减到指向数组第一个元素的指针; list2当然已经是指向指针的指针了。

函数中需要注意的一个细节,例如:

void otherfunction(char *list[12])
{
...
}

C 编译器对该声明的处理方式与以下内容没有任何区别:

void otherfunction(char **list)
{
...
}

void otherfunction(char *list[])
{
...
}

特别是,它不进行数组边界检查,就功能而言,12 也可能不存在。


C99 引入了 VLA(可变长度数组)类型,还引入了带有“静态”和数组边界大小的符号。您需要阅读标准才能完全理解这些内容。

在像下面这样的函数中,数组的大小确实很重要,并且在运行时确定。对于一般的二维数组,除了第一个维度之外的所有维度都需要指定。

void vla_function(size_t m, int vla[m][m]);

引用标准(第 6.7.5.3 节):

void f(double (* restrict a)[5]);
void f(double a[restrict][5]);
void f(double a[restrict 3][5]);
void f(double a[restrict static 3][5]);

(Note that the last declaration also specifies that the argument corresponding to a in any call to f must be a non-null pointer to the first of at least three arrays of 5 doubles, which the others do not.)

关于c - C/C++ 中的指针/数组语法 (char **p, *p[n]),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2305255/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com