数组名与指针区别

在最开始学习C语言的时候,最常听到的说法之一就是“数组和指针是相同的”,不幸的是,这是一种非常危险的说法,并不完全正确。

首先看C标准对指针的解释为:指针是一个变量,变量的值是另外一个变量的地址。那么,既然指针是变量,那么指针必然有自己的存储空间,只不过是该存储空间内的值是一个地址值,而不是别的内容。那按照最常听到的说法“数组名和指针是相同的”,那么数组名也应该有自己的存储空间喽?

 

事实上,在第一幅图中,这个时候我们编译的话,编译器一般都会报错的,如图所示。这个时候我们看一下报错的信息就可以知道对数组名取地址得到的结果其实是一个: char(*)[4] ,表示的是数组名的内涵为一种数据结构,也就是说是:数组起始地址开始的,以数组长度和sizeof(char)乘积为宽度的一个数据结构(我是这么理解的,大家如果有不同的见解可以留言一起讨论)。C语言规定,数组名代表数组的首地址,也就是第0号元素的地址。

但对数组名取地址时却要注意了,在理解“对数组名取地址”这一表达式的含义时一定要记住:数组名是“数组”这种变量的变量名,这样,&array就好理解了,它取的是“数组”这种变量的地址。

而在第二幅图中,我们编译的话,提示的错误是无法从“char (*)[4]”转换为“char *”,可见指针只是指向字符串的首字符,是首字符的地址。

 

★总结:数组名的内涵为一种数据结构,也就是说是:数组起始地址开始的,以数组长度和sizeof(char)乘积为宽度的一个数据结构。数组名代表的是数组首地址,注意这是的用词是“代表”,编译器只是给数组元素分配相应的空间,并未分配其它任何空间,数组名是“数组”这种变量的变量名,只是一个符号,系统不会为它分配任何空间。没有分配空间,也就谈不上变量,也就不是指针。

此外,只有当数组名在表达式中使用时,编译器才会为它产生一个指针常量。

还有在函数中

#include <iostream>

 2 void arrayTest(char str[])

 3 {

 4   cout << sizeof(str) << endl;

 5 }

 6 int main()

 7 {

 8   char str1[10] = "I Love U";

 9   arrayTest(str1);

10 return 0;

11 }

程序的输出结果为4。不可能吧?数组名内涵为数组这种数据结构,在arrayTest函数体内,str是数组名,那为什么sizeof的结果却是指针的长度?

 这是因为:

(1) 数组名作为函数形参时,在函数体内,其失去了本身的内涵,会退化成一个指针;

(2) 很遗憾,在失去其内涵的同时,数组名做为参数传递时,只是把数组名代表的地址传递给函数,这里的传递过程是值传递,此时在被调函数体内做自增(自减)等操作,是对形参的自增(自减),与主调函数中的数组名无关。

猜你喜欢

转载自blog.csdn.net/qq_29250265/article/details/94546510