程序的执行过程中,一个函数调用另外一个函数以完成某一特定的功能称为函数调用。如果函数调用出现在一个表达式中,该表达式亦称为函数表达式。函数调用时,实参的值传递到形式参数中就实现了数据由主调函数到被调函数的传递。图5.2swap函数值传递调用时参数的变化情况③控制流程转移到被调函数执行。在设计传值调用函数时,函数的形式参数是普通变量。......
2023-11-20
如果被调函数的形式参数是指针型参数(即某种数据类型的指针变量作为函数的形式参数),则主调函数中对应的实际参数就必须是同类型指针值(地址量),这种函数调用参数传递的方式称为传地址值方式。
在传地址值函数调用方式中,实参和形参对应同一个存储首地址(本质上是同一数据),当被调函数通过形参修改了该存储区域的数据时,实际上也同时修改了实参数据。
【例5.5】 地址值参数传递函数调用示例。
在上面程序中,首先请读者注意与例5.3程序的不同之处,例5.5程序中函数swap的形式参数是指针型参数,函数内部对形式参数的操作使用的是指针变量指向的数据对象操作的方式;在主函数中调用swap函数时使用的实际参数是变量a和b存储单元的首地址,即函数调用的实际参数是变量a和b的指针。上面程序执行过程中,实际参数和形式参数的关系及变化如图5.5所示(图中用虚线表示两个函数区域的分界线,为了便于描述,假设变量a的存储首地址为1000,变量b的存储首地址为2000)。
图5.5 地址值传递函数调用时参数的变化情况
从程序执行过程可以看出,函数调用时主调函数将变量a和b的存储单元首地址传递到被调函数swap指针型形式参数中,参数传递完成后仍然会断开参数的传递通道,但由于形式参数通过参数传递得到了主调函数中变量a和b的首地址,形成了指针变量x指向实际参数变量a,指针变量y指向实际参数变量b的指针变量与数据对象之间的指向关系,即此时被调函数中的*x就是实参变量a,*y就是实参变量b。程序在执行了被调函数中的语句序列t=*x;、*x=*y;、*y=t;后达到了在被调函数swap中交换主调函数main中实际参数变量a和b值的目的。程序执行后的输出结果为:
swap函数调用前:a=3,b=5
swap函数调用后:a=5,b=3从上面程序执行的过程可以得出使用地址传送方式在函数之间传递数据的特点是:形参和实参在主调函数和被调函数中均使用同一存储单元,所以在被调函数中对该存储单元内容任何的变动必然会反映到主调函数的实参中。
利用通过指针形参在被调函数中可以修改主调函数对应实参的特性,还可以实现从一个被调函数中获取多个返回数据的目的。
【例5.6】 利用指针形式参数从函数中获取多个返回数据。
在例5.6的程序中,函数调用时将实参a和b的值复制给函数summul的形式参数x和y,实参变量mul将自己的地址传递给指针形式参数v。在被调函数summul中,v是指向实参mul的指针,*v就是mul,将a*b赋值给*v实质上就是赋值给变量mul,这样就通过函数的指针参数获取了被调函数中的数据。程序一次执行的结果如下:
请输入变量a和b的值:10,20 //10,20是从键盘上输入的数据
sum=30,mul=200//程序执行结果
虽然在被调用函数中使用指针型参数就提供了在被调函数中操作主调函数中实际参数的可能性。但并不是用了指针变量作函数的形式参数就一定可以在被调函数中操作或修改主调函数中的实参。在被调函数中是否能够操作或修改主调函数中实参值还取决于在被调函数中对指针形参的操作方式,操作指针形参变量指向的对象(即实参本身)则可以达到在被调函数中操作或修改主调函数实参的目的;但若操作的是指针形参变量本身则不能实现在被调函数中操作或修改主调函数实际参数的目的。(www.chuimin.cn)
【例5.7】 地址值参数传递函数调用示例。
在上面程序中,首先请读者注意与例5.5程序的不同之处,虽然两个程序中函数swap的形式参数都是指针型参数,但例5.5程序中swap函数内部对形式参数的操作使用的是指针变量指向的数据对象操作的方式;而上面程序中swap函数内部对形式参数的操作则是指针变量本身。上面程序执行过程中,实际参数和形式参数的关系及变化如图5.6所示(图中用虚线表示两个函数区域的分界线,为了便于描述,假设变量a的存储首地址为1000,变量b的存储首地址为2000)。
图5.6 地址值传递函数调用时参数的变化情况
从程序执行过程可以看出,函数调用时主调函数将变量a和b的存储单元首地址传递到被调函数swap指针型形式参数中,参数传递完成后仍然形成了指针变量x指向实际参数变量a,指针变量y指向实际参数变量b的指针变量与数据对象之间的指向关系。但在被调函数swap的执行过程中,通过辅助的指针变量t交换了指针变量x和y原来的指向,使得指针变量x指向实参变量b,而指针变量y指向实参变量a。但随着swap函数执行完成程序控制流程的返回,在函数swap中定义的所有自动变量x、y和t都被系统自动撤销。程序执行的结果并没使得主函数中的实参变量a和b交换内容。程序执行的结果为:
swap函数调用前:a=3,b=5
swap函数调用后:a=3,b=5
有关C语言程序设计基础(第3版)的文章
程序的执行过程中,一个函数调用另外一个函数以完成某一特定的功能称为函数调用。如果函数调用出现在一个表达式中,该表达式亦称为函数表达式。函数调用时,实参的值传递到形式参数中就实现了数据由主调函数到被调函数的传递。图5.2swap函数值传递调用时参数的变化情况③控制流程转移到被调函数执行。在设计传值调用函数时,函数的形式参数是普通变量。......
2023-11-20
图5.3程序运行结果说明:定义函数时指定的形参变量在未出现函数调用时,并不占用内存的存储单元。图5.4程序运行结果说明:程序中实参与形参同名,但两者的作用范围不同,程序开始执行时,为主函数中的变量n分配存储空间,实参n 在主函数main()中有效;主函数调用函数s(),有效的是形参n。程序的运行结果表明,当函数调用时,实参的值传送给形参,在被调函数内部,形参的变化不会影响实参的值。......
2023-10-21
我们通过下面的示例来说明按值传递方式中参数在函数之间的传递。图5.1实参与形参传递示意图当数组名作为函数参数时,函数传递数据方式采用的是“按地址传递”的方式,但要求形参和相对应的实参都必须是类型相同的数组。图5.3数组v的存储形式这样一来,形参数组中元素值的改变就会反过来影响到实参数组。......
2023-11-18
在C语言中,以函数首部声明函数的形式称为函数原型。使用函数原型是C语言的一个重要特征,主要作用是利用它在程序的编译阶段对调用函数的合法性进行全面检查。......
2023-11-18
程序在编译时将每一个变量名对应一个地址,在内存中不再出现变量名,而只有地址。对变量值的存取通过地址进行,访问方式通常有两种。直接利用变量地址进行存取。在例6.1 中,当系统执行输入语句scanf时,根据变量i 与地址的对应关系,找到变量i 的起始地址2011,然后把键盘输入的数值存入&i 所指示的单元中。变量i在内存中的地址和数值,如图6.1 所示。这里,指针变量只能存放地址,而不能存放其他数据。......
2023-10-21
系统标准库中有许多返回指针值的函数,如字符串处理、存储分配等标准库函数。返回指针值的函数的调用与普通函数的参数传递相同,所不同的是需要定义一个与其返回值数据类型相同的指针变量来接收返回值。求,要求使用静态局部变量和返回指针的函数方式进行处理。返回指针值函数设计最重要的一点是其返回值(指针),总体原则是:返回的指针所对应的内存空间不能因该指针函数的返回而被释放掉。......
2023-11-20
指针变量既可以作为函数的形参,也可以作为函数的实参。所以,为了解决通过被调用函数来实现主调函数中变量值的改变,必须使用指针变量作为函数的形参。在执行被调用函数时,使形参指针变量所指向的变量的值发生变化。函数调用完成后,通过不变的实参指针变量将变化的值保留下来。图6.8程序运行结果说明:函数swap 的形参是两个整型指针变量p1 和p2,故主函数在调用时,必须使用变量a 和b 的地址,即&a 和&b 作为实参。......
2023-10-21
相关推荐