数组指针和数组的地址

时间:2014-09-02 14:56:30

标签: c

以下程序打印a和数组共享相同的地址。 我该如何理解这种行为? 是& arr指针arr的地址,它包含起始地址10个字符?

#include <stdio.h>

int main()
{
    char arr[10] = {0};

    char* a = (char*)(&arr);

    *a = 1;

    printf("a=%p,arr=%p.\n", a, arr);
    printf("%d\n", arr[0]);
    return 0;
}

4 个答案:

答案 0 :(得分:2)

在C中分配数组时,得到的结果如下:

          +---+ 
  arr[0]: |   |
          +---+
  arr[1]: |   |
          +---+
           ...
          +---+
arr[N-1]: |   |
          +---+

就是这样。没有为名为arr的对象留出单独的内存位置来存储数组的第一个元素的地址。因此,数组的第一个元素(&arr[0])的地址与数组本身的地址(&arr)是相同的

除非它是sizeof或一元&运算符的操作数,或者是用于在声明中初始化另一个数组的字符串文字,表达式为类型“{元素数组T”将被转换(“衰减”)为“指向T的指针”类型的表达式,表达式的值将是第一个元素的地址数组。

因此,第一个arr调用中的表达式printf的类型为char [10];根据上述规则,表达式“衰减”为char *类型,值为arr[0]的地址。

在表达式&arr中,arr是一元&运算符的操作数,因此不应用转换;而不是获得类型char **的表达式,而是获得类型为char (*)[10]的表达式(指向char的10元素数组的指针)。同样,由于数组的第一个元素的地址与整个数组的地址相同,因此表达式arr&arr具有相同的

答案 1 :(得分:1)

在惯用语C中,您应该写char *a = arr;char *a = &(arr[0]);&arr通常为char **。即使现代(C ++)编译器自动修复它,它也不正确。

由于arrchar的数组,arr[0]char,而arr与&(arr[0])相同,因此它是char * }。如果你习惯了其他语言可能会很奇怪,但这就是C的工作原理。如果arr是包含struct的任何其他类型的数组,那将是相同的。

答案 2 :(得分:0)

arra打印的地址是数组arr的第一个元素的内存地址。 (请记住,数组的名称始终是指向该数组的第一个元素的指针。)这是因为在定义了数组arr之后,将a定义为指向同一地址的指针在记忆中。

答案 3 :(得分:0)

根据C标准(6.3.2.1 Lvalues,数组和函数指示符)

  

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

数组的地址是其第一个元素的地址。所以虽然这些类型不同

char ( * )[10](对应于&amp; arr)和char *(在演员声明中使用) char * a =(char *)(&amp; arr); )它们将具有与数组第一个元素的地址相同的值。

如果你不使用强制转换,那么由expression&amp; arr初始化的指针的正确定义将是

char ( *a )[10] = &arr;

看到差异然后指针递增。对于指针a的定义,表达式++a的值将比初​​始值更大sizeof( char)。对于指针,我展示了表达式++ a的值将比初​​始值更大10 * sizeof( char )

在您的情况下,表达式*a的类型为char,您可以编写*a = 1;,而在我的情况下,表达式*a的类型将为char[10]你可能不会写*a = 1;