一个函数如何实现return好几个返回值(借鉴学习前辈的文章,链接放文章里了)


三个方法来源:https://blog.csdn.net/weixin_45863921/article/details/105220460

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两种方法的大成,但是这里难点特别多,比如结构体的定义,结构体的赋值,结构体的引用等等

4.返回型参数法

该方法是练习的时候发现的,我也将那道题和这个方法做了结合,想要详细了解可以去看那篇文章
杨氏矩阵、返回型参数

这个方法的思想就是,在函数参数中多传入两个变量的地址,然后在函数中解引用访问这两个变量,可以把需要返回的值放入这两个变量,因为是传址,因此可以成功接收到。
但是,如果这两个参数是毫无意义的,那我觉得不如就用我之前介绍的三种方式。

这里的px,py就是返回型参数
参入的参数是极其有意义的。一、row、col代表矩阵的行列长度,这正是矩阵需要的。二、row、col都有代表下标的属性(意思是行列和下标都是代表位置的变量,用来接收目标下标也是情理之中)

#include<stdio.h>

void Young_matrix(int arr[3][3], int key, int *px, int *py)
{
	int x = 0;
	int y = *py-1;//(x,y)是初始矩阵右上角元素的下标
	while (x <= *px-1 && y >= 0)
	{
		if (arr[x][y] > key)
		{
			y--;//去掉一列
		}
		else if (arr[x][y] < key)
		{
			x++;//去掉一行
		}
		else
		{
			*px = x;
			*py = y;
			return;
		}
	}
	*px = -1;
	*py = -1;
}

int main()
{
	int arr[3][3] = { 1,2,3,4,5,6,5,7,8 };
	int key = 0;//要寻找的值
	scanf("%d", &key);
	int row = 3;
	int col = 3;
	Young_matrix(arr, key, &row, &col);

	if(-1 == row && -1 == col)
	{
		printf("找不到\n");
	}
	else
	{
		printf("找到了,下标是:(%d,%d)\n", row, col);
	}

	return 0;
}

结尾

这里是壮壮的学习之路,感谢大家的浏览与支持

  • 35
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 32
    评论
C语言中,线程函数通常只接受一个参数,即void类型指针。然而,我们可以通过使用结构体或者指针的方式,传递多个参数给线程函数。 首先,我们可以创建一个结构体来存储多个参数,然后将结构体传递给线程函数。例如: ```c #include <stdio.h> #include <pthread.h> struct ThreadArgs { int arg1; float arg2; char arg3; }; void *threadFunc(void *args) { struct ThreadArgs *myArgs = (struct ThreadArgs *)args; printf("arg1: %d\n", myArgs->arg1); printf("arg2: %f\n", myArgs->arg2); printf("arg3: %c\n", myArgs->arg3); pthread_exit(NULL); } int main() { pthread_t thread; struct ThreadArgs args = {10, 3.14, 'A'}; pthread_create(&thread, NULL, threadFunc, (void *)&args); pthread_join(thread, NULL); return 0; } ``` 上述代码中,我们定义了一个结构体ThreadArgs,包含了三个不同类型的参数。然后,我们在主函数中创建了一个ThreadArgs类型的变量args并对其进行初始化。接着,我们通过pthread_create函数创建了一个新的线程,并将args结构体的地址作为参数传递给线程函数threadFunc。 在线程函数中,我们将传递进来的参数强制转换为ThreadArgs类型指针,并访问各个参数的,然后打印输出。 这样,我们就成功地将多个参数传递给线程函数了。 另外一种方式是将参数存储在数组或者指针中,并将该数组或指针传递给线程函数。在线程函数内部,我们可以通过解引用指针或索引数组的方式来使用这些参数。 总之,通过使用结构体或者指针,我们可以很容易地传递多个参数给线程函数,并在函数内部使用这些参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值