C语言——指针(五)

📝前言:
上篇文章C语言——指针(四)更加深入的介绍了不同类型指针的特点,这篇文章主要想记录一下函数与指针的结合运用以及const和assert关于指针的用法
1,函数与指针
2,const
3,assert断言

🎬个人简介:努力学习ing
📋个人专栏:C语言入门基础
🎀CSDN主页 愚润求学
🌄每日鸡汤:对待生命,你不妨大胆一点,因为我们最终要失去它

文章目录

    • 一,函数与指针
      • 1,指针变量作为函数参数
      • 2,返回指针的函数
    • 二,const
      • 1,const 修饰变量
      • 2,const 修饰指针变量
    • 三,assert断言
      • 1,assert的使用
      • 2,assert的禁用

一,函数与指针

在上一篇文章中,我们提到了函数指针,函数指针是用来存放函数地址的指针,这篇文章,我们还将继续探究函数与指针。

1,指针变量作为函数参数

像int ,char类型一样,指针类型也可以作为函数的参数类型。
当我们使用指针类型作为函数的参数,实际向函数传递的是储存单元的地址当我们改变该地址空间的数据后,尽管子程序调用结束,但是数据的改变情况也会被保留下来。

看下面这段代码👇🏻,利用swap函数能实现实参a和b的交换吗?

void swap(int x,int y)
{int t = x;x = y;y = t;
}

答案是:不能
因为这个函数在传值时:只是把a和b的值传递给了形参,但是形参只是实参的临时拷贝,形参之间值的交换,无法影响到实参,所以也完成不了交换

当我们利用指针变量作为函数参数👇🏻

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//实现交换:
void swap1(int* p1, int* p2)
{int t;t = *p1;*p1 = *p2; *p2 = t;
}
int main()
{int* pa, * pb, a = 3, b = 4;pa = &a;pb = &b;swap1(pa, pb); //调用函数,在函数内部交换printf("%d %d\n", a,b);return 0;
}

输出结果 👇🏻

这里是引用
我们发现🔍
a和b的值在函数内部被交换完以后,尽管函数调用结束,但是a和b是永久的交换了

这也就是传值和传址的区别:传值是对形参进行操作,但是传址是对实参的地址空间进行操作

2,返回指针的函数

我们把返回地址值(即返回指针值)的函数称之为指针函数,指针函数定义如下:
类型名* 函数名(参数);
如:int * fun(int x, int y); 表示fun是具有两个整型参数且返回整型指针的函数,返回的指针值指向一个整型数据。

使用实例:
返回两个数中大数的地址的函数:

int* fun(int* x, int* y)
{int* z;if (*x > *y)z = x;elsez = y;return z;
}
int main()
{int a, b, * p;scanf("%d %d", &a, &b);p = fun(&a, &b);//用p来接收所返回的地址printf("max = %d\n", *p);//打印p所指向的数据return 0;
}

运行程序(输入3 8)👇🏻
在这里插入图片描述
max = 8,如我们所愿:函数fun返回了b的地址,p接收的就是b的地址👍

二,const

C语言中提供了const关键字,其主要作用是:
限定声明的变量值为常量,在程序运行时值不能改动。

1,const 修饰变量

如下面的代码👇🏻

#include<stdio.h>
int main()
{int m = 0;m = 20; //这是我们正常的修改值的方式const int n = 0; //n有const修饰n = 20//(错误)n无法修改return 0;
}

编译错误如下👇🏻
在这里插入图片描述

在上述代码中,n的本质还是变量,只不过被const修饰以后,在语法上加了限制,让我们不能直接修改n(这时,我们也称n为常变量)

2,const 修饰指针变量

下面有两种不同的修饰方式👇🏻

const int *p; //第一种也等效于(int const *p)
int* const p;//第二种

●第一种,右边离const最近的是*,修饰的是*,意思是:不能通过p来改变p指向的空间的内容
●第二种,右边离const最近的是p,修饰的是p,意思是:不能改变p变量本身的内容
如下面的代码👇🏻

int main()
{int n = 10;int m = 20;const int *pn = &n;*pn = 20;  //(无法执行)p = &m;  //(可以执行)return 0;
}

在上面的代码中
无法执行是因为:const修饰了*pn,所以pn所指向的内容无法修改
但是p = &m; 可以执行,因为p是变量本身,没有被限制,可以修改

再看下面的代码👇🏻

int n = 10
int m = 20;
int const * const p = &n;

如果这样写,const既修饰了*,又修饰了p,则:
*p = 20;
p = &m;
都无法执行

三,assert断言

assert.h头文件中定义了宏assert()

1,assert的使用

assert()用于在运行时确保程序符合指定条件,如果不符合,就报错终止运行
如👇🏻

#include<stdio.h>
#include<assert.h>
int main()
{int* p1 = NULL;assert(p1 != NULL);return 0;
}

一旦我们运行👇🏻

这里是引用

上面的代码:assert(p1!=NULL); 发现表达式不符合条件,于是assert就会终止运行,并且给出错误信息的提示。

assert()宏接受一个表达式作为参数:
●如果表达式为真(返回值非零),assert不会产生任何作用,程序继续执行。
●如果表达式为假(返回值为零),assert() 就会报错,在标准错误流stderr中写入一条错误信息,显示没有通过表达式(包含这个表达式的文件名和行号)

