在C.中,数组的名称是指向它的第一个元素的指针,不是吗?

在下面的示例代码中,我使用string作为数组,如果str的名称是指向str的第一个元素的指针,在这种情况下,字符串的第一个字符,即s,str的大小,应该是8,但它给了6而不是。

#include  char str[] = "string"; char *ptr = "string"; int main(void){ int first = sizeof(str); int second = sizeof(str[0]); int third = sizeof(ptr); int size_of_array = sizeof(str)/sizeof(str[0]); printf("the size is %d, %d, %d, %d", size_of_array, first, second, third); return 0; } 

看起来str不是指针,str的大小不是ptr的大小? 我很困惑

首先,问题的关键: 编译器严格按照声明大小处理sizeof。 在以下代码中,假设指针变量保存32位(4字节)地址:

 char str1[] = "abcd"; char *pstr = str1; // str1 is declared to be a fixed array of 5 chars (4+nul) size_t str1size = sizeof(str1); // str1size = 5; // pstr is declared to be a 32 bit pointer to a memory address. size_t pstrSize = sizeof(pstr) // size of a 32 bit pointer; 4. 

要掌握你所看到的结果,请查看数组和指针变量的差异,(其中大多数人认为比较少)。

数组和指针变量之间C的核心差异是

  • 指针变量保存一个地址; 声明的数组一个地址。
  • 因此,声明的数组不能修改它们的“地址”(因为它们地址,它们不像指针变量那样保存地址)。

如果你想真正地用C语言中的数组和指针包围你的第一个,我根本无法强调。除此之外,他们的关系充其量只是乱伦。 指针变量位于像数组(或任何其他变量)的地址。 但与数组不同,它们还将地址作为其 。 数组他们的地址。

第一个最好的certificate如下:

 char str1[] = "abcd"; char *pstr = NULL; pstr = str1; // ok. pstr holds the address *at* str1. str1[0] = *pstr; // ok. copies 'a' on to 'a'. pstr++; // ok. increment the address held in pstr by one item (char) size. str1[0] = *pstr; // ok. copies 'b' over 'a'. pstr = str1+1; // ok. pstr holds the address *at* str1 + one item (char) size. str1 = pstr; // does not compile. str1's address cannot be changed. 

请注意,指针变量本身包含一个地址,而固定数组一个地址。 因此,最后的陈述完全正确。

 pstr = str1; // ok. put the str1 address in pstr, a pointer variable. 

长话短说; 数组不是指针,指针不是数组。

由于隐式转换,您似乎能够在需要指针的上下文中使用数组1许多新手(并且经验丰富)开发人员会混淆两者。

你自己的代码片段是一个完美的例子,因为数组不是指针,而指针不是数组。

1. “重要的是要注意,在许多情况下,数组会衰减为指针,因为这是混淆的持续来源。” – Ed S.


你的sizeof将运行变量的“真实”类型,这就是为什么你得到的数字与你认为数组名称等同于指针的假设不符。


只是为了让读者清楚这个问题; 数组不是指针,指针不是数组..

是和否,str是一个数组,但当它出现在表达式中时,它将转换为指向数组第一个成员的指针。

奇怪的是,当你做一个sizeof(str)实际上它应该给你一个7而不是6,因为它包含NUL终结符。

字符串\ 0

如果您使用了strlen(),它将返回6。

奇怪的是,之前的答案都没有直接解决标题中提出的问题。

不,数组的名称不是指向其第一个元素的指针。

大多数表达式中,作为数组的表达式将转换为指向第一个元素的指针。 因为这在大多数表达式中都会发生,所以人们倾向于将数组视为指针。 但是,有四个例外。 当数组是sizeof_Alignof&的操作数时,数组不会转换为指针,或者当数组是用于初始化数组的字符串文字时。 因为您的一个示例使用数组作为sizeof的操作数,所以它使用数组,而不是指向第一个元素的指针。

因此,在sizeof(str[0]) ,首先解析str[0] 。 在此子表达式中, str不是sizeof的操作数,因此它将转换为指针。 然后该指针与下标运算符一起使用,结果是数组的第一个元素。 然后sizeof计算该元素的大小,即1。

sizeof(str)strsizeof的操作数。 所以它没有转换为指针; 这是arrays。 然后sizeof计算到该数组的大小,即7。

请注意,此转换不仅适用于标识符(名称); 它适用于任何表达式。 因此,如果p是指向数组的指针,则用float (*p)[4]; ,然后*p是一个四浮点数组,因此它被转换为指向float的指针(当它不是sizeof_Alignof&的操作数时)。