1.const 修饰指针
1.1const修饰变量![]()
tip:
在C语言中,这里的a是常变量,但是如果在C++中,这里的a就是常量
在变量前加上const 本意是a的值不能被修改,但是仍然可以通过指针去修改a的值,如下图:
1.2 const 修饰指针变量
const 可以放在*左边,也可以放在*右边,俩边的作用是不一样的。
左边:限制的是指针变量指向的内容,不能通过指针变量p来改变*p的内容,但是p的内容是能改变的,p可以指向其他变量。
右边:限制的是指针变量p,*p可以改变,但是p的内容不能改变,不能指向其他变量![]()
![]()
如果在*的两边都放上const,那么p和p指向的内容就都不能修改了
2.野指针
概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
2.1野指针的成因
2.1.1 指针未初始化
2.1.2 指针越界访问
2.1.3 指针指向的空间释放
p一旦拿到这个地址的时候,就是野指针了,因为p中存放的这个地址指向的内存空间已经返还给操作系统了
2.2 如何去规避野指针
2.2.1 指针初始化
如果知道指针应该指向哪里,就直接给指针一个值
如果还不知道指针变量应该指向哪里的时候,那么初始化为NULL;
tip:
NULL是C语言中定义的一个标识符常量,值是0,0也是地址,读写该地址时会报错。
2.2.2 小心指针越界
2.2.3 指针变量不再使用时,及时置NULL,指针使用之前检查有效性
2.2.4 避免返回局部变量的地址
3. assert 断言
assert.h 头文件定义了宏 assert(),用于在运行时确保程序符合指定条件,如果不符合,就报错终止运行。这个宏常常被称为“断言”
ex:
assert(p!=NULL);
上行代码用于验证变量p是否等于NULL ,如果确实不等于NULL ,程序继续运行,否则终止运行,并且给出报错信息提示。
assert() 宏接受⼀个表达式作为参数。如果该表达式为真(返回值非零),assert() 不会产生任何作用,程序继续运行。如果该表达式为假(返回值为零)assert() 就会报错,在标准错误流 stderr 中写入⼀条错误信息,显示没有通过的表达式,以及包含这个表达式的文件名和行号。
assert() 的使用对程序员是非常友好的,使用 assert() 有几个好处:它不仅能自动标识文件和出问题的行号,还有⼀种无需更改代码就能开启或关闭 assert() 的机制。如果已经确认程序没有问题,不需要再做断言,就在 #include <assert.h> 语句的前面,定义⼀个宏 NDEBUG 。
定义宏NDEBUG,所有 assert 全部失效,变成空语句,不会做任何判断。
4.指针的使用和传址调用
4.1库函数strlen的功能是求字符串长度,统计的是字符串中 \0 之前的字符的个数。
4.2传值调用和传址调用
4.2.1传值调用
实参传递给形参的时候,形参是实参的一份临时拷贝,形参有自己独立的空间,对形参的修改不会影响到实参。
4.2.2 传址调用
传递的是地址,传址调用可以让函数和主调函数之间建立真正的联系