
🎉个人主页: 缘三水的博客
❄专栏传送门:C语言专栏(新手向)
🎀人生格言:行动是迷茫的最好解药
🚀个人介绍:

往篇回顾
❄ 【C语言】指针1
文章目录
- 往篇回顾
- (一)const修饰
-
- [1.1 const修饰变量](#1.1 const修饰变量)
- [1.2 const修饰指针](#1.2 const修饰指针)
- [(二) 野指针](#(二) 野指针)
-
- [2.1 野指针成因](#2.1 野指针成因)
- [2.2 规避野指针](#2.2 规避野指针)
- (三)assert断言
- (四)传址调用
- 总结
以下是本篇文章正文内容
(一)const修饰
1.1 const修饰变量
const可以限制变量不被修改
一修改,则会报错
示例
c
int main()
{
const int n = 10;
n = 100;
return 0;
}
但是指针给我们提供了一种另类的修改 变量值的途径
示例
c
int main()
{
const int n = 10;
int* p = &n;
*p = 100;
printf("%d", n);
return 0;
}

这种另类的修改
显然是不符合const要限制变量n的初心的
那我们该如何防止呢?
1.2 const修饰指针
指针变量也是变量,也能用const修饰,有两种类型
- const放在 * 左边
放在 * 左边就是限制了*p的修改
而p的修改不受影响 - const放在 * 右边
放在 * 右边就是限制了p的修改
而*p的修改不受影响
总结:p 和 *p两种限制一种
const右边限制,另一种就不受限制
(二) 野指针
定义
野指针即为指针指向的空间是不可知的(不确定的、随机的、不正确的)
2.1 野指针成因
- 指针未初始化,使用指针
c
int main()
{
int *p;//局部变量指针未初始化,默认为随机值
*p = 20;
return 0;
}
- 指针越界访问
c
int main()
{
int arr[10] = {0};
int *p = &arr[0];
int i = 0;
for(i = 0; i <= 11; i++)
{
*(p++) = i;//当指针指向的范围超出数组arr的范围时,p就是野指针
}
return 0;
}
- 指针指向空间释放
c
int* test()
{
int n = 100;
return &n;
}
int main()
{
int*p = test();
printf("%d\n", *p);
return 0;
}
n在出test函数时,空间就已经被释放了
虽然存储了当时变量n对应的地址
但在释放后,再根据当时的地址解引用找到对应的值就不行了
2.2 规避野指针
- 指针初始化
指针变量不再使用,及时置为NULL空指针
NULL值是0,0也是地址,
这个地址是无法使用的,读写该地址会报错
c
int*p = NULL;
- 放止指针越界
数组有对应的空间
访问时就不能超出这个空间,否则就是非法访问
- 检查指针有效性
指针变量使用前,可以用if else语句判断是否为空指针
- 局部变量要注意
当出一个函数时,局部变量的空间就被释放了
再想使用对应的地址就要小心
返回局部变量的地址 (返回栈空间 的地址 )是错误 的
返回局部变量的值 存到寄存器中,再赋给另一个变量是ok的
(三)assert断言
assert()宏
需要包含头文件#include <assert.h>
括号内表达式为真,则不起任何作用
括号内表达式为假,则程序报错,并打印断言的条件和断言的位置
如果想关闭 assert断言,则可以在头文件前加上 宏NDEBUG,assert就失效了
assert的缺点 是影响程序运行时间
但是在Debug 版本下利用assert排查问题
在Release 版本下,assert会自动优化
这样既可以排查bug,又可以不影响程序运行效率,实现双win
(四)传址调用
问题 写一个函数,交换两个数的值
示例1
传值调用

为什么两个值没发生交换?
原因:形参是实参的临时拷贝
形参、实参是分别有自己独立的空间的
改变形参并不会影响实参
于是a,b的值无法完成交换
示例2
传址调用

函数调用时将a,b的地址传给指针变量
这样就建立起了主调函数和函数之间的联系
两者就不是独立的,在利用解引用改变值时,a、b的值随即改变
结论:
在函数内部只需要使用 主调函数中的变量值,采用传值调用
在函数内部需要修改 主调函数中的变量值再传回 主调函数,采用传址调用
总结
这篇文章我们详细介绍了指针部分内容,希望能对你有帮助
有错误的地方希望可以得到大佬的指正
最后不要吝啬你的点赞,收藏和评论!!!
感谢你的观看