文档章节

一直没有搞懂的C语言参数传递,今天终于明白了

算法与编程之美
 算法与编程之美
发布于 2017/04/08 08:24
字数 885
阅读 32
收藏 0

本讲我们和大家一起来聊一聊C语言中有关参数传递的一些知识。

1. 问题引入

请写出以下程序的打印结果。

#include <stdio.h>

// 将某整数加10

void add_by_10(int a){

a = a + 10;

}

int main(int argc, char *argv[]){

int a = 2;

add_by_10(a);

printf("a= %d\n", a);

}

上面的程序非常的简单,我们定义了一个函数add_by_10,它的功能是实现整数加10,然后在main函数中调用,由于a初始值为2,当调用函数了以后,a的值变成了12。

事实真是如此吗?如果你编译执行了这段程序,你会发现打印的结果是:"a = 2".

为什么会这样呢?这和你想的完全不一样。

2. 问题分析

接下来我们就和大家一起来分析为什么会是这样的结果。

之前的文章我们讲过,所谓变量的定义其实就是从4G的内存条上去拿空间,如你定义了一个int a;其本质含义就是要从你新买的4G内存条上拿走一块4字节大小的空间,如下所示,黄色部分的空间就是属于a的,其他人不能用哈。

一直没有搞懂的C语言参数传递,今天终于明白了

我们再将该问题深入一些,其实系统在分配内存时,是以函数为基本单元,如问题1中定义的程序,我们有两个函数main和add_by_10,所以系统会先分别给这两个函数分配内存,然后这两个函数内部的变量都会在各自函数所属的内存空间去拿内存。

在4G的内存条上有一部分区域是属于main函数的(黄色区域),还有一部分区域是属于add_by_10函数的(橙色区域),如下所示:

一直没有搞懂的C语言参数传递,今天终于明白了

main函数中定义了一个int a;所以这个a会从main区域拿走4字节的空间(黑色区域),并赋值为2。另外add_by_10函数中有一个参数int a所以这个a也会从add_by_10区域拿走4字节空间(灰色区域),如下所示:

一直没有搞懂的C语言参数传递,今天终于明白了

当在main函数中执行add_by_10(a)这行代码时,会将main函数a的值,赋给add_by_10函数的形参a,如下:

一直没有搞懂的C语言参数传递,今天终于明白了

add_by_10函数中,对其所属的a变量执行了加10操作后,a变成了12,如下:

一直没有搞懂的C语言参数传递,今天终于明白了

add_by_10函数调用结束后,将会释放add_by_10的内存空间。

从上面的一步一步分析,大家可以看到,其实main函数中的a一直都是2,并没有发生任何的改变,而改变的只是add_by_10函数中的a值。所以这就是为什么你最终看到的结果是:"a= 2"而不是"a= 12"。

请思考:怎样才能达到"a = 12"这个结果?

3. 总结

本文给大家介绍了C语言中有关参数传递的一些知识点旨在帮助初学者更好的理解参数传递中一些容易犯错的地方。

另外本文部分内容描述不是特别严谨,旨在用最简单的方式帮助初学者更好的理解参数传递,待有一定的基础后,可深入了解函数栈的基本原理及操作系统是如何管理内存的。

欢迎关注微信公众号“算法与编程之美”,及时了解更多信息。

© 著作权归作者所有

算法与编程之美
粉丝 297
博文 96
码字总数 106067
作品 0
成都
程序员
私信 提问
GET与POST传递数据的最大长度能够达到多少

各种web开发语言中,各个页面之间基本都会进行数据的传递,web开发里面比较常用的数据传递方式有get post,一直以来我都只知道get传递的数据量要比post传递的数据量要少,所以传递大数据量还...

微信迷
2014/02/27
1K
0
看到C语言中jmp_buf的定义明白了一件事

一直不明白在调用setjmp(jmpbuf j) 和longjmp(jmpbuf j, int i)传值是怎么传的,今天看了jmp_buf 的定义才明白 typedef struct jmpbuf{ } jmp_buf[1];将jmp_buf定义为一个数组,那么可以将数...

OneThin
2011/07/04
4K
2
PHP中imagecopyresampled参数详解

铂金小猪学PHP 今天做php缩微图程序,用到了imagecopyresampled函数,在网上找了很多说明也没搞懂后面的参数到底是什么意思,试了很多遍终于明白。 bool imagecopyresampled ( resource $ds...

铂金小猪
2012/03/15
28.3K
1
关于windows 下sublime编译运行C中文不显示问题

首先,我们要知道,windows命令行默认不是utf8的。而我的sublimem默认是utf8我又不想变成gbk. 然后我从网站摘抄到这样一段话可以解决这个问题。 一直苦恼于如何在Windows终端中显示UTF-8字符...

merph
2016/12/12
93
0
谈 “中国文化根底在道教”

鲁迅曾说中国文化根底在道教,一直没有很明白这个意思。 读顾颉刚的《春秋时代的孔子与汉代的孔子》一文,终于搞明白了,里面讲到: “孔教是一个没有完工的宗教,和汉朝的经学很有关系,…....

樵者
2015/12/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

PostgreSQL 11.3 locking

rudi
今天
5
0
Mybatis Plus sql注入器

一、继承AbstractMethod /** * @author beth * @data 2019-10-23 20:39 */public class DeleteAllMethod extends AbstractMethod { @Override public MappedStatement injectMap......

一个yuanbeth
今天
13
1
一次写shell脚本的经历记录——特殊字符惹的祸

本文首发于微信公众号“我的小碗汤”,扫码文末二维码即可关注,欢迎一起交流! redis在容器化的过程中,涉及到纵向扩pod实例cpu、内存以及redis实例的maxmemory值,statefulset管理的pod需要...

码农实战
今天
4
0
为什么阿里巴巴Java开发手册中不建议在循环体中使用+进行字符串拼接?

之前在阅读《阿里巴巴Java开发手册》时,发现有一条是关于循环体中字符串拼接的建议,具体内容如下: 那么我们首先来用例子来看看在循环体中用 + 或者用 StringBuilder 进行字符串拼接的效率...

武培轩
今天
9
0
队列-链式(c/c++实现)

队列是在线性表功能稍作修改形成的,在生活中排队是不能插队的吧,先排队先得到对待,慢来得排在最后面,这样来就形成了”先进先出“的队列。作用就是通过伟大的程序员来实现算法解决现实生活...

白客C
今天
87
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部