函数参数
实参和形参
实际参数是具体的值,该值要被赋给作为形式参数的变量。
形参无法改变实参
因为被调函数使用的值是从主调函数中拷贝而来的,所以无论被调函数对拷贝数据进行什么操作,都不会影响主调函数中的原始数据。
场景 1 —— 一级指针作为参数(交换值)
#include <stdio.h>
#include <stdlib.h>
void swqp(int *x, int *y)
{
int tmp;
tmp = *x;
*x = *y;
*y = tmp;
}
int main(int argc, char *argv[])
{
int a = 5;
int b = 6;
swqp(&a, &b);
printf("a = %d\n", a);
printf("b = %d\n", b);
return EXIT_SUCCESS;
}
liyongjun@Box20:~/project/c/study$ make t=point/point_1 run
./point/point_1.out
a = 6
b = 5
场景 2 —— 一级指针作为参数(分配空间)
#include <stdio.h>
#include <stdlib.h>
void get_memory(char *x)
{
x = (char *)malloc(1);
printf("x = %p\n", x);
}
int main(int argc, char *argv[])
{
char *p = NULL;
get_memory(p);
printf("p = %s\n", p);
return EXIT_SUCCESS;
}
liyongjun@Box20:~/project/c/study$ make t=point/point_2 run
./point/point_2.out
x = 0x55d53d5942a0
p = (null)
同样是一级指针,为什么场景 1 正常,而场景 2 出错。
分析:
首先回归本原,主调函数都是把实参这个值拷贝一份赋给被调函数的形参变量。所以形参怎么改变都不会改变实参的值。
先说场景 2,main() 函数把 p 的值拷贝一份赋给 get_memory() 的形参 x,x 和 p 并没有任何关系,仅仅是 main() 函数把 p 的值借用一下,作为一个实参给 x 赋下值。因此 x 怎么变化也不可能影响到外部的 p。再说白一点,main() 函数就是把 NULL 这个值赋给了变量 x,你说和 p 有个屁的关系呀。
另一点:p 虽然是指针类型,但是也难逃自身就是一个变量的命运。
再说场景 1,main() 函数把 a 的地址拷贝一份赋给 swap() 的形参 x,x 和 a 的地址并没有任何关系,仅仅是 main() 函数把 a 的地址借用一下,作为一个实参给 x 赋下值。但是这里和场景 2 有点不一样了,&a 和 x 手里都攥有一个相同的值,而这个值就是变量 a 的地址,那么使用这个地址就能改变 a 的值,所以 swap() 能够改变 a 的值。
总结一下就是,传递一级指针,想要改变指针本身的值是不可以的,改变指针指向的变量的值是可行的。
小结
实参是值,形参是变量。
参考
《C Primer Plus 第6版 - 9.1.6》