C中实参与形参的“值传递”只能“单向传送”(透彻的理解)
来源:互联网 发布:网络环境下的侵权案例 编辑:程序博客网 时间:2024/05/16 13:50
今天又彻底地把这部分知识回顾了一下,好好地理解了一番。还是记下来比较靠谱,加深印象,省的以后再忘。
主调函数(比如main函数)中,调用函数(比如numpp函数)时,如果swap的参数在函数中改变了,那么此参数必须是指针类型的。还是例子好说话。
目的:实现main中的一个整形变量加1。(当然实际情况,如果简单的功能,不会采取调用函数方式,仅作说明)
错误的例子:
void numpp(int x){x++;}main(){int a=2;numpp(a);printf("a=%d\n",a);}上述代码运行结果为:a=2,并没有加1。
正确的写法为:
void numpp(int *x){(*x)++;}main(){int a=2;numpp(&a);printf("a=%d\n",a);}这次的运行结果是正确的:a=3。
这是为什么呢?
错误的例子分析:main中,a=2,调用numpp函数时,实参a的值传如x,然后x+1,于是x=3,函数调用结束后,x被释放掉,而a的值依旧没有改变,还是2,形参x的值并不会再传给a,只能实参向形参单向传送。
正确的例子分析:main中,a=2,&a是a的地址,即指针,调用numpp函数时,a的指针传送给指针变量x,那么x就指向了变量a,(*x)++,也就是x指向的变量加1,也就是a+1,变成了3,函数调用结束后,x被释放掉,但a的变化被保留了下来,所以是加1后的值3。
总结1:“单向传送”的“值传递”方式,就是形参值的改变不能改变实参的值。不可能通过执行调用函数改变实参变量的值,但是可以改变实参指针变量所指向的变量的值。
经验:为了使函数中改变了的变量值能被主调函数所用,不能把要改变值的变量作为函数参数,而应该用指针变量作为函数参数。在函数执行过程中,使指针变量所指向的变量值发生变化,函数调用结束后,这些变量值的变化依然保留下来。
其实还有一个经典的例子,就是swap函数,交换两个变量的值。
两个经典的错误:
1、
void swap(int x,int y){int t;t=x;x=y;y=t;}main(){int a,b;int *p1=&a,*p2=&b;swap(p1,p2);printf("a=%d,b=%d\n",a,b);}
2、
void swap(int *x,int *y){int *tp;tp=x;x=y;y=tp;}main(){int a,b;int *p1=&a,*p2=&b;swap(p1,p2);printf("a=%d,b=%d\n",*p1,*p2);}
例1中的错误同最上面的错误一样,必须用指针变量做参数才行。但例2中,就是用指针变量做的参数,但还是不对,下面分析一下:main中,p1指向a,p2指向b,调用函数swap时,p1的值传送给x,p2的值传送给y,也就是说x指向a,y指向b,在函数中,x和y作了交换,于是x指向b,y指向a。但是,形参x和y的值并不会回头再传给实参p1和p2,所以p1依旧指向a,p2依旧指向b。a和b的值也依旧没有改变。
总结2:其实本质跟总结1一样。“单向传送”的“值传递”方式,就是形参值的改变不能改变实参的值。不可能通过执行调用函数改变实参指针变量的值,但是可以改变实参指针变量所指向的变量的值。
最后总结:函数执行过程中,不能通过改变形参变量的值,也不能通过改变形参指针变量的值,来改变实参变量或实参指针变量,而是通过改变形参指针变量指向的变量值,来改变实参变量的值。
如果这句话看明白了,那就真正理解了。
还有一句话可以体会一下:函数的调用,只可以得到一个返回值(即函数值),而使用指针变量做参数,可以得到多个变化了的值。
- C中实参与形参的“值传递”只能“单向传送”(透彻的理解)
- 形参和实参值单向的值传递
- C语言-实参到函数形参传递的理解
- 实参与形参的传递关系
- Java值传递和引用传递及形参实参的分析(实例对比c++)
- 关于C++中实参形参的传递问题
- 关于函数实参和形参的地址传送
- 通过栈帧来解释实参到形参的“似的单向传递”
- 黑马程序员------C语言中对形参和实参的理解
- 形参与实参之间的值传递
- 参数传递---形参改变实参指针变量的值
- 《c++primer》中接受命令行,并输出传递给main的实参的值
- 实参变量与形参变量之间的数据传递是值传递
- C函数的实参与形参的输出区别
- 通过函数分配内存,理解实参,形参之间的传递.
- C语言基础 实参与形参的类型一致
- 关于c的形参实参与运行时结构
- 形参和实参的理解练习
- android UI适配
- Java中for的几种用法
- Spark SQL Catalyst源码分析之Optimizer
- HDU 2021 发工资咯:)
- UML 序列图详解
- C中实参与形参的“值传递”只能“单向传送”(透彻的理解)
- JAVA实现简单的堆栈结构
- 【Android性能优化】Hierarchy viewer is shows n/a
- Android中常用的bitmap处理方法
- HDU 2022 海选女主角
- clojure从零开始(一)
- 不得已才能考虑缩小尺寸
- StringUtils
- Volley(一)