C语言中 数组名 和 &数组名


== 实验环境 ==
1. 编译器:gcc 5.4.0
2. 操作系统:Ubuntu 16.04 x86_64

缘起
本以为此知识点我已熟练掌握,可是最近应用的时候还真给记混淆了。所以写篇文章加深印象。

Show me the code
废话少说,show me the code.

#include <stdio.h>

int main(void)
{
    int array[5] = {0};

    printf("1.          array = %p\n", array); 
    printf("2.         &array = %p\n", &array); 
    printf("3.      &array[0] = %p\n", &array[0]); 
    printf("4.      array + 1 = %p\n", array + 1);
    printf("5.  &array[0] + 1 = %p\n", &array[0] + 1);
    printf("6.     &array + 1 = %p\n", &array + 1);
    printf("7.  sizeof(array) = %lu\n", sizeof(array)); 

    return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
请你思考一分钟,然后再看答案。

运行结果是:

讨论
在绝大多数关于数组的表达式中,数组名代表指针常量,这个指针指向数组首个元素。从数值上讲,数组名表示的值就是首个元素的地址。 从结果的第1行和第3行,第4行和第5行,都可以验证这一点,即array的值就等于&array[0]的值。

刚才已经说过,数组名代表指针常量,且这个指针指向数组首个元素。当对这个指针进行加减的时候,以一个数组元素为颗粒度。例子中的数组元素为整型,所以数组名加1时地址加4. 对比第4行和第1行,可以验证。

但是,在以下2种语境中,数组名并不是上面说的指针常量。
1. sizeof(数组名)
2. &数组名

对于1,sizeof(数组名)返回整个数组的长度,而不是指针常量的长度。 结果的第7行,返回20(=4*5),而不是返回8(因为地址宽度是64位,所以指针占8字节)。

对于2,对数组名取地址所产生的值的类型是一个指向整个数组的指针,而不是一个指向指针常量的指针。所以&array的类型是指向整个数组的指针,而array是指向array[0]的指针,虽然在数值上相同(结果的第1行和第2行),但是在类型上不同。

正因为它们的类型不同,所以在加1或减1的时候,颗粒度不同。array以一个数组元素为颗粒度,例子中的数组元素为整数,所以array加1时地址加4(对比结果的1、4两行);而&array以整个数组为颗粒度,例子中的数组为有5个元素的整型数组,所以&array加1时,地址加20(对比结果的2、6两行)。

总结
绝大多数情况下,数组名代表指针常量,这个指针常量指向数组首个元素。从数值上讲,数组名的值就是首个元素的地址。当对这个指针常量进行加减的时候,以一个数组元素为颗粒度。

在 sizeof(数组名) 和 &数组名 这2种语境中,数组名并不是上面说的指针常量。 sizeof(数组名)返回整个数组的长度,而不是指针常量的长度。&数组名 的类型是一个指向整个数组的指针,而不是一个指向指针常量的指针。

数组名和&数组名虽然在数值上相同,但是在类型上不同——数组名是指向首个元素的指针,&数组名是指向整个数组的指针。在指针加减整数的时候,前者以一个元素为颗粒度,后者以整个数组为颗粒度。
————————————————
版权声明:本文为CSDN博主「车子 chezi」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/longintchar/article/details/80044077

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值