看下面的额程序:
```c
#include<stdio.h>
struct gas mpg1(struct gas che);
void mpg2(struct gas *aut);
struct gas
{
float distance;
float gals;
float mpg;
};
int main(void)
{
struct gas car={
100.0,
10.0,
10.0
};
printf("When the car goes %.3f KM and used %.3f oil, the mpg is %.3f .\n",car.distance,car.gals,car.mpg);
printf("***************\n");
mpg1(car);
printf("这里的数值没有发生变化:\n");
printf("When the car goes %.3f KM and used %.3f oil, the mpg is %.3f .\n",car.distance,car.gals,car.mpg);
car=mpg1(car);
printf("引用之后发生了变化:\n");
printf("When the car goes %.3f KM and used %.3f oil, the mpg is %.3f .\n",car.distance,car.gals,car.mpg);
printf("***************\n");
mpg2(&car);
printf("When the car goes %.3f KM and used %.3f oil, the mpg is %.3f .\n",car.distance,car.gals,car.mpg);
return 0;
}
struct gas mpg1(struct gas che)
{
che.distance=134;
che.gals=12;
che.mpg=11.17;
return che;
}
void mpg2(struct gas *aut)
{
aut->distance=98.8;
aut->gals=11.1;
aut->mpg=8.9;
}
运行结果:
问题: 为什么指针直接改变了 实参,而 直接用结构体 却不能改变 实参呢?
值传递与地址传递的问题。
mpg2(&car); 是将car的地址传到函数mpg1()中,函数中进行修改,外部地址对应的car的值也会随之修改。
mpg1(car);是值传递,将cat的值传进mpg1()函数中,作用域是函数中。函数中参数的改变不会改变函数外的值。
car=mpg1(car);虽然mpg1(car)函数里面值的修改不会直接引起car的改变,但是函数最后retrun返回修改的参数,并且赋值给外部car,这样外部的car值也会随之改变。
望采纳
打个比方,用指针就是把学霸的作业直接给你,你乱涂乱画对他会有实质性影响,但是直接调用就相当于学霸把他的作业打印了一份给你,你乱涂乱画对原来的那份没有任何影响
使用结构体变量作为函数的实参时,采用的是值传递,会将结构体变量所占内存单元的内容全部顺序传递给形参
相当于函数内复制了一个与原结构体一样的结构体进行操作
这就是值传递和地址传递的区别。
你好,我看了你列出的三种情况
第一种情况:调用函数,函数参数列表里声明的是形参,把实参传给形参,然后函数调用完毕,所有操作发生在形参,然后形参销毁了,整个过程和实参没有任何关系,所以当然没有改变实参。
第二种情况:把调用的函数的返回值赋给你打算操作的那个结构体。这样就成功把结构题的数据改变了。但是这个函数确实没什么意思,因为在形参和实参进行形实结合的时候,调用了一遍结构体的默认复制构造函数,然后在返回的时候又临时调用了一遍复制构造函数,然后把临时的返回值赋值给你要改变的这个结构体,才进行了两个结构体的内部成员的一一对应赋值。就最后这一步一一对应赋值是有用的,前面两部多余了,所以应该用第三种情况的方案。
第三种情况:把你想改变的那个结构体的地址传进来,函数根据这个地址索引到对应的内存空间,直接改变了你想改变的那一块儿内存空间里的数据。传地址是节约内存的,上述第二种是额外开辟了两块儿无用内存。
解决了吗?望采纳
一个是由指针改变引起的变化,一个是单纯返回值改变,可以学习一下函数相关知识和指针的实现
这就是值传递和地址传递的区别。可以复习下知识点
第一个没有发生变化是因为函数中的值没有传递到main中,
第二个发生变化是因为main中接收了函数的返回值,
第三个发生了变化是因为在函数中取指针指向的值, 并改变了指针所指向的值, 在main中把地址赋给了结构体, 所以第三个的值发生了改变