指针变量作为函数参数详解,形参和实参之间的值传递如何传递?如何改变指针变量所指向的变量?

news2024/9/26 5:19:20

 函数的参数不仅可以是整型,浮点型,字符型等数据,还可以是指针类型;它的作用是将一个变量的地址传送到另一个函数中。

关于地址,指针,指针变量可以参考我的上一篇文章:

地址,指针,指针变量是什么?他们的区别?符号(*)在不同位置的解释?_juechen333的博客-CSDN博客指针是C语言中的一个重要概念,也是C语言的一个重要特色;使用指针,可以使程序简洁、紧凑、高效。不掌握指针,就没有掌握C语言的精华。https://blog.csdn.net/qq_57342311/article/details/129225045

目录

一、引入

1.1改变指针变量的值

1.2改变指针变量所指向的值

二、程序练习

2.1程序实现

2.2程序分析


一、引入

我们先来看一个问题:输入整数 a 和 b,按大小先后顺序输出 a 和 b。

可以使用多种方法来处理这个这个问题

1.1改变指针变量的值

#include<stdio.h>
int main()
{
	int* p1, * p2, * p, a, b;	//定义指向整型的指针变量和整型变量
	printf("请输入两个整数:");
	scanf_s("%d,%d", &a, &b);
	p1 = &a;	//赋予a的地址,指向变量a
	p2 = &b;	//赋予b的地址,指向变量b
	if (a < b)	//如果a<b,交换p1和p2
	{
		p = p1;
		p1 = p2;
		p2 = p;
	}
	printf("a=%d, b=%d\n", a, b);	//输出a, b的值
	printf("max = %d, min = %d\n", *p1, *p2);	//输出指针变量p1和p2所指向的变量值
	return 0;
}

判断语句中也可以改为直接对 p1 和 p2 赋予新值,不用中间变量 p,使程序更加简练。

{
	p1 = &b;
	p2 = &a;
}

运行结果:

程序分析:

由图可知,指针变量 p1 和 p2 的值发生了交换,而变量 a,b的值未发生交换。

这种算法是不交换原来变量的值,而是交换指针变量的值。

1.2改变指针变量所指向的值

用指针变量作为函数参数

#include<stdio.h>
int main()
{
	void swap(int* p1, int* p2);
	int* point_1, * point_2, a, b;	//定义指向整型的指针变量和整型变量
	printf("请输入两个整数:");
	scanf_s("%d,%d", &a, &b);
	point_1 = &a;	//赋予a的地址
	point_2 = &b;	//赋予b的地址
	if (a < b)	//如果a<b,调用swap函数
	{
		swap(point_1, point_2);
	}
	printf("a=%d, b=%d\n", a, b);	//输出a, b的值
	printf("max = %d, min = %d\n", *point_1, *point_2);	//输出两个指针变量的值所指向的变量值
	return 0;
}

void swap(int* p1, int* p2)	//自定义函数,交换指针变量p1和p2
{
	int* temp;
	temp = p1;
	p1 = p2;
	p2 = temp;
}

运行结果:

程序分析:

由运行结果我们可以看出:变量 a 和 b 未发生交换,指针变量 point_1 和 point_2 的值也没有发生交换,那么函数 swap 到底实现交换功能了吗?我们将swap函数添加一个输出语句看一下结果。

void swap(int* p1, int* p2)	//自定义函数,交换指针变量p1和p2
{
	int* temp;
	temp = p1;
	p1 = p2;
	p2 = temp;
	printf("*p1 = %d, *p2 = %d\n", *p1, *p2);
}

可知在swap函数中,*p1 = 8,*p2 = 5;实现了交换的功能,但没有将改变的值传回去。

结合函数调用的知识,我们可以知道调用函数时,采取的是单向值传递,形参的改变不能使实参也随之改变。

由图可知,指针变量 point_1 和 point_2 的值没有发生交换,那么他们指向的变量也没有发生变化。

如果在函数中我们能使指针变量所指向的变量发生变化,那么就可以达到交换原变量的目的,此时而指针变量本身的值(即地址)不发生变换

我们对 swap 函数稍作修改,使它访问到指针变量所指向的变量。

void swap(int* p1, int* p2)		//自定义函数,交换指针变量所指向的变量*p1和*p2
{
	int temp;
	temp = *p1;		//交换*p1和*p2
	*p1 = *p2;
	*p2 = temp;
}

运行结果:

程序分析:

从结果我们可以看出,变量 a 和 b 发生了交换,也就是指针变量 point_1 和 point_2 指向的变量发生了交换。

由图可知,指针变量 point_1 和 point_2 的值(即地址 &a,&b)未发生变化,指针变量所指的变量(即变量 a,b)发生了变化。

这种算法是交换原来变量的值,而不交换指针变量的值。

这里需要注意的是中间变量 temp 的定义形式:

void swap(int* p1, int* p2)		//自定义函数,交换指针变量所指向的变量*p1和*p2
{
	int* temp;          //指针变量temp
	*temp = *p1;		//交换*p1和*p2
	*p1 = *p2;
	*p2 = *temp;
}

