关于结构体是什么,可以理解为你自定义的一种变量类型,这种变量类型内部包含好几个不同类型的变量;
比如下方这个结构体,可以理解为定义了一种变量类型,名称是point,这种变量由两个int类型变量构成:

struct point{
    int x,y;
};

接着这个函数,是一个返回值类型为指向point类型变量的指针的函数:

struct point* getStruct(struct point* p);

在了解这个函数内容做了什么之前,我们需要先了解:

scanf("%d",&p->x);
scanf("%d",&(p->x));

上面这两行代码,是等价的。scanf函数需要接受的参数是地址,而指针通过->访问到的是成员的值并非地址,所以此处仍然需要取地址符。
所以下面这个函数实现了输入传入指针指向的结构体变量的x和y的值并返回指针p(但是p在这里始终没有变,相当于把传进来的东西原封不动地传回去了

struct point* getStruct(struct point* p){
    scanf("%d",&(p->x));
    scanf("%d",&(p->y));
    printf("%d %d",p->x,p->y);
    return p;
}

接下来这个没什么好说的,就是打印数值而已:

void output(struct point p){
    printf("%d %d",p.x,p.y);
}

下面这个也没什么好说的,使用指针访问成员并输出:

void print(const struct point *p){
    printf("%d %d",p->x,p->y);
}

接下来逐行解析main函数中的语句:

struct point y={0,0};

声明一个point类型的变量,名称为y,并且给它的x和y都赋值为0

getStruct(&y);

输入y,这里函数其实是有返回值的,但是没有使用

output(y);

输出y。注意,y一直都是一个point类型的变量,不是指针

output(*getStruct(&y));

先输入y,再输出y。getStruct函数的返回值就是y的地址,也就是&y,而*号是取值运算符,取出&y这块地址里的值,也就是*(&y),等价于

getStruct(&y);
output(y);

print(getStruct(&y));

getStruct的返回值是一个指针(y的地址),print函数接受的参数类型也是一个指向point类型变量的指针,也就是y的地址&y。等价于

getStruct(&y);
print(&y);

最后一句:

*getStruct(&y)=(struct point){1,2};

等号右边是将{1,2}指定为(struct point)类型,并将这一坨赋值到左边去。那现在看左边,getStruct(&y)返回值是y的地址,也就是&y,加上前面的取值运算符就是*(&y)。也就是y。所以就是等价于先

getStruct(&y);

y=(struct point){1,2};

End

Last modification:May 8, 2022
If you think my article is useful to you, please feel free to appreciate