C语言一个函数如何实现好几个return返回值

 更新时间:2022年08月12日 08:27:27   作者:壮壮  
本文主要介绍了C语言一个函数如何实现好几个return返回值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1.全局变量法(慎用)(宏定义也可以实现)

使用全局变量的原因

由于全局变量的作用域是从变量定义处开始直到程序结束,而对于编写有多个返回值的C语言函数,我们可以考虑把要返回的多个值定义成全局变量。当函数被调用时,全局变量被更改,我们再把更改后的全局变量值应用于主调函数中。函数被调用后被更改后的全局变量值即为函数的数个返回值

//实例:自定义一个函数,依次分别返回两个数中较大的和较小的
 
#include <stdio.h>
 

int max = 0;
int min = 0;

void max_min(int x, int y)
{
	max = x;
	min = x;
	max = (x > y) ? x : y;
	min = (x < y) ? x : y;
}

int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	max_min(a, b);
	printf("%d %d", max, min);
	return 0;
}

运行结果

方法分析

我们都知道,设计函数很重要的一点就是高内聚低耦合,函数设计出来最好是一个独立的模块,内部的程序最好与外部减少纠缠,但是这种通过全局变量来实现多个return返回值的方法就严重破坏了函数的独立性,原因很简单,你想,全局变量在整个源程序都是可以使用的,如果你在函数内部使用了这个全局变量,但是这个全局变量也很有可能在其他地方被其他代码给改掉。所以我的建议就是如果整个程序代码比较少的时候可以用用,如果程序很复杂,涉及多个函数多个文件的话,还是考虑一下下面的几种方法

2.数组指针法

使用数组指针法的原因

对于函数参数的传递,我们知道有传值和传址这两种方法。我们来复习一下这两个方法的差异,传值的话,函数参数是形参,形参是实参的一份临时拷贝,对形参的修改不会影响实参;传址的话,我们把实参的地址传过来,函数形参可以通过这个门牌号(地址)找到实参,因此也可以通过这个地址对实参进行修改。因此我们可以在主函数定义一个数组,将需要函数返回的值以变量的形式定义在这个数组里,然后把数组地址传给函数,通过数组地址找到数组并把返回值存放到数组里,这样我们就可以在数组里看到多个返回值了

//实例:自定义一个函数,依次分别返回两个数中较大的和较小的
// 
 #include <stdio.h>
 
void max_min(int arr[])
{
	if (arr[1] > arr[0])
	{
		int tmp = 0;
		tmp = arr[1];
		arr[1] = arr[0];
		arr[0] = tmp;
	}
}


int main()
{
	int arr[2] = { 0 };
	int i = 0;
	printf("请输入你要比较的两个数:>\n");
	for (i = 0; i < 2; i++)
	{
		scanf("%d", &arr[i]);
	}
	max_min(arr);
	printf("较大的数是: %d\n", arr[0]);
	printf("较小的数是: %d\n", arr[1]);
	return 0;
}

运行结果

方法分析

这种方法的缺陷就是要求返回值的类型必须是一致的,如果不一致可以看看第三种方法(第一个方法也可以实现多个返回值类型不一致的函数,但是就是太危险了)

3.结构体指针法

使用结构体指针法的原因

我们能够知道,结构体里能够定义多种类型的数据,但是存值方法却类似数组,所以利用结构体简直就是集上面两种方法之大成(存值形式类似数组的话,也就可以传址给函数,避免出现全局变量的尴尬情况,而结构体内多种数据类型又避免了数组只能存放一种数据类型的尴尬,真的棒!!!)。。但是初学者难以理解结构体这个知识点

代码实例

//实例:自定义一个函数,用户能输入学生的姓名,班级,总成绩和排名,并将这些数据返回给主函数进行调用

#include<stdio.h>
#include<string.h>

struct stu
{
	char name[20];
	int class;
	float score;
	int rank;
};

void scanf1(struct stu* ps1)
{
	char name1[20] = { 0 };
	int class1 = 0;
	float score1 = 0.0f;
	int rank1 = 0;
	scanf("%s%d%f%d", name1, &class1, &score1, &rank1);
	strcpy(ps1->name, name1);
	ps1->class = class1;
	ps1->score = score1;
	ps1->rank = rank1;
}

int main()
{
	struct stu s1;
	scanf1(&s1);
	printf("口腔医学210%d班的%s同学,你的总成绩是%f,在该专业排名第%d", s1.class, s1.name, s1.score, s1.rank);
	return 0;
}

运行结果

方法分析

这个代码是集1.2两种方法的大成,但是这里难点特别多,比如结构体的定义,结构体的赋值,结构体的引用等等

结尾

到此这篇关于C语言一个函数如何实现好几个return返回值的文章就介绍到这了,更多相关C语言 return返回值内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++赋值运算符

    C++赋值运算符

    这篇文章主要介绍了C++赋值运算符,C++当中允许类对象赋值,这是通过默认的重载赋值运算符实现的,下面我们就来介绍介绍该内容吧,,需要的朋友可以参考一下
    2022-01-01
  • Windows网络编程之winsock实现文件传输示例

    Windows网络编程之winsock实现文件传输示例

    这篇文章主要介绍了Windows网络编程之winsock实现文件传输示例,对于学习Windows网络程序设计来说具有很好的学习借鉴价值,需要的朋友可以参考下
    2014-08-08
  • C语言实现时间戳转日期的算法(推荐)

    C语言实现时间戳转日期的算法(推荐)

    下面小编就为大家带来一篇C语言实现时间戳转日期的算法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • C/C++利用栈和队列实现停车场管理系统

    C/C++利用栈和队列实现停车场管理系统

    数据结构的课程设计一般都不是很好理解,今天小编为大家总结了一下c和c++版本的常见栈和队列的的停车场管理程序,需要的小伙伴可以参考一下
    2022-06-06
  • C/C++后端学习与练习深入

    C/C++后端学习与练习深入

    这篇文章主要介绍了C/C++对于后端的学习与练习,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Visual Studio 2022 激活码(亲测可用)

    Visual Studio 2022 激活码(亲测可用)

    在 Visual Studio 2019 的基础上,新版集成开发坏境提供了非常多的改进,包括对 64 位、.NET 6 的支持,为核心调试器提供更好的性能。本文给大家分享Visual Studio 2022 激活码,需要的朋友参考下吧
    2021-12-12
  • 关于移位操作的一点重要说明

    关于移位操作的一点重要说明

    下面小编就为大家带来一篇关于移位操作的一点重要说明。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • 基于Protobuf C++ serialize到char*的实现方法分析

    基于Protobuf C++ serialize到char*的实现方法分析

    本篇文章是对Protobuf C++ serialize到char*的实现方法进行了详细的分析介绍。需要的朋友参考下
    2013-05-05
  • C++中的String的常用函数用法

    C++中的String的常用函数用法

    这篇文章主要介绍了C语言中String的常用函数用法,对学习String的小伙伴有一定的参考价值,感兴趣的小伙伴可以借鉴一下
    2023-03-03
  • C++编写LINUX守护进程的实现代码

    C++编写LINUX守护进程的实现代码

    这篇文章主要介绍了如何使用C++实现LINUX守护进程,文中代码非常详细,供大家学习参考,感兴趣的小伙伴可以了解下
    2020-06-06

最新评论