这时程序虽然语法上没有报错,但编译时会报错,*p1 就是 a,是整型变量,而 *temp 是指针变量 temp 所指向的变量,由于未给 temp 赋值,因此temp的值是无法确定的,所以temp所指向的存储单元也是未知的,因而 *temp = *p1 就是向一个未知的存储单元赋值,这是不合法的。

总结:

函数的调用只可以得到一个返回值,而使用指针变量作为参数,可以得到多个变化了的值。

二、程序练习

输入3个整数 a,b,c,要求按大小顺序将他们输出,用函数实现。

2.1程序实现

#include<stdio.h>
int main()
{
	void exchange(int* q1, int* q2, int* q3);	//声明函数,后面需要调用
	int a, b, c, * point_1, * point_2, * point_3;
	printf("请输入三个整数:");
	scanf_s("%d,%d,%d", &a, &b, &c);
	point_1 = &a; point_2 = &b; point_3 = &c;
	exchange(point_1, point_2, point_3);
	printf("Max = %d, Mid = %d, Min = %d\n", a, b, c);
	return 0;
}

void exchange(int* q1, int* q2, int* q3)	//自定义函数,交换3个变量的值
{
	void swap(int* p1, int* p2);		//声明函数,后面需要调用
	if (*q1 < *q2) { swap(q1, q2); }
	if (*q1 < *q3) { swap(q1, q3); }
	if (*q2 < *q3) { swap(q2, q3); }
}

void swap(int* p1, int* p2)		//自定义函数,交换指针变量所指向的变量*p1和*p2
{
	int temp;
	temp = *p1;		//交换*p1和*p2
	*p1 = *p2;
	*p2 = temp;
}

2.2程序分析

exchange 函数的作用是对3个数按大小排序,在执行 exchange 函数过程中,要嵌套调用 swap 函数,swap 函数的作用是对两个数按大小排序,通过调用 swap 函数(最多调用3次)实现3个数的排序。

主函数中3个指针变量的值未发生改变,3个指针变量所指向的变量的值发生了改变。

要熟练掌握指针变量和指针变量所指向变量之间的关系,避免混淆!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

线程的基本方法

线程等待&#xff1a;wait方法 调用wait方法的线程会进入WAITING状态&#xff0c;只有等到其他线程的通知或程序被中断才会返回。调用wait方法后会释放对象的锁&#xff0c;因此 wait方法一般被用于同步方法或同步代码块中 。 线程睡眠&#xff1a;sleep方法 调用sleep方法会导…

Spring Boot 版本升级2.2.11.RELEASE至2.7.4

2.2.11.RELEASE > 2.7.4项目更新spring-boot-starter-parent 主依赖&#xff0c;导致项目跑不起了日志也没有输出有用信息&#xff0c;自己查看源码调试启动入口打断点&#xff0c;一步步进入方法定位项目停止代码我的项目执行到SpringApplication.class 的152行代码会停止项…

华为HCIE学习之Openstack Glance组件(glance对接swift)

文章目录一、Glance的结构二、服务部署流程三、将glance存储在swift中1、默认使用swift来存储2、指定可以存在swift中3、swift版本4、keystone的endpoint地址&#xff08;当glance去找swift时通过keystone去找&#xff09;5、租户名:用户名&#xff0c;用户必须拥有admin角色6、…

【C语言】自定义类型:结构体、枚举、联合

目录 1.结构体 1.1结构体类型 1.2结构体的自引用 1.3结构体的初始化 1.4结构体内存对齐 //对齐 //offsetof //修改默认对齐数 1.5结构体传参 2.位段 2.1位段的内存开辟 2.2位段的内存分配 3.枚举 4.联合&#xff08;共用体&#xff09; //判断大小端 1.结构体…

【GO】k8s 管理系统项目23[前端部分–工作负载-Pod]

k8s 管理系统项目[前端部分–工作负载-Deployment] 1. 代码部分 1.1 准备工作 由于Pod页面和Deployment内容差不多.那么就直接把Deployment的内容复制过来.再做修改. 替换Deployment为Pod替换Deploy为Pod替换deployment为pod替换deploy为pod禁用新增的按钮,删除新增方法,表…

django后端服务、logstash和flink接入VictoriaMetrics指标监控

0.简介 通过指标监控可以设置对应的告警&#xff0c;快速发现问题&#xff0c;并通过相应的指标定位问题。 背景&#xff1a;使用的 VictoriaMetrics(简称 VM) 作为监控的解决方案&#xff0c;需要将 django 服务、logstash 和 flink 引擎接入进来&#xff0c;VM 可以实时的获…

SpringBoot:SpringBoot配置文件.properties、.yml 和 .ymal(2)

SpringBoot配置文件1. 配置文件格式1.1 application.properties配置文件1.2 application.yml配置文件1.3 application.yaml配置文件1.4 三种配置文件优先级和区别2. yaml格式2.1 语法规则2.2 yaml书写2.2.1 字面量&#xff1a;单个的、不可拆分的值2.2.2 数组&#xff1a;一组按…

