1.什么叫指针
C语言中,每创建一个值(数据),都会在内存中开辟出一定的空间,并且每个空间都有指定的名字,这个名字在C语言中叫做地址,也就是指针,类似宿舍的门牌号,通过门牌号来找到相应的房间,就像通过指针找到对应的值。
我们只要记住指针就是地址,地址就是指针,没什么可怕的,不要认为指针很高级,就是我们理解的地址,只不过在C语言中我们要学会如何去使用它。
2.定义指针变量
定义一个指针变量需要用到解引用操作符 * ,例如:
int* 表示整型指针类型;
char* 表示字符型指针类型;
这些类型加上 * 就变成指针类型了;
例如:
&是取地址符号,&a表示取出a的地址
p是一个指针变量,里面放的是a的地址,int* 表示p 是一个指针,指向一个int 类型的变量,那么p的类型就是 int*,我们也可以用解引用操作符 * 改变a的值,
例如:
可以看到a的值变成了10, *p表示通过p中的地址找到对应的空间,可以使用或者改变它,*p就等价于a,可以用*p改变a的值。
用*p修改a的值可以不受const的影响,尽管这样不太合理,会出现警告,不建议这样用。
3.指针变量类型
3.1指针加减整数
我们知道常见的指针类型:int*,char*,float* 等等,
指针类型确定了指针加减一个整数跳过多少字节
例如:
p1+1跳过4个字节,p2+1跳过1个字节,这就是指针变量的类型差异带来的变化
指针的类型决定了指针向前或者向后⾛⼀步有多⼤(距离)。
3.2指针减指针
指针减去指针的绝对值表示两个地址之间相差的元素个数
例如:
这是模拟strlen函数计算字符串的长度,可以看到字符串的长度是3,
3.3指针变量的大小
指针变量里面储存的是指针,也就是地址,那么地址的大小是怎么计算的呢?
可以看到,虽然指针类型不同,但是大小是一样的呀,我们要知道指针的大小取决于环境的不同
32位平台下地址是32个bit位(即4个字节)
64位平台下地址是64个bit位(即8个字节)
就像我们的宿舍号,308是个四人间,207是个六人间,大小不一样,但是门牌号都是三位数呀,
3.4 void*指针
void*指针是一种特殊类型的指针,它可以接收任意类型的指针,但是不能指针加减和解引用作,他就
像一个垃圾桶,什么都可以往里放,但使用它的时候就要进行强制转换成我们需要的类型。
void*的作用是使⽤在函数参数的部分,⽤来接收不同类型数据的地址,这样的设计可以 实现泛型编程的效果,使得⼀个函数来处理多种类型的数据,这个我们后面会讲到。
4.const修饰指针
下面来看一段代码:
用const修饰一个整型n,那么就不能再更改 n的值了,虽然n是一个变量,但是const修饰后,由于语法限制,就不能在修改n的值了,这就是const的作用,
要是用const修饰指针呢
可以合理地使用const来避免一些值发生变化。
5.野指针
概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
5.1野指针的成因
1.定义指针时未初始化
2.指针越界访问
3.指针指向的空间被释放
这个p指向的空间已经被释放了,p找不到n的位置了,这种情况是非常危险的,
5.2如何避免野指针
1.指针初始化
2.⼩⼼指针越界
3.指针变量不再使⽤时,及时置NULL,指针使⽤之前检查有效性
牢记这三条准则,避免出现野指针。