`
mywebcode
  • 浏览: 988367 次
文章分类
社区版块
存档分类
最新评论

再谈C语言有参函数调用时参数值传递问题

阅读更多

C语言有参函数调用时参数间数据传递问题

C语言中在发生有参函数调用时,实参变量与形参变量之间的数据都是单向的“值传递”方式。包括指针变量和数组名作参数的情况。

C语言要求函数的实参要有确定的值,在函数调用时给形参分配相应的内存单元,同时将实参的“值”赋(复制)给形参,实现数据从实参到形参的传递(‘值传递’方式)。因为是复制,所以在操作副本(形参)过程中不会影响到原本(实参)内容。

首先,作为函数实参的量包括常量、变量和表达式。其中变量又包括简单变量、数组元素、数组名、指针变量等。不同类型变量作参数实现的数据传递方式相同,效果不同。所谓方式相同即都是参数间数据单向的“值传递”,效果不同是指被调函数能否改变主调函数中变量的值。


情况一:简单变量或数组元素作为函数参数

数组元素本身属于简单变量,在向形参传递数据时,根据前述规则只需将变量中的“复制一份放到形参变量中去操作,此时在被调用函数中操作的对象(形参)与实参并不在同一内存单元,并且在调用结束后形参所占内存单元被释放,因此调用函数不会影响到实参变量的值。同时被调函数也不会影响到主调函数中其他变量的值。

例:1

#include<stdio.h>

void main()

{int a=1,f(int a);

printf("%d%d",a,f(a));

}

f(int a)

{return(++a);}

2

#include<stdio.h>

void main()

{int a[3]={1,2,3},f(int a);

printf("%d%d",a[0],f(a[0]));

}

f(int a)

{return(++a);}


情况二:指针变量数组名作为函数参数

1.指针变量作函数参数

指针变量作实参在调用时仍然符合前述“值传递”规则,将其“值”赋给形参,相当于复制。此时数据在实参与形参间传递仍是单向的,调用函数不会影响实参的“”(即指针变量中所存地址)。而与简单变量不同的是指针变量复制给形参的“”本身是一个地址,这个地址为形参访问其所指变量创造了可靠条件。我的理解是,实参是一个抽屉的钥匙,在传参时,实参复制了一把钥匙传给形参。而被调函数拿到钥匙副本后,进行的操作可以分为两类:1、对钥匙本身做了一些操作(对指针本身进行操作);2、通过钥匙对抽屉里的内容进行了一些操作(对指针所指的变量进行操作);两种操作都不可能影响实参的值(即钥匙原本),却有可能改变实参所指向变量的值(即抽屉里的内容)。

1

#include<stdio,h>

void main()

{void swap(int*p1,int*p2);

int a,b;

int *pointer1,int*pointer2;

scanf("%d,%d",&a,&b);

pointer1=&a; pointer2=&b;

if(a<b) swap(pointer1,pointer2);

printf("%d,%d",a,b);

}

void swap(int*p1,int*p2)

{int temp;

temp=*p1;

*p1=*p2;

*p2=temp;}

2

#include<stdio,h>

void main()

{void swap(int*p1,int*p2);

int a,b;

int *pointer1,int*pointer2;

scanf("%d,%d",&a,&b);

pointer1=&a; pointer2=&b;

if(a<b)

swap(pointer1,pointer2);

printf("%d,%d",a,b);

}

void swap(int*p1,int*p2)

{int temp;

temp=p1;

p1=p2;

p2=temp;}

2.数组名作函数参数

数组名本身是一个特殊的指针变量,其值是数组的首地址,因此作实参时其传给形参的是内存中某指定单元的地址,调用过程中形参数组与实参数组占用同一段内存单元,因此对形参数组的操作也就是对实参数组的操作,对实参数组形参数组来说数据传递表现为“双向”的,而对实参变量形参变量而言数据的传递仍然是单向的。

#include<stdio,h>

void main()

{int a[3]={1,2,3};

void f(int a[]);

f(a);

for(i=0;i<3;i++)

printf("%d",a[i]);

}

void f(int a[])

{for(i=0;i<3;i++)

a[i]++;

}


情况三:引用作为函数参数:

首先申明引用和指针最大的不同是:应用本身不是变量,不存在自己的变量空间,引用只是一个作为变量别名的标志。

引用必须依托于一个已实际存在的变量,正如一个人的如果连正名都没有,就无所谓小名了。正因为引用只是为了方便为同一个变量所取的小名,所以在任何地方通过引用对变量的操作和通过变量名进行操作的结果是一样的。

综上,当引用作为函数参数时,对形参的操作既是对原变量的操作,可以改变实参的值。效果上虽然和通过指针改变实参一样,但两种机制完全不同,引用并没有另开辟其它空间,直接对“原本”进行了操作,节省了时间和空间。


(拓)结构体数组作函数参数

用结构体数组作函数参数包含两类情况:结构体数组元素作实参和结构体数组名作实参。两类情况仍然服从数据的单向传递原则只不过前者传给形参的是某些变量的值,后者传给形参的是结构体数组的首地址。

1.结构体数组元素作实参

符合结构体变量作实参规则,采取单向“值传递”方式将结构体变量所占的内存单元的内容全部顺序复制给形参(函数调用期间形参也要占用内存单元)。注意当实参的成员中包含数组时形参相应的成员接受到的是一个地址。

2.结构体数组名实参

同整形数组数组名作实参一样传递给形参的是内存中已指定单元的地址,调用过程中形参数组与实参数组占用同一段内存单元,因此对形参数组的操作也就是对实参数组的操作。对数组的操作表现为双向性。

综上所述,对于有参函数调用时,实参变量与形参变量之间的数据都是单向的“值传递”方式。至于调用过程中是否会改变主调函数中变量的值,则只需根据具体算法看被调函数是否会找到主调函数中变量所在内存单元并对其原本进行操作。

分享到:
评论

相关推荐

    C语言中函数调用和参数传递机制的探讨

    结合汇编讲解了c语言汇中函数参数是如何传递,如何调用的

    关于C语言中函数调用和参数传递机制的探讨.txt

    C语言 函数调用 参数传递机制 探讨 txt

    C语言函数调用与参数传递剖析.pdf

    C语言函数调用与参数传递剖析.pdf

    c语言中函数调用的几个实例

    c语言函数调用 在C语言中,函数是一种重要的程序模块,可以将一段可重用的代码块封装起来,以便在程序的其他部分中被调用。函数的使用可以减少代码重复,提高程序的可读性和可维护性。 在C语言中,函数调用是通过...

    C语言函数的定义、声明以及函数的调用方法_c语言函数学习实例_

    1.掌握C语言函数的定义、声明以及函数的调用方法2.了解主调函数和被调函数之间的参数传递方式3.熟练掌握数组作为函数参数的用法

    C语言函数调用与参数传递剖析

    本文档在某知名网站下载,要么浏览量最多,要么最新,保证精品,至少为你节约3RMB。格式为caj或者kdh需要专业阅读器打开。

    关于C语言函数调用汇编时参数大于4个的时候该如何传参-附件资源

    关于C语言函数调用汇编时参数大于4个的时候该如何传参-附件资源

    C语言程序设计:函数.pptx

    当函数调用时,将实参的值传递给形参。 形参必须指定类型,只能是简单变量或数组,不能是常量或表达式 形参与实参类型一致,个数相同顺序相同。 若形参与实参类型不一致,自动按形参类型转换———

    C语言回调函数学习.

    对指针的应用是C语言编程的精髓所在,而回调函数就是C语言里面对函数指针的高级应用...如果你把函数指针(函数的入口地址)传递给另一个函数,当这个函数指针被用来调用它所指向的函数时,我们就说这个函数是回调函数。

    [linux嵌入式方向]C语言回调函数学习

    对指针的应用是C语言编程的精髓所在...如果你把函数指针(函数的入口地址)传递给另一个函数,当这个函数指针被用来调用它所指向的函数时,我们就说这个函数是回调函数。 为什么要使用回调函数呢?我们先看一个小例子:

    C语言函数参数传递的几个问题

    从实例和理论两方面讨论了函数的传值调用和传址调用,揭示了数组名和函数名 作形参时的本质,指出形参数组名和形参函数名与相应的指针变量的一致性.

    C语言函数调用栈(一)

    编译器使用堆栈传递函数参数、保存返回地址、临时保存寄存器原有值(即函数调用的上下文)以备恢复以及存储本地局部变量。不同处理器和编译器的堆栈布局、函数调用方法都可能不同,但堆栈的基本概念是一样的。寄存器是...

    C语言中的参数传递机制详解

    C中的参数传递 本文尝试讨论下C中实参与形参的关系,即参数传递的问题。... printf(函数调用后实参n的值:%d,地址:%#x\n, n, &n); return 0; } void change(int i){ printf(形参i的值:%d,地址:%#x\n,i,&i); i++

    C语言函数调用栈(二)

    创建一个栈帧的最重要步骤是主调函数...对于有多个参数的函数,调用约定需规定主调函数将参数压栈的顺序(从左至右还是从右至左)。某些调用约定允许使用寄存器传参以提高性能。2)栈的维护方式主调函数将参数压栈后调用被

    C语言程序设计标准教程

     函数名(实际参数表) 对无参函数调用时则无实际参数表。 实际参数表中的参数可以是常数,变量或其它构造类型数据及表达式。 各实参之间用逗号分隔。'Next of Page在C语言中,可以用以下几种方式调用函数: 1.函数...

    c语言\第8章 函数.ppt

    c语言\第8章 函数.ppt 函数的定义与调用 函数间的信息传递方式 函数与数组 递归函数与递归调用 变量的存储类型及作用域 内部函数和外部函数

    C程序中用指针变量作函数参数

    在调用函数时,给形参分配存储单元,并将实参对应的值传递给形参,调用结束后,形参单元被释放,实参单元仍保留并维持原值。因此,在执行一个被调用函数是,形参的值如果发生改变,并不会改变主调函数的值。

    c语言函数.doc )

    第6章+函数.doc 1....掌握通过“值传递”调用函数的方法 4.掌握带有指针形参的函数的定义及调用方法。 5.理解变量作用域和存在期的概念,掌握全局变量和局部变量,动态变量和静态变量的定义、说明和使用方法

    C语言中的回调函数

     回调函数是程序中一种常用的函数调用方式。其特点是可以在下层软件模块(宏观上的被调用者)中,调用来自上层的软件模块(宏观上的调用者)中的函数,这和通常的调用顺序是相反的。  程序的调用方式软件模块的...

Global site tag (gtag.js) - Google Analytics