C指向字符串数组和数组名称消歧的指针

时间:2018-02-19 08:42:11

标签: c arrays pointers

我找到了这段代码:

char *array[4]={"aa","bb","cc","dd"};
char *(*ptr)[4]=&array;

在评论中说:

  

ptr:它是指向大小为4的字符串数组的指针

根据定义,变量 array 是什么?

在这种情况下会是什么?

char array[4]={"aa","bb","cc","dd"};

因为我发现了这个:

double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
double *p = balance;

说:

  

数组名是指向数组第一个元素的常量指针,   因此,上述程序片段将p指定为第一个的地址   balance的元素。

好的,我认为得到了这个。那么,为了尝试回答我的第一个问题,那么变量array是一个指向数组第一个元素的第一个字符的常量指针,即'a'?我这样说是因为变量名前面有*符号。

第二个问题的答案就是:array是指向数组第一个元素的常量指针。

显然,C中的指针和数组仍有问题......

2 个答案:

答案 0 :(得分:2)

不。数组不是C中的常量指针。这是错误的。

在大多数情况下,数组衰减成指向第一个元素的指针。这并不意味着它是一个指针。

因为数组是不可修改的左值,所以你会想到不断变化的东西。因此,您不能将其用作修改它的地方。

来自§6.3.2.1p3

  

除非它是sizeof运算符,_Alignof运算符或一元&运算符的操作数。运算符,或者是用于初始化数组的字符串文字,具有类型''数组类型''的表达式将转换为类型为''指向类型'的指针的表达式,指向该类型的初始元素数组对象,而不是左值。如果数组对象具有寄存器存储类,则行为未定义。

这解释了发生了什么 - 该语句中的balance被转换为指向第一个元素的指针。第一个元素是double,指向它的指针是double*,该指针包含balance[0]的地址。

本段还指出&arraychar* (*)[]的原因,因为用作操作符&地址的操作数的数组是数组未转换为指针的情况。这就是为什么第一个声明是合法的。 (请注意,char *(*ptr)[4]是一个指向4 char* - s数组的指针。此处array的地址已分配给ptr)。

来自§6.3.2.1p1

  

... 可修改的左值是一个左值,它没有数组类型,没有不完整的类型,没有const限定类型,如果是结构或联合,没有任何成员(包括,递归地,所有包含的聚合或联合的任何成员或元素)具有const限定类型。

无论来源是什么,也许它试图告诉你这个想法,即数组不是可修改的左值,所以C中balance++之类的语句是非法的,因为balance是一个数组名。

不会出错或混淆正确的方式来描述标准§6.2.5p20

中的数组
  

数组类型描述了具有特定成员对象类型的连续分配的非空对象集,称为元素类型。只要指定了数组类型,元素类型就应该是完整的。 数组类型的特征在于它们的元素类型和数组中元素的数量。数组类型据说是从其元素类型派生的,如果它的元素类型是T,则数组类型有时称为''T'数组。从元素类型构造数组类型称为“数组类型派生”

还要注意一件事,当你使用char a[]={"aa","bb"};时 - 这是错误的,因为字符串文字是char数组,它会衰减成指针 - 所以它是char*的数组 - 不是数组char

答案 1 :(得分:1)

没有。数组不是指针。有一种称为“数组到指针转换”(衰减)的东西,但它只发生在第一级,并且不会使数组和指针成为同一个东西。

在您的代码段中:

char array[4]={"aa","bb","cc","dd"};

array可以用作(衰减)指向指向字符串第一个字符的另一个指针的指针,换句话说,就是数组中的第一个元素。第一个元素没有“第一个字符”,因为那是第二个元素,还有其他事项。

这可以用另一种方式理解:balance可以转换为指向balance[0]的指针,因此我们有balance == &(balance[0])。但是array = &(&(array[0][0]))永远不会发生这种情况,因为address-of运算符返回一个rvalue,或者无论如何都是一个无法再获取地址的值,因此array 不是指向array[0][0]

由于您使用的字符串文字实际上是字符的常量指针,因此array的内容如下所示:

           array
          +----------+
array --> | array[0] |  --> "aa"
          +----------+
          | array[1] |  --> "bb"
          +----------+
          | array[2] |  --> "cc"
          +----------+
          | array[3] |  --> "dd"
          +----------+

因此,array 指向任何字符的指针,它可能会被转换为(衰变为)指向char的另一个指针的指针,但它赢了“ t永远转换为指向第一个字符'a'

的指针
相关问题