C语言中对数组a再取址是什么

c    int a[5];
    sizeof(a);
    sizeof(&a); 

如上,a是数组名,那么a对C来说不就是数组a的首地址吗,那么&a又是什么意思?&a的内容是什么?

阅读 7.5k
5 个回答

a和&a的值是相同的,都等于a[0]的地址,区别是两者类型不同。

用下面的代码打印一下就知道值是一模一样的了:

    printf("a = %p\n", a);
    printf("&a = %p\n", &a);
    printf("&a[0] = %p\n", &a[0]);

a的类型是int [5]&a的类型是int (*)[5]。所以,sizeof(a)求的是整个数组的字节数(一般的机子都是20),而sizeof(&a)求的是一个指针的字节数,等于sizeof(unsigned long)(32位的机子是4, 64位的机子是8)。

另外,类型的不同在函数调用传参的时候也会造成区别。假设有如下三个函数:

    void fun1(int a[]) {}
    void fun2(int *a) {}
    void fun3(int (*a)[5]) {}

fun1fun2等价(数组退化为指针),可以接受a,传&a就编译不过了。相反,fun3可以接受&a,但是传a就要报错了。

a本身是一个引用变量,C是会给a本身分配一个内存地址,&a就是获取这个地址的引用。数组的内容是存放在堆中,其引用放在栈中,这样读取速度才比较快。a的值就是数组的首地址的引用。

C语言有对于取址有两种模式,一种是直接取址,另一种是间接取址。对于上述例子来说,如果执行sizeof(a),则返回数组的长度,对于数组来说,其内存结构是连续的,而且是定长的。我们令int *p = &a,则p其实是指向数组a的指针,对于指针来说,其存储的是它所指向变量的内存地址,在32位系统中,地址一般存储为4个字节,在64位系统中存储为8个字节,所以sizeof(p)返回4或者8。
我们可以拿一个示例图来展示p和a的内存结果:
图片描述
在上图中a的首地址就是0x1234,那么p的值即为0x1234,注意图中指针长度为4字节,即该图展示的是32位系统的指针。

&a的类型是指针,C标准里面没有地址这个概念。