***1.***被调用的函数的形参只有函数被调用的时候才会临时分配存储单元,一旦调用结束占用的内存会被释放。换句话说,就是函数体内部形参的地址和外部实参的地址完全是两个地址
**2.**当main函数调用函数时,把实参copy给了形参,此时形参临时分配存储空间用于存储拷贝过来的值
**3.**C语言中实参变量和形参变量之间的数据传递是单向的“值传递”方式,即只能由实参传递至形参单向
1.1值传递-传递值
#include<stdio.h>
void swap(int x,int y)
{
int s; //定义一个变量
s = x; //这些传递都切实有效的
x = y;
y = s;
printf("函数体中形参x=%d,y=%d,地址:&x=%d,&y=%d\n",x,y,&x,&y); //函数体内输出的值为形参存储单元里的“被交换过的值”
}
int main()
{
int x =1, y = 2; //x,y分别被赋值了1、2成为实参
void swap(int x,int y); //声明函数
printf("交换前实参:x=%d,y=%d,地址:&x=%d,&y=%d\n",x,y,&x,&y);
swap(x,y); //调用函数,实参将值传给形参,形参开始临时分配存储单元
printf("交换后实参:x=%d,y=%d,地址:&x=%d,&y=%d\n",x,y,&x,&y); //由于函数被调用后即会内存释放,故这里的x,y应该为实参,按照上面所说函数形参与实参存储单元不同故输出“顺序没有改变的值”
//最后一句语句意味着再讲形参中的值传回实参来输出,自然是不行的
}在这里插入代码片
以下是实参与形参不一样的例子,直观不易混淆,可参考
void swap(int n,int m)
{
int s;
s = n;
n = m;
m = s;
printf("函数体中形参n=%d,m=%d,地址:&n=%d,&m=%d\n",n,m,&n,&m);
}
int main()
{
int x =1, y = 2;
void swap(int n,int m);
printf("交换前实参:x=%d,y=%d,地址:&x=%d,&y=%d\n",x,y,&x,&y);
swap(x,y);
printf("交换后实参:x=%d,y=%d,地址:&x=%d,&y=%d\n",x,y,&x,&y);
}在这里插入代码片
1.2.值传递-传地址
#include<stdio.h>
void swap(int *a,int *b)
{
int *s=NULL;
s = a;
a = b;
b = s;
printf("函数体中形参*a=%d,*b=%d,a=%d,b=%d,地址:a=%d,b=%d\n",*a,*b,a,b,&a,&b); //该条语句足以说明形参的是由实参拷贝的,a、b表示的是&x、&y,&a、&b表示的是形参a,b的地址
}
int main()
{
int x =1, y = 2;
void swap(int *a,int *b);
printf("交换前实参:x=%d,y=%d,地址:&x=%d,&y=%d\n",x,y,&x,&y);
swap(&x,&y);
printf("交换后实参:x=%d,y=%d,地址:&x=%d,&y=%d\n",x,y,&x,&y); //与传递值同理只能单向,且实参不受形参改变的影响
}
2.地址传递
#include<stdio.h>
void swap(int *a,int *b)
{
int s;
s = *a; //取出地址a指向的值赋给s
*a = *b; //取出地址b指向的值赋给地址a指向的值
*b = s; //取s的值赋给地址b指向的值
printf("函数体中形参*a=%d,*b=%d,a=%d,b=%d,地址:a=%d,b=%d\n",*a,*b,a,b,&a,&b); //由于实参和形参都指向所以形参和实参改变是一致的
}
int main()
{
int x =1, y = 2;
void swap(int *a,int *b);
printf("交换前实参:x=%d,y=%d,地址:&x=%d,&y=%d\n",x,y,&x,&y);
swap(&x,&y); //使形参a、b分别指向1、2,实参为&a、&b
printf("交换后实参:x=%d,y=%d,地址:&x=%d,&y=%d\n",x,y,&x,&y);
}*/
//注意:int *a=&x a有自己独立的内存地址,存储的内容是x的地址,*a是x的值
3.引用传递
#include<stdio.h>
void swap(int &a,int &b) //内存不会给别名分配地址,直接引用它所引用的变量
{
int s;
s = a;
a = b;
b = s;
printf("函数体中形参为&a,&b\na=%d,b=%d,地址:a=%d,b=%d\n",a,b,&a,&b); //&a,&b的地址与下面&x,&y相同,即相当于a、b就等于x、y即实参和形参一致,形参变换实参受其影响也变换
}
int main()
{
int x =1, y = 2;
void swap(int &a,int &b);
printf("交换前实参:x=%d,y=%d,地址:&x=%d,&y=%d\n",x,y,&x,&y);
swap(x,y);
printf("交换后实参:x=%d,y=%d,地址:&x=%d,&y=%d\n",x,y,&x,&y);
}*/
//注意:int &a=x; 用于引用传递,可以认为a为x的别名