Bootstrap

数组名到底是不是指针? --- 数组名与指针的区别

数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用。即便相似但不相同!


一、结论:数组名不是指针

数组名不是指针的一些证明:

1. 指针可以进行算数运算,比如算数递增和递减以及指针之间的减法运算;但是数组名不可以。两者本质上还是有区别的。

2. 指针是在运行时动态分配内存,数组名在编译时分配内存空间。而这意味着数组的内存分配是静态的,而指针的内存分配是动态的。

之前使用的下面的证明方式,确实证明不充分。

当时认为如果数组名是指针的话,那么sizeof(数组名)和sizeof(p)都应该输出指针的大小4/8。但是证明不充分,因为sizeof关键字本身针对数组和指针就有不同的用法,针对指针,输出指针的大小;针对数组,输出数组空间元素的大小

证明:数组名不是指针

反证法:假设数组名是指针,则arr和p都是指针。因为:在win32平台下,指针长度为4;
那么sizeof(str)和sizeof(pStr)的输出都应该为4。

根据输出,sizeof(arr)=3 ,sizeof(p)=4。假设不成立。 证明完成:数组名不是指针。

二、不同与相似

1. 既然数组不是指针,那两者还有什么不同之处呢?

1.1 数组和指针是两种不同的类型

数组名指代一种数据结构,这种数据结构就是数组。

指针是一种存放地址的变量。

这就是上面代码中,为什么sizeof(arr)≠sizeof(p)的原因。因为arr是一种一种数据结构,即一个长度为10的char型数组,所以sizeof(str)的结果为这个数据结构占据的内存大小:10字节。 

1.2 数组名是不可修改的左值,指针是可修改的左值

通常,数组名作为指针常量,不能被修改。(只有在某些场合下,比如被转换成指针变量的时候才可以被修改)

2. 既然这么多不同,那为什么会产生数组名是指针的错觉?

原因:数组名在许多场合会自动转换为指向数组首元素的指针(函数传参、赋值给指针、表达式)

2.1 数组传参时,数组名会退化成指针。这时数组名被当成常量指针,可以被修改。

大家注意一下:常量指针≠指针常量 
数组名只能被看做是指针常量。只有在数组传参的时候,数组名才会转化成常量指针

2.2 赋值给指针的时候,数组名作为指针使用

int arr[10] = { 1,2,3,4,5,6,7,8,9,0 }  ->  int *p = arr

2.3 在表达式中,数组名作为指针变量出现

两个数组之间的赋值,例如 arr1[i] = arr2[i]

备注:大多数时候我们使用,都碰到了数组名被隐形转换成指针的情况。所以自然而然就会觉得数组名就是指针,理论上还是有点区别的。

不过俺也不确定自己的分析是否准确,大家可以批评指正,互相进步!谢谢大家!

;