C语言,在结构变量中,为什么被调函数的结构变量指针可以改变实参,而直接调用结构体却不行呢

看下面的额程序:


```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;    
}


运行结果:

img

问题: 为什么指针直接改变了 实参,而 直接用结构体 却不能改变 实参呢?

值传递与地址传递的问题。
mpg2(&car); 是将car的地址传到函数mpg1()中,函数中进行修改,外部地址对应的car的值也会随之修改。
mpg1(car);是值传递,将cat的值传进mpg1()函数中,作用域是函数中。函数中参数的改变不会改变函数外的值。
car=mpg1(car);虽然mpg1(car)函数里面值的修改不会直接引起car的改变,但是函数最后retrun返回修改的参数,并且赋值给外部car,这样外部的car值也会随之改变。

望采纳

打个比方,用指针就是把学霸的作业直接给你,你乱涂乱画对他会有实质性影响,但是直接调用就相当于学霸把他的作业打印了一份给你,你乱涂乱画对原来的那份没有任何影响

使用结构体变量作为函数的实参时,采用的是值传递,会将结构体变量所占内存单元的内容全部顺序传递给形参
相当于函数内复制了一个与原结构体一样的结构体进行操作

这就是值传递和地址传递的区别。

你好,我看了你列出的三种情况
第一种情况:调用函数,函数参数列表里声明的是形参,把实参传给形参,然后函数调用完毕,所有操作发生在形参,然后形参销毁了,整个过程和实参没有任何关系,所以当然没有改变实参。
第二种情况:把调用的函数的返回值赋给你打算操作的那个结构体。这样就成功把结构题的数据改变了。但是这个函数确实没什么意思,因为在形参和实参进行形实结合的时候,调用了一遍结构体的默认复制构造函数,然后在返回的时候又临时调用了一遍复制构造函数,然后把临时的返回值赋值给你要改变的这个结构体,才进行了两个结构体的内部成员的一一对应赋值。就最后这一步一一对应赋值是有用的,前面两部多余了,所以应该用第三种情况的方案。
第三种情况:把你想改变的那个结构体的地址传进来,函数根据这个地址索引到对应的内存空间,直接改变了你想改变的那一块儿内存空间里的数据。传地址是节约内存的,上述第二种是额外开辟了两块儿无用内存。
解决了吗?望采纳

一个是由指针改变引起的变化,一个是单纯返回值改变,可以学习一下函数相关知识和指针的实现

这就是值传递和地址传递的区别。可以复习下知识点

第一个没有发生变化是因为函数中的值没有传递到main中,
第二个发生变化是因为main中接收了函数的返回值,
第三个发生了变化是因为在函数中取指针指向的值, 并改变了指针所指向的值, 在main中把地址赋给了结构体, 所以第三个的值发生了改变