之前我们介绍了指针和各种类型的数组之间的关系,以及怎样使用指针来操做各种类型的数组
其实除了操作数组之外,在c语言当中指针还有其他的作用,我们今天先来简单的介绍几个和指针有关的概念
1 二级和多级指针
指针可以指向一个具体的数据的地址,那么如果指向的地址保存的是一个指针类型的数据,那么这个指针就叫做二级指针

a是一个变量,保存了数据10,p1是指向a的指针,保存的数据是a的地址,p2是指向p1的指针,保存的是p1的地址
指针的类型一般要和指向的地址保存的数据类型相同,所以二级指针的生命应该是 <类型>**p

根据就近原则 *p说明变量是指针类型 **p 表示指针指向的数据是指针,int **p 表示一个指向int指针的指针
#include
取二级指针的值,取到的是另外一个指针,然后对这个指针取值,最后得到想要的数据
我们把数据想象成宝藏,变量想象成宝箱,指针想象成藏宝图,那么以上的过程就是,把宝藏(数据10),放到箱子(变量a),然后把藏宝图(a的地址),放到第二个箱子里(一级级指针p1),然后把第二箱子的藏宝图(p1的地址),放到第三个箱子里(二级指针p2)
要取回宝藏,先打开第三个箱子取出宝图(*p2==p1),在根据宝图找到第二个箱子(*p1==a),最后找到第一个箱子(a)取出值
同样的道理我们也可以定义三级指针,四级指针,和更高级的指针
2 NULL指针和野指针
在c语言当中,局部变量在使用的时候如果不赋初始值,那么就会自动生成一个随机的值
#include
对于指针也是一样
#include
那么对于指针来说,如果没有特别的指明指针指向的地址,那么这个指针可以指向内存当中的任意位置,这就给程序带来了安全隐患,这种不确定指向位置的指针,我们就叫野指针
为了避免野指针的出现,在c语言当中定义了一个宏常量NULL,可以理解为空地址,我们在声明指针的时候,如果不确定指针的指向,可以把指针初始化为NULL,这是一个非常好的习惯
int *p=NULL;野指针的产生主要就是由两个原因造成的
- 指针没有初始化
- 指针指向的内存被释放
#include这里p就是野指针,任何的操作都没有意义
#include这里的malloc是引用stdlib.h头文件之后可以使用的标准库函数,表示分配一个内存空间,并且返回空间的地址

分配了合法的空间就不是野指针了,但是如果把空间释放掉
#includefree函数用来释放一块内存空间,释放后空间消失了,但是指针还指向原地址,那么也构成的野指针
所以好的习惯是
- 声明一个不确定指向的指针变量,就把指针指向NULL
- 释放掉一块空间就把指向空间的指针指向NULL
p指向NULL之后最大的好处就是可以利用p==NULL来判断指针是否是一个有效指针,可以避免一些错误
#include
而不指向NULL,就没有办法判断指针是否有意义
#include这里就无法判断p的值是否有意义

3 void指针
之前使用void的位置是在函数声明的时候,表示函数的类型为空类型
指针同样也可以使用void来声明,表示指针指向的数据类型不确定,一般情况向使用void声明的指针,在使用的时候通常会强制转换为具体的数据类型

直接使用void指针会出错
正确的用法是
#include把p的类型强制转化为 int* 再取值

NULL指针解决的问题是指针指向的位置不确定
void指针解决的问题是指针指向位置的类型不确定
在具体使用的时候都需要把NULL和void替换成确定的值,否则就没有意义
Ps: stdlib.h头文件解锁的malloc和free函数
标准库头文件 <cstdlib>zh.cppreference.com
malloc函数可以让我们手动的分配内存空间
参数是一个size_t类型的数据(可以理解为unsigned int),表示分配空间的大小单位是字节
返回值是一个void指针,也就是创建的空间地址,如果空间分配失败,返回NULL指针

free函数用来释放被分配的空间,参数是分配空间的地址,会把传入的地址指向的空间释放掉
返回值是void,表示没有返回值
具体的例子:
#include手动的分配了一个 int 大小的空间,返回空间的地址,再把地址转为int指针,使用完成之后使用free释放空间,把指针指向NULL;

数组也可以
#include手动的分配了5个int长度的空间,这里p可以看作是数组

本文介绍了C语言中指针的相关概念,包括二级和多级指针的定义与使用,NULL指针用于避免野指针,以及void指针在类型不确定情况下的应用。通过示例解释了如何初始化指针、动态分配内存以及释放内存,并强调了检查指针是否有效的做法。
560

被折叠的 条评论
为什么被折叠?



