对子程序(函数)传参的理解,不要再错了

2022/12/11 4:24:59

本文主要是介绍对子程序(函数)传参的理解,不要再错了,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

首先问一个问题:把指针作为参数就是传引用的方式传递参数,这种说法对吗?

子程序参数的概念

很多时候,程序需要子程序作用于由主程序创建的对象,这需要通过参数来实现。参数在程序中被称为实际参数,在子程序中被称为形式参数。程序给子程序传递参数的方式有两种:

1.传值

程序和子程序创建两组不同的对象(变量),在主程序中创建的对象属于主程序,在子程序中创建的对象属于子程序,对象的作用域是不同的。程序和子程序的通信是单方向的,即从主程序到子程序,主程序传递实际参数的值,存储到子程序相应的形式参数中。

2.传引用

允许子程序改变主程序中变量的值,对象(变量)的内存地址被主程序和子程序共享,实际参数和形式参数指向同一个对象。用个形象的说法,程序和子程序可以共同使用一个box,主程序可以把一样东西放在box里给子程序,子程序可以换一样东西放在box里给主程序。

对C语言函数参数的探究

现有如下代码:

#include<stdio.h>
void function1(unsigned int parameter){
	parameter += 50;
}
void function2(unsigned int *parameter){
	*parameter += 50;
}
void function3(unsigned int *parameter){
	parameter++;	/*所指类型长度为4字节,指针会加上4个内存单元*/
	printf("The parameter address is %d\n",parameter);
}
int main(){
	unsigned int object = 325, *pointer = &object, value = (unsigned int)pointer;
	function1(object);
	printf("The object is %d\n",object);
	function2(pointer);
	printf("The object is %d\n",object);
	function3(pointer);
	printf("The pointer is %d\n",pointer);
	function2((unsigned int*)value);
	printf("The object is %d\n",object);
	return 0;
}

对其按32位编译运行结果如下:
图片描述
function1定义参数形式为unsigned int型,而function2和function3参数都为unsigned int指针型。打印的第一个结果为325没有改变,对function1的调用说明了形式参数的改变不影响实际参数;注意function2改变的是*parameter(parameter指向的地址存放的值),调用function2打印375,object的值被改变了,但是参数本身都没改变;再看function3改变的是parameter指针(形式参数),打印其值为6422304(传递来的指针值被加了4),而调用function3打印的值为6422300,刚好是参数原来的值,证明了参数为指针(地址)时,实际参数依然不变,之前object之所以改变,是因为function2中形式参数和实际参数都指向了object的地址且改变的就是参数指向的地址存放的值;最后注意看value并非是一个指针变量,但是却可以把value当成指针来用,使用value传参调用function2也能改变object的值(可能你会感觉类型转换太明显了,如果编译器允许,你可以全部用自动类型转换,效果是一样的)。
综上所述,C语言函数传参实质上只有传值的方式,而不会把参数看成引用,也就是把所有参数视为值的形式。所以,把指针(地址)作为参数就是传引用的方式传递参数这种说法是错误的。

思考练习

请将以下代码加入到之前的代码中,自行完成对value的测试代码并编译运行。

void function4(unsigned int parameter){
	*(unsigned int*)parameter += 50;
}

与function2((unsigned int*)value);进行比较,你能发现什么吗?



这篇关于对子程序(函数)传参的理解,不要再错了的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程