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语言有参函数调用时参数间数据传递问题相关推荐

  1. C语言有参函数调用时参数值传递问题

    http://blog.csdn.net/hehuimin6/article/details/38800459

  2. 页面url带参数_微信小程序云开发教程微信小程序的JS高级页面间数据传递

    同学们大家好,我是小伊同学,上一节课我们讲解了全局数据的读写方法,那么在页面间同样需要数据交互,今天我们就来学习这部分内容. 在微信小程序中,我们常常需要将数据在页面之间进行传递,比如用户的身份信息, ...

  3. python调用接口获取数据_python:接口间数据传递与调用方法

    如下所示: import requests import unittest import json from pubulic_way.get_token import getSession class ...

  4. 三、Vue(组件、组件间数据传递、slot内容分发、vue-router路由、单文件组件、vue-cli脚手架 )

    一. 组件component 1. 什么是组件?     组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码     组件是自定义元素(对象) ...

  5. ASP.NET页面间数据传递的方法

    本文我们将讨论的是ASP.NET页面间数据传递的几种方法,对此希望能帮助大家正确的理解ASP.NET页面间数据传递的用处以及便利性. 0.引言 Web页面是无状态的, 服务器对每一次请求都认为来自不同 ...

  6. ASP.NET页面间数据传递的几种方法

    1.ASP.NET页面间数据传递的各种方法和分析 1.1 使用Querystring 方法 QueryString 也叫查询字符串, 这种方法将要传递的数据附加在网页地址(URL)后面进行传递.如页面 ...

  7. asp.net页面间数据传递(总结篇)

    asp.net页面间数据传递(总结篇) 1. Get(即使用QueryString显式传递)      方式:在url后面跟参数.      特点:简单.方便.      缺点:字符串长度最长为255 ...

  8. Matlab GUI与GUI间数据传递实现

    Matlab GUI与GUI间数据传递实现 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.ne ...

  9. 进程间数据传递:Queue,Pipe 进程间数据共享:Manager

    进程间数据传递:Queue,Pipe 进程间数据共享:Manager 1.使用multiprocessing模块的Queue实现数据传递 ''' 进程间通讯:Queue,用法跟线程里的Queue一样, ...

最新文章

  1. 只有大规模算力才能救AI?强化学习之父 vs 牛津教授掀起隔空论战
  2. iOS经常使用加密方式(MD5,AES,BASE64)与网络数据安全
  3. linux挂载wondiws目录,linux cifs自动挂载windows硬盘或文件夹
  4. 阿里云栖开发者沙龙PHP技术专场-聊聊服务稳定性保障这些事
  5. ES5_03_Object扩展
  6. android: listview与sqlite数据操作实例
  7. gpg加密命令 linux_Ubuntu下加密命令GPG和KEY
  8. python生成html表格_如何使用Python生成html目录列表
  9. thinkphp5 两个控制器传参数_PID参数整定:看大神是如何整定参数
  10. UEFI开发与调试---运行阶段介绍
  11. 嵌入于MOEA/D的一个自适应约束处理方法
  12. 算法之路-圆柱体面积
  13. Camera.cullingMask 常用操作
  14. 线稿图视频制作补充(调整视频亮度、对比度;删除无用文件)
  15. 数据抓包(网络爬虫)-正方教务管理系统登录
  16. 51单片机c语言学习感想,学习51单片机心得体会
  17. cesium教程-3(显示高度,海拔,经度,纬度)
  18. WPS Office 2019 v11.8.2专业增强版+教程
  19. windows 10 移动热点无互联网连接
  20. 开启Mac的壁纸自动更换功能

热门文章

  1. 数据离散化 - 等宽等频聚类离散 - Python代码
  2. Android自定义Lint实践
  3. 论文浅尝 | 使用循环神经网络的联合事件抽取
  4. 领域应用 | 从本体论开始说起——运营商关系图谱的构建及应用
  5. 决策树(西瓜书学习)
  6. 专家:人工智能开始对现实世界产生重大影响​​
  7. js构造函数内存在的闭包
  8. python201811210作业4
  9. 不会Python开发的运维终将被淘汰?
  10. 20165212 预备作业3 Linux安装及学习