我知道当用作函数参数 char* a[]
时相当于char a[][]
。
当用作函数参数char* a[]
时,相当于char** a
。 Also known as Array to pointer conversion to some.
然而,当在块范围中使用时,它们不一样,我很困惑,因为我应该更喜欢一个而不是另一个,或者我应该跳过char a[][]
,因为我通常倾向于在其他人的代码中看到char* a[]
。
反对char a[][]
的一个论点显然是你必须给它将包含的C字符串一个固定的大小,但是这会以任何方式影响性能吗?
我应该更喜欢这个:
char* a[] = {"hello", "world"};
或者这个:
char a[][10] = {"hello", "world"};
答案 0 :(得分:8)
理解函数参数看似奇怪的语法案例的关键是理解数组衰减。这完全是关于C中的一个规则,无论何时将数组作为参数传递给函数,它都会衰减为指向该数组的第一个元素的指针(*)。
所以当你写一些像
这样的东西时void func (int a[5]);
然后在编译时,数组被替换为指向第一个元素的指针,使上述内容等于:
void func (int* a);
这种指针衰减规则递归地应用于多维数组。因此,如果将多维数组传递给函数:
void func (int a[5][3]);
它仍然衰减到指向第一个元素的指针。现在,实际上,2D数组实际上是一个数组数组。因此,第一个元素是一维数组,在本例中大小为3。你得到一个数组指针到那个类型int(*)[3]
。使上述内容等同于
void func (int (*a)[3]);
这实际上是为什么我们可以省略数组参数的最左侧维度,而只是省略该维度的原因。这样做我们创建一个不完整类型的数组,通常你无法使用它:例如,你不能在函数体内编写像int array[];
这样的代码。但是在参数的情况下,没有指定最左边的维度并不重要,因为无论如何该维度都会“消失”。
(*)来源,C11 6.7.6.3/7:
参数声明为''数组类型''应调整为 ''指向类型的限定指针',...
答案 1 :(得分:2)
将数组类型调整为指针类型只有在声明为函数的参数时才有效
函数参数char* a[]
将调整为char** a
,char a[][10]
调整为char (*a)[10]
。否则char* a[]
将a
声明为指向char
的指针数组,而char a[][10]
声明a
char
数组的数组。
的偏好
char* a[] = {"hello", "world"};
这个
char a[][10] = {"hello", "world"};
当您想要保存一些字节的内存时有意义。在后一种情况下,对于a[0]
和a[1]
中的每一个,分配10个字节。请注意,在char* a[]
的情况下,a
的元素指向的字符串是不可变的。
如果您想要连续的内存分配,请使用char a[][10]
。