关于结构体是什么,可以理解为你自定义的一种变量类型,这种变量类型内部包含好几个不同类型的变量;
比如下方这个结构体,可以理解为定义了一种变量类型,名称是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