数组
在谈到数组的时候,我们需要记住一句话:数组名是指针变量,保存数组首元素的地址
一维数组:在C89标准中,数组是不可以用数组名来表示的,我们需要注意的是在定义数组的时候要定义数组的长度
#define MAX_SIZE 1024
Int a[MAX_SIZE]={0};
Printf(“a=%p\n”,a);//打印数组首元素地址
Printf(“&a=%p\n”,&a);//打印数组的地址
举例说明
总结:从图上我们可以清楚地看出,数组名是指针常量,保存的是数组首元素的地址
&a=0x1000:对一维数组名取地址等于数组的地址
*(&a)=a:对一位数组的地址取值等于数组首元素的地址
由以上一维数组我们可以类比出二维数组及三维数组:
二维数组:在二维数组这里我们特别需要注意的是,二维数组在定义时可以省略行但是不可以省略列。在这里我们再来画一张二维数组的地址图,方便大家理解。
我们来举个例子,大家可以试着跟着一起思考一下
假设a是一个二维数组,那*(*(a+i)+j)代表什么意思呢?
我们一步步来解释:
a+i:第i+1个一维数组的地址
*(a+i):第i+1个一维数组首元素的地址
*(a+i)+j:第i+1个一维数组第j+1个元素的地址
*(*(a+i)+j):第i+1个一维数组第j+1个元素的值
我们也可以总结出一句话:对二维数组的地址取值等于该数组首个一维数组的地址
解决了一维数组和二维数组的地址问题,那么三维数组就很简单了
我们可以很快的推断出三维数组名等于该三维数组的首个二维数组的地址
假设b是一个三维数组,那么*(*(*(b+i)+j)+k)代表什么意思呢?
我们再来一步步看:
b+i:第i+1个二维数组的地址
*(b+i):第i+1个二维数组的首个一维数组的地址
*(b+i)+j:第i+1个二维数组的第j+1个一维数组的地址
*(*(b+i)+j):第i+1个二维数组的第j+1个一位数组的首元素地址
*(*(b+i)+j)+k:第i+1个二维数组的第j+1个一维数组第k+1个元素的地址
*(*(*(b+i)+j)+k):第i+1个二维数组的第j+1个一维数组第k+1个元素的值
我们可以得出结论:对三维数组的地址取值等于该三维数组的首个二维数组的地址
解决了数组地址取值的问题,我们需要注意的另一点就是在函数传参时需要注意的几个问题
1、数组传参传数组名时会自动退化为指针
2、传一维数组名,用元素指针来接
3、传二维数组名,用一维数组的指针来接
4、传三维数组名,用二维数组的指针来接
5、传指针数组,用指针的指针来接(在这要特别注意野指针的问题)
既然谈到指针与数组,我们来讲几点指针与数组的区别
1、 空间分配:数组是静态分配,指针是动态分配
2、 安全性:数组容易越界,指针容易内存泄漏
3、 函数传参:都转化为指针传参
4、 访问效率:数组是直接访问(效率高),指针是间接访问
5、 指针偏向于地址的处理,数组偏向于值的处理
6、 数组的分配空间是连续的,而指针不一定