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

太过爱你忘了你带给我的痛 2022-05-26 01:39 260阅读 0赞

C语言中 数组名&数组名

== 实验环境 ==

  1. 编译器:gcc 5.4.0
  2. 操作系统:Ubuntu 16.04 x86_64

缘起

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

Show me the code

废话少说,show me the code.

  1. #include <stdio.h>
  2. int main(void)
  3. {
  4. int array[5] = {
  5. 0};
  6. printf("1. array = %p\n", array);
  7. printf("2. &array = %p\n", &array);
  8. printf("3. &array[0] = %p\n", &array[0]);
  9. printf("4. array + 1 = %p\n", array + 1);
  10. printf("5. &array[0] + 1 = %p\n", &array[0] + 1);
  11. printf("6. &array + 1 = %p\n", &array + 1);
  12. printf("7. sizeof(array) = %lu\n", sizeof(array));
  13. return 0;
  14. }

请你思考一分钟,然后再看答案。

运行结果是:

这里写图片描述

讨论

在绝大多数关于数组的表达式中,数组名代表指针常量,这个指针指向数组首个元素。从数值上讲,数组名表示的值就是首个元素的地址。 从结果的第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

发表评论

表情:
评论列表 (有 0 条评论,260人围观)

还没有评论,来说两句吧...

相关阅读