结构体的声明
struct tag //tag为结构体标签
{
member-list; //结构体成员变量
}variable-list;
例如描述一个学生:
struct Stu
{
char name[20]; //姓名
int age; //年龄
char sex[5]; //性别
char sno[20]; //学号
}; //分号不能丢
特殊的结构体声明
匿名结构体类型
struct
{
int a;
char b;
float c;
}x;
struct
{
int a;
char b;
float c;
}a[20],*p;
以上两个结构体在声明的时候省略掉了结构体标签tag;所以在结构体后如果不直接创建结构体变量x,a[20],*p以后将无法使用此结构体。
在上面代码的基础上,p=&x合法吗?
编译时会发现:
由于是匿名结构体,编译器会将上面的两个结构体声明当成完全不同的类型 ,所以是非法的。
结构体的成员
结构体的成员可以是标量,数组,指针,甚至其他结构体。
结构体成员的访问
1-> 结构体变量访问成员。 结构体变量的成员是通过点操作符(.)访问的。
#include<stdio.h>
#include<stdlib.h>
struct Stu
{
char name[20];
int age;
};
int main()
{
struct Stu s;
strcpy(s.name, "zhangsan"); //使用.访问name成员
s.age = 20; //使用.访问age成员
system("pause");
return 0;
}
2-> 结构体访问指针变量的成员。有时候我们得到的不是一个结构体,而是指向一个结构体的指针,通过(->)来访问。
#include<stdio.h>
#include<stdlib.h>
struct Stu
{
char name[20];
int age;
};
int main()
{
struct Stu *s;
strcpy(s->name, "zhangsan"); //使用->访问name成员
s->age = 20; //使用->访问age成员
system("pause");
return 0;
}
结构的自引用
问题:在结构体中包含一个类型为该结构体本身的成员是否可以?
答:不可以
struct node
{
int data;
struct node next;
};
结构体还没有定义,成员就已经使用,而且它的成员结构体的大小无法计算,所以肯定是不可以的。
正确的自引用方式:
struct node
{
int data;
struct node *next;
};
结构体的定义和初始化
1. 定义
struct Point
{
int x;
int y;
}p1; //声明类型的同时定义变量p1
struct Point p2;//定义结构体变量p2
- 初始化
struct Point
{
int x;
int y;
}p1 = { 3, 4 }; //声明类型的同时定义变量p1且赋初值
struct Point p2 = { 1,2 };//定义结构体变量p2的同时赋初值
struct s
{
int data;
struct Point p1;
struct s*next;
}n1 = { 10, {5,6},NULL }; //结构体嵌套初始化
结构体内存对齐
结构体内存对齐的规则:
1. 第一个成员在结构体变量偏移量为0的地址处。
2. 其它成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 对齐数=编译器默认的一个对齐数与该成员大小的较小值
VS中默认值为8,Linux中默认值为4。
3. 结构体的总大小为最大对齐数的整数倍。
4. 如果嵌套了结构体,嵌套的结构体对其到自己的最大对齐数的整数倍;结构体的大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
练习1(不嵌套结构体)
#include<stdio.h>
#include<stdlib.h>
struct s1
{
char c1;
int i;
char c2;
};
int main()
{
printf("%d\n", sizeof(struct s1));
system("pause");
return 0;
}
分析:
运行:
练习2(嵌套结构体)
#include<stdio.h>
#include<stdlib.h>
struct s1
{
char c1;
int i;
char c2;
};
struct s2
{
char c;
struct s1 p;
double d;
};
int main()
{
printf("%d\n", sizeof(struct s2));
system("pause");
return 0;
}
分析:
运行:
设置结构体如何节省空间?
让占用内存小的成员尽量集中在一起。
#include<stdio.h>
#include<stdlib.h>
struct s1
{
char c1;
int i;
char c2;
};
struct s2
{
char c1;
char c2;
int i;
};
int main()
{
printf("%d\n", sizeof(struct s1));
printf("%d\n", sizeof(struct s2));
system("pause");
return 0;
}
s1和s2的类型成员一模一样,但是:sizeof(struct s1)=12; sizeof(struct s2)=8;
结构体传参
#include<stdio.h>
#include<stdlib.h>
struct s1
{
char c1;
int i;
char c2;
};
void print1(struct s1 s)
{
printf("%c\n", s.c1);
}
void print2(struct s1 *s)
{
printf("%c\n", s->c1);
}
int main()
{
struct s1 s = { 'a', 4, 'b' };
print1(s);
print2(&s);
system("pause");
return 0;
}
哪一个更好??
首选print2。
原因:函数传参时,参数需要压栈,如果传递的是结构体,结构体过大,参数压栈的系统开销就比较大,会导致性能下降。
所以最好传地址。