2,assert的禁用

上面谈到了用assert来检查程序,但是程序中使用assert会增加程序的运行时间。当程序没有问题,我们不需要assert的时候,只需在#include<assert.h>的语句前面定义一个宏NDEBUG
例如👇🏻

#define NDEBUG
#include<assert.h>

这时候再编译程序,编译器就会禁用文件中所有的assert语句。

一般我们在Debug版本中使用assert,在Release中禁用assert
如:在vs这样的集成开发环境,Release版本中,是直接优化掉的;
但是在Linux的Release版本下,assert还起作用,需要我们自行禁用

🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/257549.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java数字化健康卫生智慧云HIS系统源码

基于云计算技术的B/S架构云HIS集挂号、处方、收费、取药、病历于一体,完全适配各类中小型医院、诊所。 一、云 HIS定义 1、云 HIS 系统是运用云计算、大数据、物联网等新兴信息技术&#xff0c;按照现代医疗卫生管理要求&#xff0c;在一定区域范围内以数字化形式提供医疗卫生…

C语言——输出菱形

法一&#xff1a; #include<stdio.h> #define N 7 //假设输出7层菱形 int main(){int i;//i控制第几行 int j;//j控制每一行空格的循环个数 int k;//k控制每一行*的循环次数 for(i1;i<4;i){//将图形分为两部分,前四行(第一部分) for(j1;j<4-i;j){//输出第i行的…

TwinCAT3 Modbus-TCP Client/Server使用

目录 一、环境配置和准备 1、PLC中安装TF6250-Modbus-TCP库 2、勾选TF6250的license 3、PLC工程中添加Tc2_ModbusSrv库文件 4、分别创建测试ModbusTCP测试的Server和Client程序 二、PLC作为Client端 1、设置测试电脑IP地址 2、运行MobusTCP测试工具 3、PLC端程序编写 …

Java期末复习题之抽象类、接口

点击返回标题->23年Java期末复习-CSDN博客 第1题. 首先设计一个学生抽象类Student&#xff0c;其数据成员有name(姓名)、age(年龄)和degree(学位)&#xff0c;以及一个抽象方法show()。然后由Student类派生出本科生类Undergraduate和研究生类Graduate&#xff0c;本科生类Un…

element el-pagination solt 使用

起初只是想修改一下&#xff0c;共多少条的颜色&#xff0c;和跳转至 发现并不支持 网上找通过js修改&#xff0c;因为我这是在 dialog里面的 好像并不能适用 mounted() {document.getElementsByClassName("el-pagination__jump")[0].childNodes[0].nodeValue &quo…

【EI会议征稿中】2024年第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)

2024年第四届人工智能、自动化与高性能计算国际会议&#xff08;AIAHPC 2024&#xff09; 2024 4th International Conference on Artificial Intelligence, Automation and High Performance Computing 2024第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)将于20…

名创优品出海更难了,Q3净利增速放缓

近日&#xff0c;有媒体报道称&#xff0c;名创优品受市场流传针对公司的做空报告&#xff0c;叠加高管团队两次减持&#xff0c;共计180万股&#xff0c;若对应25美元的价格&#xff0c;则达4500万美元(约3.2亿元)。 12月5日&#xff0c;其港股收盘股价下跌14.04%&#xff1b…

cpu 300% 爆满 内存占用不高 排查

top查询 cpu最高的PID ps -ef | grep PID 查看具体哪一个jar服务 jstack -l PID > ./jstack.log 下载/打印进程的线程栈信息 可以加信息简单分析 或进一步 查看堆内存使用情况 jmap -heap Java进程id jstack.log 信息示例 Full thread dump Java HotSpot(TM) 64-Bit Se…

嵌入式Linux:ARM驱动+QT应用+OpenCV人脸识别项目实现

一、前言&#xff1a; 这个项目主要分为两部分&#xff0c;客户端&#xff08;ARM板端&#xff09;负责利用OpenCV采集人脸数据&#xff0c;利用TCP将人脸数据发送给服务器&#xff0c;然后服务器根据人脸数据进行人脸识别&#xff0c;将识别后的结果返还给客户端&#xff0c;客…

查看电脑cuda版本

1.找到NVODIA控制面板 输入NVIDIA搜索即可 出现NVIDIA控制面板 点击系统信息 2.WINR 输入nvidia-smi 检查了一下&#xff0c;电脑没用过GPU&#xff0c;连驱动都没有 所以&#xff0c;装驱动…… 选版本&#xff0c;下载 下载后双击打开安装 重新输入nvidia-smi 显示如下…

报错处理集

这个报错处理集的错误来源于编译arm平台的so文件产生的。但是后续可以补充成linux一个大的错误处理集。 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 第一次整理的时间是2023年12月8日10:05:59&#xff0c;以下错误来源于欧拉系统编译…

NumPy学习:NumPy(Numerical Python)基础(一)

1.什么是NumPy NumPy 是 Python 中用于科学计算的基础包。 它是一个 Python 库&#xff0c;提供多维数组对象&#xff0c; 各种派生对象&#xff08;例如掩码数组和矩阵&#xff09;&#xff0c;以及 用于对阵列进行快速操作的各种例程&#xff0c;包括 数学、逻辑、形状操作、…