使用char * a [] vs char a [] []

时间:2016-04-15 09:13:11

标签: c arrays pointers char

我知道当用作函数参数char* a[]时相当于char a[][]

当用作函数参数char* a[]时,相当于char** aAlso known as Array to pointer conversion to some.

然而,当在块范围中使用时,它们不一样,我很困惑,因为我应该更喜欢一个而不是另一个,或者我应该跳过char a[][],因为我通常倾向于在其他人的代码中看到char* a[]

反对char a[][]的一个论点显然是你必须给它将包含的C字符串一个固定的大小,但是这会以任何方式影响性能吗?

我应该更喜欢这个:

char* a[] = {"hello", "world"};

或者这个:

char a[][10] = {"hello", "world"};

2 个答案:

答案 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** achar 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]