关于C语言中函数参数传递问题的探讨

来源 :电脑知识与技术 | 被引量 : 0次 | 上传用户:gorlsand
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  摘要:在C语言中,函数是实现程序模块化设计思想的手段。函数在调用过程中常常存在着实参和形参之间的数据传递。文章阐述了调用函数的过程中实参和形参之间数据传递的实质和属性,即值传递和单向性。
  关键词:函数;形参;实参;数据传递
  中图分类号:TP312文献标识码:A 文章编号:1009-3044(2007)17-31457-01
  Analysis of Data Transferring from Actual Argument to Formal Argument in C Language Function Calling
  LU Xiang-ning, LI Xiao-mei
  (Hainan Software Professional Institute, Qionghai 571400,China)
  Abstract: C's design philosophy is to use functions as building blocks. When a function is called, value of the actual argument is assigned to the variable known as the formal argument. This paper presents that the essence of data transferring from actual argument to formal parameter is value delivery and one-way.
  Key words: functions; formal parameters; actual arguments; data transferring
  
  1 引言
  
  在C语言教学过程中,我发现有很多初学者对函数调用过程中实参和形参之间的数据传递问题理解不够透彻,尤其是指针做函数参数时,常常有许多误解。有这样一个程序:
  #include
  main()
  {
  void swap(int *p1,int *p2);
  int a,b;
  int *point1,*point2;
  clrscr();
  scanf("%d,%d",&a,&b);
  point1=&a;point2=&b;
  if(a  printf("a=%d,b=%d\n ",a,b);
  printf("max=%d,min=%d\n ",*point1,*point2);
  }
  void swap(int *p1,int *p2)
  {
  int *temp;
  temp=p1;
  p1=p2;
  p2=temp;
  }
  编程者的目的很明显,即编写用户自定义函数void swap(int *p1,int *p2),并以整型指针作为参数,在main()函数中调用这一函数来实现两个整型数据a和b的值的互换。但这个函数能否实现两个数值的交换呢?下面我们对其进行分析。
  
  2 函数调用过程分析
  
  在前面这一程序的main()函数中,整型指针变量point1、point2分别指向整型变量a、b,即point1 和point2的值分别为变量a和b的地址。在调用函数swap()时实参(point1,point2)将各自的“值”传递给形参(p1,p2) 。如图1所示(图中虚线箭头表示数据的传递方向,实线箭头表示指向),由于point1 和point2的值分别为变量a和b的地址,所以p1和p2也分别得到变量a和b的地址,即p1和p2也分别指向变量a和b。
  图1 实参向形参进行“值”的传递
  实参向形参进行“值”的传递之后,执行swap()函数的函数体部分,当执行语句“temp=p1;” 后,将p1的值(主函数中整形变量a的地址)赋给指针变量temp,这时temp也指向了变量a,如图2所示。
  图2 执行赋值语句temp=p1;后
  执行赋值语句“p1=p2;”,将p2的值(主函数中整形变量b的地址)赋给p1,这时p1不再指向变量a,而指向了变量b,如图3所示,temp和p2的指向不变。
  图3 执行赋值语句p1=p2,后
  最后执行赋值语句“p2=temp;”,将temp的值(主函数中整形变量a的地址)赋给p2,这时p2的值发生改变,不再指向变量b,而指向变量a。如图4所示。
  由上述讨论可以看出,编程者调用swap()函数,仅仅改变了形参变量p1和p2的值,即改变了p1和p2的指向,而这一过程中实参变量point1 和point2并没有指向。swap()函数调用结束后,形参所占内存单元被释放,形参变量p1和p2以及局部指针变量temp消亡。因此,该程序调用swap()函数的执行结果就是改变了通过中间指针变量temp交换了两个形参变量p1和p2的指向,对main()函数没有起到任何作用。
  
  3 函数的改正及问题分析
  
  前例中,调用swap()函数虽然不能改变实参指针变量point1 和point2的值(即它们的指向),但是我们可以改变point1 和point2所指向的内存单元当中的值,即改变整型变量a、b的值。对swap()函数做如下修改:
  void swap1(int *p1,int *p2)
  { int temp;
  temp=*p1;
  *p1=*p2;
  *p2=tem}
  分析修改后的函数swap1()可知,在函数swap1()调用执行过程中,不仅没能改变实参指针变量point1 和point2的指向,形参指针变量p1和p2的指向也一直没有改变,只是交换了是p1和p2指向的内存单元中的值,即使a、b值互换。
  这样以来,就实现了函数调用的功能,达到了编程者的目的。
  然而,也有很多人将swap()函数修改为如下形式:
  void swap2(int *p1,int *p2)
  { int * temp;
  *temp=*p1;
  *p1=*p2;
  *p2=*tem}
  函数swap2()中,编程者以整型指针变量temp为中间变量,交换p1和p2所指向的内存单元中的值,是否能达到这个目的呢?
  启动TUBOR C编译环境中,如前例在主函数中对swap2()函数进行调用,编译时 “*temp=*p1;” 语句出现警告,忽略这个警告,运行程序,并输入5,9按回车键,运行结果如图5。
  显然,编程者的目的没有达到,执行swap2()函数的过程中,指针变量temp和p1指向了同一个内存单元,并将p2所指向的内存单元中的值赋给p1所指向的内存单元,即将main()函数中变量b的值赋给变量a,因而出现了图示结果。
  函数swap2()中问题出现在语句“*temp=*p1;”,对指针变量temp的这种使用方式存在很大的冒险性。由于指针变量temp并没有确定的地址值,所以temp的指向是不可预测的,对*temp赋值可能会造成重要数据的丢失,应避免指针变量的这种使用方式。
  
  4 结论
  
  通过这个例子,本文浅析了函数调用过程中实参与形参之间数据传递的实质,即“值传递”,就好像是实参把自身的数值拷贝了一份给形参,这种“值传递”是单向的,即由实参传递给形参,形参无法改变实参的值。笔者认为这种提法不仅有失准确性,还给初学者造成了概念上的混淆,误认为传递的是实参变量的地址。初学者在学习C语言过程中,往往“谈指针色变”,理解指针做函数参数的情况更是难于上青天,本文结合实例,阐述了函数调用过程中实参对形参的“单向值传递”性,希望对广大初学者有所帮助。
  
  参考文献:
  [1]谭浩强.C程序设计[M] .北京:清华大学出版社,2000.186-189.
  [2]陈家骏.程序设计教程用C++语言编程[M]. 北京:机械工业出版社,2004.155-160.
  [3]Herbert Schildt,著.戴健鹏,译.C语言大全(第2版)[M]. 北京:电子工业出版社,1994.120-125.
  注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。
其他文献
摘要:近年来分形理论和它的构造方法受到极大关注。Julia集是使用非线性复映射f(z)=zm+c为迭代函数生成的一类著名分形,而逃逸时间算法是生成Julia集最常用的算法。本文在给出逃逸时间算法的算法步骤之后,针对迭代函数fm.c(z)=zm+c中参数m,c变化的不同情况,给出了Julia集的实验图例,并分析了二次表达式的常规Julia集(m=2)和高阶的广义Julia集(m>2)的一些特点。  
期刊
摘要:利用当前通用的计算机编程技术,以高级编程语言VB为制作工具,以Origin7.0为作图工具,绘制了铸造Ti-6Al-4V钛合金疲劳裂纹扩展曲线。采用该编程技术,实现了参数的随机输入和曲线的动态形成,真实地制作了不同应力比下的疲劳裂纹扩展速率(da/dn)与裂纹尖端应力强度因子(ΔK)的关系曲线。同时该方法极大地提高了数据处理的效率及准确性。  关键词:VB;Ti-6Al-4V合金;疲劳裂纹扩
期刊
摘要:数字水印是数字作品版权保护的重要技术手段,不可察觉性和鲁棒性是图象水印中基本要求,但它们却是一对互相制约的因素。该算法提出了一种新的数字水印嵌入和提取方法,以一幅图象作为水印,信息量大,优于通常把文本,字符作为水印的方法;分块随机嵌入提高了水印嵌入的顽健性;根据图象局部特征确定水印的嵌入强度,使水印的嵌入强度随图象局部特征变化而变化。针对典型攻击的实验结果表明该算法具有很好的鲁棒性。  关键
期刊
摘要:本文主要阐述如何使用虚拟机软件VMware workstation来构建网络环境,实现网络监视器的实验教学。  关键词:网路监视器;教学实验;帧  中图分类号:TP311文献标识码:A 文章编号:1009-3044(2007)17-31469-01  Using Virtual Ware VMware Workstation to Achieve Experimentation Teachi
期刊
摘要:该文通过介绍PowerPoint视频控件的使用方法,总结了常见视频媒体在PowerPoint中的运用技巧,对读者提高该软件的使用技能有着积极的意义。  关键词:PowerPoint;控件;视频媒体  中图分类号:G434 文献标识码:B文章编号:1009-3044(2007)17-31441-02  How to Employ "Video Control" in PowerPoint So
期刊
摘要:首先阐述了在实践教学中采用Proteus软件仿真的优势,然后对Proteus软件进行介绍,最后举例说明。  关键词:软件仿真的优势;Proteus软件;实例  中图分类号:TP319文献标识码:A文章编号:1009-3044(2007)17-31477-02  The Application of Proteus in Embedded System Teaching  REN Qin, C
期刊
摘要:本论文主要比较了两种多用户上行链路同步估计算法—时域同步与频域同步的性能;最后提出一种新的频率补偿算法使剩余频率快速降到±0.25子载波间距左右,使得频偏估计更具鲁棒性,并说明了算法仿真的有效性。  关键词:多用户OFDM;时域;频域  中图分类号:TN919文献标识码:A文章编号:1009-3044(2007)17-31386-04  Simple Analysis on Multiuse
期刊
摘要:压力测试是Web应用程序测试必不可少的一项工作。现以一个用ASP.NET开发的信息管理系统为例,详细论述如何使用ACT对Web应用程序进行压力测试。  关键词:Web应用程序;压力测试;ACT  中图分类号:TP306文献标识码:A文章编号:1009-3044(2007)17-31405-02  Briefing on Stress Testing of Web Application Pr
期刊
摘要:FLASH设计是目前设计业界界中使用比较广泛的一种形式,本文将着重介绍FLASH设计的现状,并对其发展前景进行详细的分析。  关键词:FLASH;动画;前景  中图分类号:TP311文献标识码:A文章编号:1009-3044(2007)17-31475-02  FLASH Design of the Status and Outlook  LI Qiao-jun,TAO Lin  (Hena
期刊
摘要:随着高等教育改革的进一步深化,许多课程的理论教学学时都不同程度地压缩了。如何在有限的学时内让学生掌握所学知识,是每个教师所面临的新问题。论文主要介绍了在数字电子技术课程的课堂教学中,引入MAX+plusⅡ软件,利用其方便、强大的仿真功能,帮助学生理解课程中的难点和重点,从而提高课堂教学的效率。  关键词:MAX+plusⅡ;数字电子技术;课堂教学  中图分类号:TP311文献标识码:A 文章
期刊