下面从传数据和传地址的区别分开讲述;我们先了解一下一个函数中的什么数据都存放在什么地方的,什么时候它需要传地址,什么时候只需要传递数据,并且什么三时候会被释放掉:
测试代码:
/*
测试:函数传参传递数据的情况
*/
#include
void func(int a,int b)
{
a = 20;
b = 30;
//打印一下输出结果
printf("func_a:%d\n",a);
printf("func_a地址:%p",&a);//打印一下a的地址
printf("func_b:%d\n",b);
printf("func_b地址:%p",&b);//打印一下b的地址
printf("func_a+b:%d\n",a+b);
return ;
}
int main()
{
int a = 10;
int b = 20;
//调用func这个函数,并传递两个参数的数据过去
func(a,b);
printf("main_a:%d\n",a);
printf("main_a地址:%p",&a);//打印一下a的地址
printf("main_b:%d\n",b);
printf("main_b地址:%p",&b);//打印一下b的地址
printf("main_a+b:%d\n",a+b);
return 0;
}
(1)void func(int a,int b)里的int a和int b只是用于定义然后接收传进来的参数(形参),因此main函数中的a和b的地址与func函数中a和b的地址不一致
(2) 当代码执行到main函数里面的func(a,b);时其实只是相当于main函数的a和b赋值给func函数的a和b中
(3)main函数与func函数中定义的a和b其实是没有关系的,只是变量名相同,只是为了传参时方便易辨别
(4)因为main函数的a和b没有改变,改变的只是func里面的a和b,因此mian函数里面的运行a依旧是10,b依旧是20;并没有任何变化
(5)func中的a和b因为是只是一个函数内的普通变量,并非static修饰的变量也不是全局变量,因此是存放在栈里面的数据,存放在栈的数据的特点是:在函数执行结束后会被释放
测试代码:
/*
测试:函数传参传递地址的情况
*/
#include
//如果形参变量加了const修饰后只可读,不可修改它地址所在的数据,编译时会报错
//void func(const int *a,const int *b)
void func(int *a,int *b)
{
*a = 20;
*b = 30;
//打印一下
printf("func_a:%d\n",*a);
printf("func_a地址为:%p\n",a);//打印a的地址
printf("func_b:%d\n",*b);
printf("func_b地址为:%p\n",b);//打印b的地址
printf("func_a+b:%d\n",*a+*b);
return ;
}
int main()
{
int a = 10;
int b = 20;
//调用func这个函数,并把变量的地址传递过去
func(&a,&b);
printf("main_a:%d\n",a);
printf("main_a地址为:%p\n",&a);//打印a的地址
printf("main_b:%d\n",b);
printf("main_b地址为:%p\n",&b);//打印b的地址
printf("main_a+b:%d\n",a+b);
return 0;
}
运行结果:
(1)当这个函数把数据的地址传递过去的时候函数的变量需要使用指针接收,因为接收的是一个地址,mian’与func之间的参数传递可看作:int *a = &a; int *b = &b;
(2)func接收的a和b变量的地址,因此当在func函数中修改了a和b变量地址所在的数据时,其实是修改mian函数中a和b的值;
(3)例如我们可以假设main函数中a和b的地址分别为0x1000和0x1004(一个int类型数据占4个字节),当我们func(&a,&b);其实只是传递这两个地址过去而已,然后func函数中只是把0x1000和0x1004这两个内存地址中的数据修改为20和30
(4)因为main函数传递给func函数的是地址,因此func函数在打印时需要解引用取它地址里面的数据
(1)函数传参时传递的是数据的话,其实只是相当于这个函数的值赋值到另一个函数
(2)函数传参时传递的是地址的话,这个时候是把变量的地址传递过去,并不是数据的地址传递过去,然后接收的函数需要对变量所在的地址修改里面值的话是需要解引用该地址后才能修改和读取里面的数据
(3)函数传参传地址时,在其他函数通过修改该地址的数据后,它这个地址的值就已经改变了,并不会因为函数执行完销毁,因为是对地址操作,销毁的只是一个存放有变量地址的指针
================================================