结构
结构是一个或多个变量的集合,这些变量可能为不同的类型,为了处理的方便而将这些变量组织在一个名字之下。
结构的声明方式:
//声明一个结构
struct point{
int x;
int y;
};
//声明三个结构,类似与int a,b,c
struct {int x;int y;} a,b,c;
//给结构赋初值
struct point maxpt = {200,300};
结构取值:结构名.变量名
struct point{
int x;
int y;
};
struct point pt;
pt.x;
pt.y;
结构中的结构:
struct point{
int x;
int y;
};
struct rect{
struct point pt1;
struct point pt2;
};
struct rect screen ;
screen.pt1.x;
结构与函数
结构的合法操作
- 结构整体复制和赋值。
- 向函数传参
- 函数返回值
- 通过&运算符取地址。
- 访问结构的成员。
- 可以通过赋值进行初始化。
传递结构的的结构成员
struct point{
int x;
int y;
};
struct rect{
struct point pt1;
struct point pt2;
};
//通过x,y构造一个点
struct point makepoint(int x,int y){
struct point temp;
temp.x = x;
temp.y = y;
return temp;
}
//将两个点相加
struct point addpoint(struct point p1, struct point p2){
p1.x += p2.x;
p1.y += p2.y;
return p1;
}
//如果p点在矩形内,则返回1,否则返回0
int ptinrect(struct point p, struct rect r){
return p.x >= r.pt1.x && p.x < r.pt2.x && p.y >= r.pt1.y && p.y < r.pt2.y;
}
//返回规范形式的矩形
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
struct rect canonrect(struct rect r){
struct rect temp;
temp.pt1.x = min(r.pt1.x,r.pt2.x);
temp.pt1.y = min(r.pt1.y,r.pt2.y);
temp.pt2.x = max(r.pt1.x,r.pt2.x);
temp.pt2.y = max(r.pt1.y,r.pt2.y);
return temp;
}
int main(int argc, char *argv[]){
struct rect screen ;
struct point middle;
struct point makepoint(int x, int y);
screen.pt1 = makepoint(0,0);
screen.pt2 = makepoint(1,1);
middle = makepoint((screen.pt1.x + screen.pt2.x)/2,(screen.pt1.y + screen.pt2.y)/2 );
}
结构指针
struct point origin, *pp;
pp = &origin;
printf("%d,%d",(*pp).x,(*pp).y);
printf("%d,%d",pp->x,pp->y);
struct rect r,*rp = &r;
//针对以上声明,以下四个表达式等价。
r.pt1.x;
rp->pt1.x;
(r.pt1).x;
(rp->pt1).x;
优先级
struct {
int len;
char *str;
} *p;
++p->len;//等价于++(p->len)
->的优先级比*高
*p->str//读取的是指针str所指向的对象的值。
结构数组
struct {
char *word;
int count;
} keytab[] = {
"auto",0,
"break",0,
"case",0
};
另外一种方式,可以将初值放在大括号内。
struct {
char *word;
int count;
} keytab[] = {
{"auto",0},
{"break",0},
{"case",0}
};
结构体的内存分配
struct p{
int x;
long l;
} p;
struct pp{
char c;
struct p px;
}ppp;
printf("%d", sizeof(ppp));//24
联合
联合是可以(在不同时刻)保存不同类型和长度的对象和变量,编译器负责跟踪对象的长度和对齐要求。
//假设一个常量可能是int、float、char类型
union u_tag{
int ival;
float fval;
char *sval;
} u;
- 联合体就是结构
- 它的所有成员相对于基地址的偏移量都为0
- 此结构空间要大到足够容纳最”宽”的成员
- 其对齐方式要适合其中所有的成员