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;
	else
		z = 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还起作用,需要我们自行禁用

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python基础语法详解,零基础入门必须掌握的知识点

文章目录 一、Python输出1、repr() 或 str() 转成字符串2、字符串填充空格进行格式化3、!a (使用 **ascii()**), !s (使用 **str()**) 和 !r (使用 **repr()**) 可以用于在格式化某个值之前对其进行转化 二、Python标识符三、Python保留字符&#xff08;关键字&#xff09;四、…

【CPCI会议、知网检索】第三届城市规划与区域经济国际学术会议(UPRE 2024)

第三届城市规划与区域经济国际学术会议&#xff08;UPRE 2024&#xff09; 2024 3rd International Conference on Urban Planning and Regional Economy 第三届城市规划与区域经济国际学术会议&#xff08;UPRE 2024&#xff09;于2024年4月19-21日在泰国曼谷举行。会议旨在…

Ubuntu安装nvidia GPU显卡驱动教程

Ubuntu安装nvidia显卡驱动 1.安装前安装必要的依赖 sudo apt-get install build-essential sudo apt-get install g sudo apt-get install make2.到官网下载对应驱动 https://www.nvidia.cn/Download/index.aspx?langcn 3.卸载原有驱动 sudo apt-get remove --purge nvidi…

【Python系列】Python函数

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

帆软报表决策报表改变屏幕大小后出现字体大小或滚动条异常解决方案:双向自适应

帆软报表决策报表改变屏幕大小后出现字体大小或滚动条异常。 解决方案&#xff1a;在模板和报表块中配置双向自适应 在每一个报表块中设置&#xff1a;

HGNN复现

python版本&#xff1a;3.6.13 torch版本&#xff1a;http://download.pytorch.org/whl/cpu/torch-0.4.0-cp36-cp36m-win_amd64.whl 安装torch&#xff1a; pip install http://download.pytorch.org/whl/cpu/torch-0.4.0-cp36-cp36m-win_amd64.whl 除了numpy、matplotlib、…

Ubuntu环境下使用GDB调试C语言项目

1. 安装gdb //终端输入 sudo apt-get install gdb 2. 启动gdb gdb GDB常用命令大全&#xff0c;参考此篇博客 使用GDB调试C项目中的makefile 1.在内核配置中启用调试信息&#xff1a; 在内核配置中&#xff0c;确保启用了调试信息。可以通过以下步骤来配置内核&#xff1a…

验证码的多种生成策略

&#x1f60a; 作者&#xff1a; 瓶盖子io &#x1f496; 主页&#xff1a; 瓶盖子io-CSDN博客 第一种 a.导入依赖 <dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.10</ver…

解决Kettle无法传输生偏字的问题

最近在搞数据传输&#xff0c;然后涉及到人名的时候&#xff0c;难免会碰到生僻字&#xff0c;utf8是无法存储的&#xff0c;然后我把目标表改为utf8mb4&#xff0c;但是还是无法传输生僻字&#xff0c;这就很奇怪了&#xff0c;明明两边的数据库都是MySQL 5.7x&#xff0c;但是…

3D热图绘制教程

本期教程 原文链接https://mp.weixin.qq.com/s/EyBs6jn78zOomcTv1aP52g 6 3D热图的绘制教程 基于《热图绘制教程》专栏,本教程已更新了5个章节,不知道大家是否有所收获。对于小杜个人来说,真的需要不断的复习和练习才可以记住,但是在自己使用的时候也需要重复的看自己的学…

【Linux】resolv.conf 文件

resolv.conf resolv.conf 文件 是 DNS 的 client 端使用的文件&#xff0c;用于设置 DNS 服务器的 ip 地址以及 DNS 域名&#xff0c;还可以配置域名搜索顺序等等。主要包含如下关键字&#xff1a;nameserver、domain、search、sortlist、options。设置的格式都是 关键字空格 …

【如何写论文】——写作提效的n个技巧:Word图、表自动编号 +Zotero实现参考文献自动化

目录 一、Word图、表自动编号1.1、单级编号1.2、多级编号1.3、交叉引用1.4、修改题注格式 二、Zotero实现参考文献自动化最后 一、Word图、表自动编号 在论文写作中&#xff0c;通常会包含数十张图片或表格。默认情况下&#xff0c;这些图片和表格都是没有编号的。 然而&…

C语言第十六集(前)

1.关于那个整形存储入char的 是先取好补码,再截断 例: 2.%u是以十进制的形式打印无符号整数 3.注意(背):存储的char类型变量的补码为10000000的直接解析为-128 4.signed char 类型的变量取值范围是-128~127 5.unsigned char 类型的变量取值范围是0~255 6.有符号类型的变量…

Linus:我休假的时候也会带着电脑,否则会感觉很无聊

目录 Linux 内核最新版本动态 关于成为内核维护者 代码好写&#xff0c;人际关系难处理 内核维护者老龄化 内核中 Rust 的使用 关于 AI 的看法 参考 12.5-12.6 日&#xff0c;Linux 基金会组织的开源峰会&#xff08;OSS&#xff0c;Open Source Summit&#xff09;在日…

matplot绘图时图像太大报错但能保存

matplot绘图时&#xff0c;图像太大&#xff0c;可能在jupyter里面报错&#xff0c;但是图像可以保存。 报错&#xff1a;Image size of 12237479x675 pixels is too large. It must be less than 2^16 in each direction. 在这里插入图片描述

编程创意汇聚地,打造个性作品集 | 开源日报 No.97

spring-projects/spring-boot Stars: 70.4k License: Apache-2.0 Spring Boot 是一个用于简化 Spring 应用程序开发的框架&#xff0c;它通过提供默认配置和约定大于配置的方式来减少开发者的工作量。Spring Boot 可以快速地创建独立的、生产级别的基于 Spring 框架的应用程序…

简单的越权

越权漏洞 危害 越权漏洞分为水平越权和垂直越权&#xff1b; 水平越权容易造成敏感信息的泄露&#xff1b;垂直越权容易造成服务器权限丢失。 普通用户执行管理员操作时&#xff0c;可能会执行一些上传操作&#xff0c;例如一句话木马 挖掘 我会在数据包中寻找例如id、us…

报错处理集

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

单片机第三季-第四课:STM32下载、MDK和调试器

目录 1&#xff0c;扩展板使用的STM32芯片类型 2&#xff0c;使用普中科技软件下载程序 3&#xff0c;keil介绍 4&#xff0c;JLINK调试器介绍 5&#xff0c;使用普中的调试器进行debug 6&#xff0c;使用Simulator仿真 1&#xff0c;扩展板使用的STM32芯片类型 扩展版…

numpy数据读取保存及速度测试

目录 数据保存及读取 速度比对测试 数据保存及读取 代码示例&#xff1a; # 导入必要的库 import numpy as np # 生成测试数据 arr_disk np.arange(8) # 打印生成能的数据 print(arr_disk) # numpy保存数据到本地 np.save("arr_disk", arr_disk) # 加载本地数据…