操作系统权限提升(十八)之Linux提权-内核提权

Linux 内核提权 Linux 内核提权原理 内核提权是利用Linux内核的漏洞进行提权的&#xff0c;内核漏洞进行提权一般包括三个环节&#xff1a; 1、对目标系统进行信息收集&#xff0c;获取到系统内核信息及版本信息&#xff1b; 2、根据内核版本获取其对应的漏洞以及EXP 3、使…

第七届蓝桥杯省赛 C++ A/B组 - 四平方和

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;蓝桥杯题解集合 &#x1f4dd;原题地址&#xff1a;四平方和 &#x1f4e3;专栏定位&#xff1a;为想参加蓝桥杯的小伙伴整理常考算法题解&#xff0c;祝大家…

Docker简介与用法

文章目录1、Docker简介1.1、Docker能解决什么问题1.2、什么是虚拟机技术1.2.1、虚拟机的缺点1.3、什么是容器1.3.1、容器与虚拟机比较1.4、分析 Docker 容器架构1.4.1、Docker客户端和服务器1.4.2、Docker 镜像(Image)1.4.3、Docker 容器(Container)1.4.4、Docker 仓库(reposit…

Windows程序员学习Linux环境内存管理

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天我们来重新审视一下Windows程序员如何学习Linux环境内存管理。由于很多程序在Windows环境下开发好后&#xff0c;还要部署到Linux服务器上去&#xff0c;所以作为Windows程序员有必要学习Linux环境的内存…

【计算机三级网络技术】 第三篇 IP地址规划技术

IP地址规划技术 文章目录IP地址规划技术一、IP 地址规划以及划分地址新技术1.IP地址的标准分类&#xff08;第一阶段&#xff09;2.划分子网的三级地址结构(第二阶段)3.构成超网的无类域间路由技术(第三阶段)4.网络地址转换技术(第四阶段)二、IP 地址分类1.A类、B类与C类IP地址…

数据的表示和运算

文章目录数制与编码进制间的转换BCD码定点数与浮点数定点数是什么&#xff1f;浮点数是什么&#xff1f;定点数与浮点数的区别机器数和真值原码、反码、补码、移码基本定义整数的加减法刷题小结最后数制与编码 进制间的转换 二进制、八进制、十进制、十六进制之间的转换不用多…

前端杂学1

1.简单且必须掌握的 1.MVVM是什么 将MVC中的V变为了MVVM&#xff0c;实现了双向绑定。其中VM就是vue的作用&#xff0c;这样页面的动态化可以通过vue来操作&#xff0c;而不是页面直接与后端操作&#xff0c;实现了前后端的分离 2.为什么vue采用异步渲染 &#xff1f; 调…

Kubernetes之服务发现

本文使用wordpressmysql搭建个人博客来讲解服务发现相关知识。 环境准备 wordpress需要连接到mysql才能正常工作&#xff0c;所以需要为mysql的pod创建一个mysql的svc&#xff0c;只要不删除重建svc&#xff0c;其IP不会变。 此时wordpress的pod需要连接mysql的svc的时候&…

HyperGBM用4记组合拳提升AutoML模型泛化能力

本文作者&#xff1a;杨健&#xff0c;九章云极 DataCanvas 主任架构师 如何有效提高模型的泛化能力&#xff0c;始终是机器学习领域的重要课题。经过大量的实践证明比较有效的方式包括&#xff1a; 利用Early Stopping防止过拟合通过正则化降低模型的复杂度使用更多的训练数…

第四阶段01-酷鲨商城项目准备

1. 关于csmall-product项目 这是“酷鲨商城”大项目中的“商品管理”项目&#xff0c;是一个后台管理项目&#xff08;给管理员&#xff0c;或运营人员使用的项目&#xff0c;并不是普通用户使用的&#xff09;&#xff0c;并且&#xff0c;只会涉及与发布商品可能相关的功能开…

企业工程项目管理系统平台(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)

工程项目管理软件&#xff08;工程项目管理系统&#xff09;对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营&#xff0c;全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…

React(二):jsx事件绑定、条件渲染、列表渲染、jsx的本质、购物车案例

React&#xff08;二&#xff09;一、jsx事件绑定1.this的绑定方式2.jsx中绑定this的三种方式3.事件对象和传参&#xff08;1&#xff09;事件对象怎么传&#xff08;2&#xff09;其他参数怎么传&#xff1f;二、条件渲染1.直接if-else2.三元表达式3.利用逻辑中断4.案例练习5.…

HTML#5表单标签

一. 表单标签介绍表单: 在网页中主要负责数据采集功能,使用<form>标签定义表单表单项: 不同类型的input元素, 下拉列表, 文本域<form> 定义表单<input> 定义表单项,通过typr属性控制输入形式<label> 为表单项定义标注<select> 定义下拉列表<o…