结构
1. 作用:用一个整体去表达多个集合在一起的数据(这些数据不一定是同类型的)。
2. 结构的声明:
struct date{
int day;
int month;
int year;
};
- 注意:
- 一个结构是一个复合的数据类型,在里面可以有不同类型的变量,整体用一个变量来表达里面的全部变量。
- struct是一个关键字,后面是一条c语言的语句,所以最后的 “ ; ”不能漏掉。
- struct声明之后,以后的每个date里面都会有“day”、“month”、“year”这三个变量。
- 和本地变量一样,如果结构类型在函数内部声明就只能在函数内使用。若想能被多个函数使用通常在函数外部声明。
3.声明结构的形式
struct point{
int x;
int y;
}; // 声明结构
struct point p1,p2; // 定义变量
- 注意:p1,p2里面分别都有x,y的值
struct point{
int x;
int y;
}p1,p2;
- 同时声明和定义变量
- (该做法不常见)
struct{
int x;
int y;
}p1,p2;
- p1,p2是无名结构,一般用于短期使用
4. 结构变量
- 看下面的例子,一旦定义了today,today内存里面就是由month, day, year三部分组成的。
struct date today;
today.month=11;
today.day=23;
today.year=2007;
month | 11 |
day | 23 |
year | 2007 |
- 结构变量的初始化(类似数组)
- 第一种
struct date today={07,31,2014};
// 大括号的值会依次赋给声明时定义的各个变量。
- 第二种
struct date thismonth={.month=7};
// 跟数组一样,当初始化的个数少于变量个数时,其他变量自动赋零值;不同的是,这里可以指定哪一个变量赋什么值。
- 注意结构类型跟结构变量是不同的,结构类型是说明该种类型的结构内部的情况,结构变量是代表整个结构的。
5.结构成员
- 结构和数组相似,数组有很多单元,结构里面有很多成员。不同的是,结构的成员可以是不同类型的,而数组必须相同。
- 数组用" [ ] “运算符和下标访问其成员,结构用” . "运算符和名字访问其成员。
a[0]=10;
today.day;
6.结构运算(跟数组不同)
- 要访问整个结构,直接用结构变量的名字。
- 对于整个结构,可以做赋值、取地址,也可以传递给函参。
- 如赋值,数组无法做这两种运算:
p1=(struct point){5,10};
// 相当于p1.x=5, p1.y=10;
p1=p2;
// 相当于p1.x=p2.x , p1.y=p2.y;
7.结构指针
- 跟数组不同,结构变量的名字并不是结构变量的地址。要取地址必须使用“ & ”运算符。
struct date *pDate=&today;
8.结构作为函参
int numberOfDays (struct date d)
- 注意
- 整个结构可作为参数的值传入函数。
- 这时候是在函数内新建了一个结构变量,只是复制了调用者的结构的值。
- 也可以返回一个结构。
- 这些性质与数组完全不同。(数组在传参时传的是地址,改变的是本身)
9.结构的输入
- 没有直接的方法可以一次scanf整个结构。
- 输入结构的两种方法:
1.写一个输入函数,在其中创建一个临时的结构变量,返回这个结构。
struct point inputPoint()
{
struct point temp;
scanf("%d",&temp.x);
scanf("%d",&temp.y);
return temp;
}
void main()
{
struct point y;
y = inputPoint();
Outout(y);
}
2.结构指针作为参数,该方法更好。
- 在这里涉及访问指针里面的成员,引入一个新的符号“ -> ”(arrow),用来表示指针所指的结构变量中的成员。
struct date{
int month;
int day;
int year;
} myday;
struct date *p = &myday;
(*p).month = 12;
p->month = 12;
// 以上两种表达意思一样,但第二种更简洁。
- 使用指针之后,代码可以写成:
struct point* getStruct(struct point *p)
{
scanf("%d",&p->x);
scanf("%d",&p->y);
return p;
}
// 这里用了指针类型的返回值返回了p,作为一个技巧,方便在往后的程序中别的函数要继续使用这个指针。如:
int main()
{
output(*getStruct(&y));
print(getStruct(&y));
}
// 别的用法还有:
getStruct(&y)->x= 0;
*getStruct(&y) = (struct point){1,2};
10.结构数组
struct date dates[100];
struct date dates[ ] = { {4,5,2005},{2,4,2005} };
// 在引用数组某个单元的成员时
dates[1].day = 20;
11.结构嵌套
struct point{
int x;
int y;
};
struct rectangle{
struct point pt1;
struct point pt2;
};
// 如果有变量
struct rectangle r;
// 就可有
r.pt1.x, r.pt1.y, r.pt2.x, r.pt2.y
// 如果定义变量
struct rectangle r,*rp;
rp = &r;
// 那么以下等价
r.pt1.x
rp->pr1.x
注意没有rp->pt1->x(因为pt1不是指针,->只能用于指针)
- 在这里数组和结构的结合使用可以多样化、多层化,如数组的单元可以是结构,每个结构内部还有结构等。