一、多维指针
一维指针保存基本变量的地址
二维指针保存一维指针变量的地址
三维指针保存二维指针变量的地址
二、数组名
一维数组名:指针常量,指向数组首元素的地址
二维数组名:首个一维数组的地址(首行的地址)
三维数组名:首个二维数组的地址
三、指针和数组的区别
1、空间分配上:数组是静态分配的,指针是动态分配的
2、访问效率上:数组访问效率更高,指针访问效率较低
3、传参时:接收的形参均是指针
4、安全性:数组容易造成越界,指针容易导致内存泄漏
四、数组的传参
传一维数组名,用数组元素的指针来接
传二维数组名,用一维数组的指针来接
传三维数组名,用二维数组的指针来接
传指针数组,用指针的指针接
五、野指针的避免
1、当定义一个指针,且该指针没有指向时,将其置为空。
2、当要往指针指向的空间赋值时,先看是否给它分配了合法的空间。
六、取值和取地址的区别
int a[1000] = {0};
就以该数组举例
&a:对一维数组的数组名取地址等于该数组的地址
*(&a) = a:对一维数组的地址取值等于数组首元素的地址
同理:
1、对二维数组的数组名取地址等于二维数组的地址。
对二维数组的地址取值等于首个一维数组的地址。
2、对三维数组的数组名取地址等于三维数组的地址。
对三维数组的地址取值等于首个二维数组的地址。
七、为了加深对数组的理解,举一个三维数字的例子:
*(*(*(a+i)+j)+k):
a+i:第i+1个二维数组的地址
*(a+i):第i+1个二维数组的首个一维数组的地址
*(a+i)+j:第i+1个二维数组的第j+1个一维数组的地址
*(*(a+i)+j):第i+1个二维数组的第j+1个一维数组的首元素的地址
*(*(a+i)+j)+k:第i+1个二维数组的第j+1个一维数组的第k+1个元素的地址
*(*(*(a+i)+j)+k):第i+1个二维数组的第j+1个一维数组的第k+1个元素的数值
八、常见的内存错误
1、内存分配未成功,却使用了它。
2、内存虽然分配成功,但是尚未初始化就引用它。
3、内存分配成功并且已经初始化,但操作越过了内存边界。
4、忘记了释放内存,造成内存泄漏。
5、释放了内存却继续使用它。
九、内存错误的应对方法以及用malloc分配空间的步骤
1、分配内存空间。
2、检查分配是否成功。若分配成功,则返回内存的首地址;若分配失败,则返回NULL,并退出程序。
3、清空分配好的空间的数据,即原来的内存中的数据。(使用malloc或bzero函数)
4、使用内存。
5、使用完内存之后,需要释放内存。
6、对指针置空。若释放内存之后不将指针置空,这时如果继续使用该指针,指针会成为野指针。