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

hgi*_*sel 2 c arrays pointers char

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

当用作函数参数时char* a[]相当于char** a.也称为Array to pointer转换为一些.

但是当在块范围内使用它们时它们是不一样的,我很困惑,因为我应该优先选择其中一个,或者我应该跳过char a[][],因为我通常倾向于char* a[]在其他人的代码中看到.

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

我应该更喜欢这个:

char* a[] = {"hello", "world"};
Run Code Online (Sandbox Code Playgroud)

或这个:

char a[][10] = {"hello", "world"};
Run Code Online (Sandbox Code Playgroud)

Lun*_*din 8

理解函数参数看似奇怪的语法案例的关键是理解数组衰减.这是关于C中的一个规则,它表示,无论何时将数组作为参数传递给函数,它都会衰减为指向该数组的第一个元素(*)的指针.

所以当你写一些像

void func (int a[5]);
Run Code Online (Sandbox Code Playgroud)

然后在编译时,数组被一个指向第一个元素的指针替换,使得上面的数字等于:

void func (int* a);
Run Code Online (Sandbox Code Playgroud)

这种指针衰减规则递归地应用于多维数组.因此,如果您将多维数组传递给函数:

void func (int a[5][3]);
Run Code Online (Sandbox Code Playgroud)

它仍然衰减到指向第一个元素的指针.现在,实际上,2D数组实际上是一个数组数组.因此,第一个元素是一维数组,在本例中大小为3.你得到一个指向该数组的数组指针,即类型int(*)[3].以上等同于

void func (int (*a)[3]);
Run Code Online (Sandbox Code Playgroud)

这实际上是为什么我们可以省略数组参数的最左侧维度,而只是省略该维度的原因.在这样做的时候,我们创建一个不完整类型的数组,这通常是你无法使用的:例如,你不能像int array[];在函数体内编写代码一样.但是在参数的情况下,没有指定最左边的维度并不重要,因为无论如何该维度都会"消失".


(*)来源,C11 6.7.6.3/7:

参数声明为''数组类型''应调整为''限定指向类型'',...

  • @Lundin:不.参数是函数的一部分,参数是函数*call*的一部分.换句话说,参数是值,参数是声明的一部分. (5认同)
  • @Lundin; 引用的文字说关于参数的调整. (4认同)
  • @Lundin引用说参数"应该调整",而不是任何关于衰减的参数. (4认同)
  • 是不是*论据*会腐烂?我很确定参数是经过类型调整的. (3认同)
  • @KerrekSB是的但你不能写'int array [];`就像我写的那样.并且根据参数vs参数的定义,它是"衰减"的参数,参见引用的C标准. (3认同)
  • 关键是衰变是*表达式*发生的事情,而不是类型.当你说"a"这个表达式时,它会从"array of int"衰减到"指向int的指针".函数参数的参数类型调整被设计为镜像,以便使函数声明和函数调用在风格上匹配,但是类型不会衰减. (3认同)
  • 备份@KerrekSB最后一条评论:***对表达式中出现的array-of-T类型的对象的引用将(有三个例外)衰减为指向其第一个元素的指针**; 结果指针的类型是指向T的指针.*([C-faq](http://c-faq.com/aryptr/aryptrequiv.html)). (3认同)
  • @hgiesel不是那个问题,腐烂只发生过一次.这就是为什么你最终得到一个数组指针. (2认同)