实参和形参

C语言-实参和形参

实际参数是具体的值,该值要被赋给作为形式参数的变量。

形参无法改变实参

因为被调函数使用的值是从主调函数中拷贝而来的,所以无论被调函数对拷贝数据进行什么操作,都不会影响主调函数中的原始数据。

场景 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》