传值调用与传址调用的运行时间区别

在传值调用(call by value)中,函数参数的值被复制并传递给函数的形式参数。在函数中对形式参数的修改不会影响到原始的实际参数。

在传址调用(call by reference)中,函数参数的地址被传递给函数的形式参数,使得函数可以直接访问和修改原始实际参数的值。

这两种方式在实际的代码编写中,运用广泛,但是这两种情况在运行时间上,却有着很大的差别,下面我们就来深究其原因

1、传值调用

#include <stdio.h>
//创建一个结构体如下
struct ABC
{
	int a[10000];
	char b[20000];
	double c[10000];
};
//传值接收
void pass_by_value(struct ABC ss)
{
	;
}

int main()
{
	clock_t start_time, end_time;
	double execution_time;
	struct ABC abc = { {0},{0,{0}} };
	// 记录开始时间
	start_time = clock();
	for (int i = 0; i < 1000000; i++)
		pass_by_value(abc);
	// 记录结束时间
	end_time = clock();
	// 计算执行时间,单位为秒
	execution_time = (double)(end_time - start_time) / CLOCKS_PER_SEC;

	printf("传值调用程序执行时间: %f秒\n", execution_time);
	return 0;
}

运行上述代码,我们发现结果如下:

 运行时间需要2.5s,这对于一个计算机来说,已经是相当长的时间了,虽然我们一共迭代了一百万次

2、传址调用

#include <stdio.h>
#include <time.h>

//创建一个结构体如下
struct ABC
{
	int a[10000];
	char b[20000];
	double c[10000];
};

//传值接收
void pass_by_value(struct ABC ss)
{
	;
}
//传址接收
void pass_by_address(struct ABC* ss)
{
	;
}


int main()
{
	clock_t start_time, end_time;
	double execution_time;
	struct ABC abc = { {0},{0,{0}} };
	// 记录开始时间
	start_time = clock();
	for (int i = 0; i < 1000000; i++)
		pass_by_value(abc);
	// 记录结束时间
	end_time = clock();
	// 计算执行时间,单位为秒
	execution_time = (double)(end_time - start_time) / CLOCKS_PER_SEC;

	printf("传值调用程序执行时间: %f秒\n", execution_time);



	// 记录开始时间
	start_time = clock();
	for (int i = 0; i < 1000000; i++)
		pass_by_address(&abc);
	// 记录结束时间
	end_time = clock();
	// 计算执行时间,单位为秒
	execution_time = (double)(end_time - start_time) / CLOCKS_PER_SEC;

	printf("传址调用程序执行时间: %f秒\n", execution_time);


	return 0;
}

运行程序,结果如下:​​​​​​​

 代码的运行速度可以说不是一个数量级,但是为什么会出现这种情况呢,我们调试来看

 此处可以看到,在传址调用时,程序会在内存中重新开辟一块新内存来保存传递过来这个结构体,因此,每调用一次这个传址调用的程序,都会新生成一个结构体,而我们写的这个结构体,一共占用140000个字节,所以程序运行速度较慢。

接下来我们来看传址调用

 可以看到,传递的仅仅是一个地址,而在64位机器上,一个地址只占用8个字节,因此运行时间较短,哪怕迭代十万次,也仅仅只用了4毫秒,很多机器正是为了保证速度,才使用C语言进行编程,因此这节约的时间非常关键。

讲到这里,或许有人会说,传递地址的话,会不会产生风险,比如我传过去的值被修改了。

其实我们有一种方法可以保护我们的数值不被修改,那就是在函数接收的地方加入const,例如:

//传址接收
void pass_by_address(const struct ABC* ss)
{
	;
}

 这样,如果强行对数值进行修改,就会出现如下错误

 如图,编译将会无法通过。

综上:当我们在使用C语言调用函数时,当涉及一些大的数组或者结构体传参时,尽量使用地址传参,这样可以大幅提升程序运行效率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值