初学者在学习C语言时候一个极容易迷惑的地方就在函数的“值传递”和“地址传递”了,出现这个迷惑的原因有些教材没有把内存图画出来,只是简单的举了几个例子,结果初学者按照例子写写代码倒是能运行出来,但始终没明白到底是怎么回事,下面我通过例子和画图来相信说明里面的细节问题。在开始之前有一个前提,你一定要粗略的看过函数这一章节,不管你是从什么教材上看过的,总之我下面的内容默认你已经对函数了解一些了。
1. 值传递。
比如:自己自定义一个函数如下:
void swap(int a, int b)
{
int temp = 0;
temp = a;
a = b;
b = temp;
}
假设在main函数中的调用该函数,如下:
int main(void)
{
int x = 10;
int y = 20;
swap(x, y);
printf("x = %d\n", x);
printf("y = %d\n", y);
return 0;
}
如图所示,实际参数x和y在传入函数之前还复制了里面的内容,并把内容交给一个临时的内存,然后在内部执行交换操作后,只是临时内存a和b做了交换,可见值传递只是传递了实参中的值,在函数内部也无法修改外部的实际参数。
2.地址传递
我们同样用交换函数来说明问题。
void swap(int *a, int *b)
{
int temp = 0;
temp = *a;
*a = *b;
*b = temp;
}
假设在main函数中的调用该函数,如下:
int main(void)
{
int x = 10;
int y = 20;
swap(&x, &y);
printf("x = %d\n", x);
printf("y = %d\n", y);
return 0;
}
如上图所示,在传递参数的时候,把x和y的地址传给了函数swap,其实地址值理论上也复制了一次,传给函数swap的是地址的一个副本,不过这并不影响*a,因为temp = *a就是将a地址中的数即0x0030里面放着的10赋值给temp变量,于是temp里面存入了10,*a = *b就是将b地址中存放的20放入a地址中,这是原理的x值发生了变化,由原来的10变成了20,最后一句*b = temp是将temp中的值10放到b存放的地址所在内存中,即y中,于是y就变成了10。


如上图所示,在传递参数的时候,把x和y的地址传给了函数swap,其实地址值理论上也复制了一次,传给函数swap的是地址的一个副本,不过这并不影响*a,因为temp = *a就是将a地址中的数即0x0030里面放着的10赋值给temp变量,于是temp里面存入了10,*a = *b就是将b地址中存放的20放入a地址中,这是原理的x值发生了变化,由原来的10变成了20,最后一句*b = temp是将temp中的值10放到b存放的地址所在内存中,即y中,于是y就变成了10。