C语言—指针2
1. const 修饰变量
1.1 const修饰变量
变量被const修饰时,变量此时为常变量,本质为常量,语法上不可被修改,但是如果此时需要修改变量值,可以通过指针的方式修改。
虽然此时通过指针的方式确实修改了变量的值,但这并不符合const修饰变量的语法,为了防止const修饰的变量被修改,可以修饰指针变量,防止const修饰变量被修改。
1.2 const 修饰指针变量
const在*pb前表示pb指向的对象不可被修改,此时就很好的保护const修饰的变量值,上述const修饰的指针变量还可以写成:int const *pb,语法上也是支持的。此时const修饰的指针变量可以防止指向的对象被修改,但是指针变量本身是可以被修改的。
原本指针变量是为了存放b的地址,指针变量本身未被修饰,存放变量c的地址后导致指针变量指向其它内存空间,为了防止指针变量指向其它内存空间,使用const修饰指针变量,修饰后的指针变量存放的地址不可被修改。
结论:const修饰指针变量的时候
const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。 但是指针变量本⾝的内容可变。
const如果放在*的右边,修饰的是指针变量本⾝,保证了指针变量的内容不能修改,但是指针指向的内容,可以通过指针改变。
2. 野指针
野指针指向的内存空间是随机的,不可知的,没有明确限制的。
2.1 野指针成因
2.1.1 指针未初始化
2.1.2. 指针越界访问
2.1.3 函数返回局部变量的指针
在vs2022环境下多次输出的结果:多次输出的均为随机值
2.2 如何规避野指针
2.2.1 初始化指针
需要使用指针是,要明确指针存放的地址,对其进行初始化,当暂时不明确指针存放的地址,可以将其初始化为空指针NULL,c语言中空指针为void*0。
2.2.2 ⼩⼼指针越界
需要访问数组元素时,可以求出元素的个数,利用for循环进行访问,防止越界
2.2.3 指针变量不再使⽤时,及时置NULL,指针使⽤之前检查有效性
3. assert 断⾔
assert.h 头⽂件定义了宏 assert() ,⽤于在运⾏时确保程序符合指定条件,如果不符合,就报错终⽌运⾏,这个宏常常被称为“断⾔”。
assert在c语言库函数网站的详细介绍:assert - C++ Reference
assert不仅可以用于判断指针,还可以用于表达式的判断:
按F10启动调试,执行第二条assert语句时,系统报错:窗口输出具体的报错原因
断言失败:Assertion failed: *pa>*pb,说明assert括号内的表达式为假,执行断言。
4. 指针的使⽤和传址调⽤
4.1 模拟strlen函数的实现
4.2 传值调⽤和传址调⽤
实现一个函数交换两个数
第一次交换并没有成功交换,输出的结果还是num1=10 num2=20,这是因为Swap1函数接收的函数参数时,开辟了新的内存空间进行存num1和num2,改变的为x和y形参的的值,,函数栈帧销毁时,x和y的值并不能存储返回,因此x和y只是实参的一份临时拷贝,改变形参并不一定改变实参;
第二次交换交换成功,将num1和 num2的地址作为参数传参时,接收的函数参数改变时,是通过地址指向的位置改变,x指向num1的地址,y指向num2的位置,此时改变形参可以改变实参。
传址调⽤,可以让函数和主调函数之间建⽴真正的联系,在函数内部可以修改主调函数中的变量;函数中只是需要主调函数中的变量值来实现计算,就可以采⽤传值调⽤。如果函数内部要修改主调函数中的变量的值,就需要传址调⽤。