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

时间:2012-10-22 04:45:30

标签: c pointers

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

#include <stdio.h>

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的大小?我对t

感到困惑

4 个答案:

答案 0 :(得分:5)

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

由于隐式转换,你似乎能够在需要指针 1 的上下文中使用一个数组(并且很遗憾),开发人员会混淆两者。

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

1。“重要的是要注意,在许多情况下,数组会衰减为指针,因为这是混淆的常见原因。” - Ed S.


你的sizeof将运行变量的“真实”类型,这就是为什么你得到的数字与你认为 array-names 等同于指针。


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

答案 1 :(得分:5)

首先,问题的主要内容:编译器严格按照声明大小处理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语言中的数组和指针包围你的第一个,我根本无法强调。除此之外,他们的关系充其量只是乱伦。指针变量位于地址,如数组(或任何其他变量)。但与数组不同,它们还地址作为。数组他们的地址。

第一个最好的证明如下:

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.

答案 2 :(得分:1)

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

奇怪的是,当你执行sizeof(str)时,它应该给你一个7而不是6,因为它包含NUL终止符。

s t r i n g \ 0

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

答案 3 :(得分:1)

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

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

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

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

sizeof(str)中,strsizeof的操作数。所以转换为指针;这是阵列。然后sizeof计算该数组的大小,即7。

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