数组与指针
前面的学习中简单介绍了指针,这一章节则开始详细介绍指针的用途了。
数组名和地址
这里讲到了一个关键而又第一眼很难理解的概念:数组名的值是数组首元素的内存地址! 什么意思呢?我一开始只是把数组名简单的理解为一个变量名,所以理解不了这句话什么意思,心想数组名的值不就是数组吗(这也是浅学习Python时留下的思维误区),实际上,数组名并不是变量,他是个常量。数组名存储的是地址,是这个名字所代表的数组得首个元素的地址,用下面一段代码可以简单地去理解。
#include <stdio.h>
int main(void){
int a[2]={0,1}; //初始化数组
if (a==&a[0])
printf("%p",a);
return 0;
}
编译并运行代码,运行结果为打印了一个地址值
0x7ffd58e62c50
首先,这个程序是正产运行了,因为%p
就是待打印的数据类型为地址的意思,打印出一个地址,说明程序没问题。那么,回到if
语句中,expression中的a==&a[0]
返回值必然是True(或者1),那么就说明数组名a的确是a[0]的地址,也就证明了,数组名的值是地址这一事实。
数组名并非变量,他是一个地址常量,他不能被赋值,但是可以把它的值赋给指针。
地址的加法
在计算机中,地址是按字节编址的。
在C语言中,指针+1的操作,是为增加了一个存储单元。对于数组,则是从这个元素的地址变为下一个元素的地址。举个例子,一个整形数组第二个元素的地址为009EFC34
,那么它第三个元素的地址应该为多少?我一开始觉得应该是009EFC35
,加一嘛。但实际上,正确的答案是009EFC38
,为什么是加了4呢?回到地址是按字节编址的这句话,联合指针+1的操作,是为增加了一个存储单元这句话,那么我们可以知道,整形数组一个元素占据一个整形变量一样的内存大小,也即是4字节(32 bit),每个元素之间都隔了一个整形变量的内存长度。
不同元素数据类型的数组,每个元素的地址间隔长度是不同的,整形数组隔4字节,long类型数组隔8字节(long类型一个变量占8字节),double类型数组隔8字节(double类型一个变量占8字节)等等。这也解释了,声明指针时,为什么必须要明确指针所指对象的数据类型。
指针表示数组法
*
运算符接指针,是为获取指针所指对象的值。
对于数组,我们可以使用诸如*(数组名+整数)
的方式来获取数组中某个元素的值(数组名是首元素的地址,加n即为第n-1个元素)。