目录:
1:const修饰指针
2:野指针
3:assert断言
4:指针的使用和传址调用
(1)const修饰指针
1——1const修饰变量:
我们知道变量是可以修改的
我们可以看到图中a直接被修改为了20。
但是如果我们希望在这个变量上加一些限制,使得它不能被修改,需要怎么做呢?
引出:(const的使用)
当在a前面加上const的时候,若想在修改a就会报出警告。
此时a被const修饰变成了常变量(本质还是变量,但是不能被修改)==>如何证明本质是变量呢?
证明本质还是变量:
数组的创建时:规定:需要指定大小,而数组的大小的指定必须是常量!
当[ ]中输入变量的时候:会报错。
当用const修饰后,依然会报错====>证明n的本质还是一个变量,只是具有了常属性。
我们使用const的目的是为了规定其不能被修改
1——2:const修饰指针变量
const修饰指针变量,可以放在*右边,也可以放在*左边,意义不同。
情况1:const在*左边
(可以看到图中*p指向a地址的数值不可被改变,但是使*p指向变量b的操作是可行的)
结论:const放在*的左边时:修饰的是指针指向的内容!!保证了指向的内org不会被修改,
但是指针变量本身的内容可以改变。
情况2:const在*右边
(图中*p所指向的变量a是可以被改变的,但是p指向b的操作会报错)
结论:const放在*右边时:修饰的是指针变量本身!!保证指针变量的内容不会被修改,
但是变量指向的内容,可以通过指针改变。
(2)野指针
概念:野指针:指针指向的位置是不可知的(随机的;不正确的;没有明显限制的)
2——1:野指针的成因
1:指针未初始化:
2:指针越界访问:
3:指针指向的空间释放:
int n是在函数text中创建的局部变量,n占的4个字节的空间,当函数texet返回后,n的空间就还给了操作系统,当*p在接收n地址的一瞬间,就变成了野指针。
2——2:如何规避野指针
1:如果指针有明确的指向,直接给出明确的地址:
int a=10; int*p=&a;
2:如果指针变量,当前还不知道指向哪里,这个时候初始化为NULL======> int*p=NULL;
NULL是c语言中定义的一个标识符常量。值是0, 0也是地址,但是这个地址是无法使用的,读取改地址会报错
3:当指针不再使用的时候,及时置为NULL,使用前检查其有效性
……………………
(3):arrest断言:
assert.h 头文件定义了宏assert(),用于在运行时确保程序符合指定条件,如果不符合,就会报错终止运行。这个宏被称为“断言”。、
assert()宏接受一个表达式作为一个参数,
若表达式为真,程序继续运行
若表达式为假,assert()就会报错:显示没有通过的表达式,以及此表达式的文件名和行号
(4)指针的使用和传址调用
我们学习指针的目的就是解决问题,那么什么样的问题,非指针不可呢?
题目:写一个函数,交换两个整形变量的值。
方法1:
在方法一中我们将a b的值传给了函数,而后创建空变量将其交换
这里简单介绍一下变量交换的基本方法:
1:首先创建一个空变量,给其附上a的值,此时n中就变成了10
2:再将x的值赋给y,此时y就变成了10;
3:最后再将y的值赋给x,实现两个变量的交换。
但是为什么这里的结果没有进行交换呢????
调试一下我们就能发现问题所在:
我们在main函数的内部创建的变量 a 的地址是 0x123ffa44 , b 的地址是 0x012ffa38
在调用函数时,将a b的值传递给了swap函数,
在函数swap内部确实接收到了a b的值,但是 a b的地址与 x y的地址不同;是相于x,y的独立空间
所以在swap函数内部交换的值自然不会影响a b
这种方式传参叫作:传值调用
得到结论:实参传递给形参的时候,形参会单独创建一份临时空间来接收实参,对形参的修改不影响实参,所以swap函数失败了。
那么应该怎么办呢?
我们想要达到的操作是在swap函数内部操作的就是main函数中的a和b===>那么就可以用到指针的知识了,直接将a b的地址传递给swap函数,在swap中通过指针间接操作main函数中的a和b
可以看到,本次swap函数顺利完成任务,这里调用函数的时候将变量的地址传递给了函数
这种调用函数的方式叫:传址调用
总结:传址调用:可以让函数与主调函数之间建立真正的联系,在函数的内部可以修改主调函数中的变量;所以在未来函数中只需要主函数中的变量值来实现计算,就可以使用传值调用。
若函数内部需要修改主调函数中的变量的值,就需要用传址调用。
感谢观看~
标签:const,函数,地址,理解,深入,swap,指针,变量 From: https://blog.csdn.net/2402_88547413/article/details/143912678