一、数组名是指针吗?
在C语言基础书上我们看到过"我们可以把地址,形象的看成指针",所以地址就是指针,指针就是地址,这句话在某种程度上应该没一点问题。但是我们也老是听别人说"数组名就是首元素的地址",所以我们就类比,数组名 = 地址,又因为 地址 = 指针,所以数组名 = 指针,如果你真的这样理解,认为数组名就是指针的话,那你就大错特错,所以"数组名就是首元素的地址" 这句话是有一定的条件的,下面我来解释,为什么数组名不是指针?
首先应该清楚数组名含义:1. 数组名就是数组名就是这个数组的名称,代表整个数组空间2.在某种程度上可以看成指针(刚刚才说了数组名不是指针吗?这里又说它是指针?别急 这里需要明白一个概念"左值和右值")
扩展: 左值和右值:假如 x= y ,顾名思义=左边就是左值 ,=右边就是右值。
左值:编译器认为x的含义是x所代表的地址,这个地址只有编译器知道,在编译的时候确定,编译器在一个特定的区域来保存这个地址,我们不必考虑这个地址到底保存到哪了。
右值:编译器认为y的含义是y所代表的地址里面的内容,这个内容是什么,只有运行的时候才知道。
这里又引出一个概念"表达式必须是可修改的左值",因为 = 是一个赋值号,所以左值必须是一个变量,你不能给一个常量进行赋值;
数组名作为左值的时候被初始化前它的地址就是不确定,编译器为其随机分配地址,但是数组一旦被初始化,数组名就是一个值,只不过这个值是首元素的地址,但它万万不能等于指针;
数组名作为右值的时候,因为他是确定的值,arr = & arr[0]所以此时可以把数组名看做指针,也就是说一定条件下数组名可以看成指针;
如果你单纯的说数组名就是指针这种说法是片面的,是错误的,但是数组名在为右值的时候可以看出指针,此时可以说数组名的值是指针。
还有我们都知道如果是指针的话指针求大小,即sizeof(指针)应该等于4,而事实上sizeof(arr) 等于40,即整个数组的大小
因此,数组名不是指针,永远也不是,但在一定条件下,数组名可以转换为指针。
二、为什么会出现三值合一?
我们先来看一个现象
arr = &arr =&arr[0] = 0xbbfc00 ,我们可以很清楚的看到 arr 、&arr、&arr[0]三值合一, &arr[0],我们好理解就是数组首元素的地址,但是数组名的值和 数组名的地址为什么又是同一个值呢?
此时我们就可以解释当我们打印&arr[0]、 arr 、 &arr 为什么三值合一:
&arr[0] 代表的是数组中首元素的地址;
arr 数组名代表整个数组空间,但是当arr作为右值的时候,arr 与&arr[0]没有本质差别,都代表数组的的首元素的地址,而不是整个数组的首元素地址;
&arr 代表的是对整个数组进行取地址,而整个数组只要告诉我们首地址,我们就可以只知道其大小多大,因为定义数组的时候我们知道其类型占几个字节里面有多少个元素,所以就可以求出其大小,所以我们给整个数组取地址,就是给整个数组首元素取地址;
所以他们三值合一也就不足为奇了!!!
三、数组名是常量?
答:数组名就是常量。
当数组名在初始化的时候,它是变量(左值必须是变量),它的地址由编译器随机分配给我们,一旦被定义了,数组名就是常量,数组名作为右值时候数组名的值就是首元素的地址。
四:指针与数组的关系
没关系
指针就是指针,用来存放地址,占四个字节(32位编译器),系统分配空间。数组就是数组用来存放同一类型数据,系统不会分配空间,只是他两经常穿着相似的衣服逗你玩罢了(只不过数组名的值有时候可以当做指针来操作而已)。。。