深入解析:【C语言】12.指针(2)

在这里插入图片描述

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


个人介绍:
在这里插入图片描述


往篇回顾

【C语言】指针1



以下是本篇文章正文内容

(一)const修饰

1.1 const修饰变量

const可以限制变量不被修改
一修改,则会报错
示例

int main()
{
const int n = 10;
n = 100;
return 0;
}

但是指针给我们提供了一种另类的修改 变量值的途径
示例

int main()
{
const int n = 10;
int* p = &n;
*p = 100;
printf("%d", n);
return 0;
}

在这里插入图片描述
这种另类的修改
显然是不符合const要限制变量n的初心的
那我们该如何防止呢?

1.2 const修饰指针

指针变量也是变量,也能用const修饰,有两种类型

  1. const放在 * 左边
    放在 * 左边就是限制了*p的修改
    而p的修改不受影响
  2. const放在 * 右边
    放在 * 右边就是限制了p的修改
    而*p的修改不受影响
    总结:p 和 *p两种限制一种
    const右边限制,另一种就不受限制

(二) 野指针

定义
野指针即为指针指向的空间是不可知的(不确定的、随机的、不正确的)

2.1 野指针成因

  1. 指针未初始化,使用指针
int main()
{
int *p;//局部变量指针未初始化,默认为随机值
*p = 20;
return 0;
}
  1. 指针越界访问
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;
}
  1. 指针指向空间释放
int* test()
{
int n = 100;
return &n;
}
int main()
{
int*p = test();
printf("%d\n", *p);
return 0;
}

n在出test函数时,空间就已经被释放了
虽然存储了当时变量n对应的地址
但在释放后,再根据当时的地址解引用找到对应的值就不行了

2.2 规避野指针

  1. 指针初始化

指针变量不再使用,及时置为NULL空指针

NULL值是0,0也是地址,
这个地址是无法使用的,读写该地址会报错

int*p = NULL;
  1. 放止指针越界

数组有对应的空间
访问时就不能超出这个空间,否则就是非法访问

  1. 检查指针有效性

指针变量使用前,可以用if else语句判断是否为空指针

  1. 局部变量要注意

当出一个函数时,局部变量的空间就被释放了
再想使用对应的地址就要小心

返回局部变量的地址(返回栈空间地址)是错误
返回局部变量的存到寄存器中,再赋给另一个变量是ok

(三)assert断言

assert()宏

需要包含头文件#include <assert.h>

括号内表达式为真,则不起任何作用
括号内表达式为假,则程序报错,并打印断言的条件和断言的位置

如果想关闭assert断言,则可以在头文件前加上 宏NDEBUG,assert就失效了

assert的缺点是影响程序运行时间
但是在Debug版本下利用assert排查问题
Release版本下,assert会自动优化
这样既可以排查bug,又可以不影响程序运行效率,实现双win

(四)传址调用

问题 写一个函数,交换两个数的值

示例1
传值调用

在这里插入图片描述
为什么两个值没发生交换?
原因:形参是实参的临时拷贝
形参、实参是分别有自己独立的空间的
改变形参并不会影响实参
于是a,b的值无法完成交换

示例2
传址调用
在这里插入图片描述
函数调用时将a,b的地址传给指针变量
这样就建立起了主调函数和函数之间的联系
两者就不是独立的,在利用解引用改变值时,a、b的值随即改变

结论:
在函数内部只需要使用主调函数中的变量值,采用传值调用
在函数内部需要修改主调函数中的变量值再传回主调函数,采用传址调用


总结

这篇文章我们详细介绍了指针部分内容,希望能对你有帮助

有错误的地方希望可以得到大佬的指正
最后不要吝啬你的点赞,收藏和评论!!!
感谢你的观看

posted @ 2026-01-08 09:06  gccbuaa  阅读(3)  评论(0)    收藏  举报