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

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行和第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两行)。

总结

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

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

  3. 数组名&数组名虽然在数值上相同,但是在类型上不同——数组名是指向首个元素的指针,&数组名是指向整个数组的指针。在指针加减整数的时候,前者以一个元素为颗粒度,后者以整个数组为颗粒度。

参考资料
https://blog.csdn.net/wangkeyen/article/details/50650000

猜你喜欢

转载自blog.csdn.net/u013490896/article/details/80044077