数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用。即便相似但不相同!
一、结论:数组名不是指针
数组名不是指针的一些证明:
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]
备注:大多数时候我们使用,都碰到了数组名被隐形转换成指针的情况。所以自然而然就会觉得数组名就是指针,理论上还是有点区别的。
不过俺也不确定自己的分析是否准确,大家可以批评指正,互相进步!谢谢大家!