2

在下面的示例代码中,我使用字符串作为数组,如果 str 的名称是指向 str 的第一个元素的指针,这种情况下 string 的第一个字符,即 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

4 回答 4

5

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

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

您自己的代码片段是一个完美的例子,说明数组不是指针,指针也不是数组。

1. “重要的是要注意,数组在许多情况下会衰减为指针,因为这是一个持续的混乱来源。” ——埃德·S。


sizeof的 's 将对变量的“真实”类型进行操作,这就是为什么在假设数组名称等同于指针的情况下,您获得的数字与您的想法不匹配的原因。


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

于 2012-10-22T04:50:02.227 回答
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.
于 2012-10-22T05:49:54.543 回答
1

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

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

字符串\0

如果你使用 strlen(),它会返回 6。

于 2012-10-22T04:53:28.377 回答
1

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

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

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

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

sizeof(str)中,str是 的操作数sizeof。所以它不会转换为指针;它是数组。然后sizeof计算该数组的大小,即七。

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

于 2012-10-22T11:40:48.903 回答