首先明确一个基本概念:
每一个要表达的数据都有一个类型,int/double等基础类型也好,指针也好,都要有类型。
何时用结构?
当我们想用一个类型表达一个复杂数据的时候,比如日期(包括年月日三个值),学生信息登记(学号班别姓名)等,我们就用到了结构。
一个结构的样子,一般来说它会有结构类型和结构变量,成员变量,我们常用的写法如下:
struct date{
int month;
int day;
int year;
}today,tomoorow;
上图中,struct date 是这个结构的结构类型,等同于int double 等, month,day,year是成员变量,today tomorrow是两个结构变量。
结构和数组的联系:
结构可以用于赋值,取地址,作为参数。
①相同点:
(1)结构的初始化和数组的初始化比较相同,struct date today={4,3,2014},可以用这种大括号的方式,来对应赋值给成员变量。
(2)和数组类似,数组用[ ]来访问其组元变量,结构变量用点 " . " ,来访问其成员变量,这里说的是结构变量而不是结构类型。
②不同点:
比起相同点,结构和数组更多有的是不同。
(1)数组中组元的类型,会一致,而struct 的成员变量可以又多个不同类型组成。
(2)数组是特殊的 const 指针,它在被初始化之后,就固定下来了,不能和其他的数组进行赋值运算。struct可以做,
today = (struct date){5,1,2018};
today=tomorrow;
上图沿用了,struct date类型的结构来进行说明,这两个操作都是合法的。
(3)结构变量在取它地址的时候,要用&符号,它不是指针。
这里重点提一下,结构和指针和参数
作用在于,加深理解。
①指针的情况:
还是拿struct date today 来作为例子。
struct date today={4,1,2014};
struct date *p=today;
(*p).month=12;
*p 可以看成是today这个变量,所以这样写没问题,为了方便起见还可以写成p->month。
进一步的我们可以有结构中的结构的情况,来进行说明。
struct point{
int x;
int y;
}; // 搞了一个关于点的结构,只有x和y
struct rectangle{
struct point p1;
struct point p2;
}r,*rp; //搞了个矩形结构,里面两个成员变量是 struct point型,并且矩形结构变量为r,和*rp。
rp=&r;
有两种种等价情况
r.p1.x // 相当于通过r访问r的p1,再访问p1的x
rp->p1.x // 相当于rp指向p1 的x
②参数的情况(这个我觉得是讲的最精彩的部分)
首先明确,当我们把结构变量作为某一函数的参数的时候,实际上也是传值,函数里面对结构变量做的运算,不会影响主函数的结构变量。那么如果我们想让外面的结构变量被子函数影响,可以用指针的方式或者是直接让子函数返回一个和外界结构变量一模一样的值,再作结构变量的赋值。
我们更推荐用指针的方式,比较省空间省时间。
以下我会用翁恺老师上课的课件中的代码说明上面的这个事情。
#include<stdio.h>
struct point{ //定义了struct point类型的结构
int x;
int y;
};
struct point* getStruct(struct point *); // 定义了一个函数名为getStruct的函数,它返回struct point 类型的指针。参数表要输入一个结构的指针。
void output(struct point);
void print(const struct point *p);
int main(){
struct point y=(struct point){0,0}; //初始化结构变量y
getStruct(&y); //对y的成员变量x,y赋值,并且返回一个结构类型指针
output(y); //注意,output 的参数是一个结构变量,它会输出结构变量的成员变量。
output(*getStruct(&y)); //这里体现了前面这样定义函数的好处,当你在函数名前面加上*号,相当于返回的是一个结构变量而不是结构变量的指针。
print(getStruct(&y)); //又一次印证了,getstruct返回的是一个指针。
}
struct point *getStruct(struct point *p){
scanf("%d",&p->x);
scanf("%d",&p->y);
return p;
}
output(struct point p)
{
printf("%d,%d",p.x,p.y);
}
print(const struct point *p)
{
printf("%d,%d",p->x,p->y);
}
感想
这个代码给我的冲击还是蛮大的,第一次知道定义一个函数的时候,可以让他返回一个指针,利用这个特性,加上 * 号运算符的话,相当于返回一个函数类型的值。