自定义类型
typedef类型说明
一般形式:
typedef 类型说明符 标识符;
例如:typedef int INTERGER;
typedef与define宏的定义有相似之处,但实际上有明显不同:
- typedef在编译阶段有效,而define宏的定义是预处理,发生在编译之前;
- typedef用来定义类型的别名,不只包含基本的数据类型,还包括自定义(如struct),课便于记忆且有一定的作用域;而define没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用;
- typedef作为类型的声明语句是以分号“ ;”结尾的,而define宏的定义通常不需要用标点结束。
结构体
结构体声明
一般形式:
struct 结构体标志
{
类型说明符 结构体成员名1;
类型说明符 结构体成员名2;
…
类型说明符 结构体成员名n;
}
例如:描述一个学生
struct Stu
{
char num[20];
char name[20];
int age;
char sex[3];
}Stu;
结构体定义和引用
1.定义
两种形式:
//说明结构的同时定义变量
struct Stu
{
char num[20];
char name[20];
int age;
char sex[3];
}s1,s2;
//先说明结构,后定义结构体变量
struct Stu
{
char num[20];
char name[20];
int age;
char sex[3];
};
struct Stu s1,s2;
2.初始化和引用
(1)初始化
struct Stu //类型声明
{
char name[15];//名字
int age; //年龄
};
struct Stu s = {"zhangsan", 20};//初始化
struct Node
{
int data;
struct Point p;
struct Node* next;
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化
struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化
(2)引用
一般格式:
结构体成员变量 . 成员变量
例如上述Stu引用age: s.age=21;
自引用:
struct Node
{
int data;
struct Node* next;
};
3.结构体内存对齐
可以通过以下几道题总结出规律:
//练习1:
struct S1
{
char a; // 1 +(补3)
int b; // 4
char c; // 1 +(补3)
};
printf("%d\n", sizeof(struct S1)); //12
//练习2:
struct S2
{
char a; //1 +(补1)
char b; //1 +(补1)
int i; //4
};
printf("%d\n", sizeof(struct S2)); //8
//练习3:
struct S3
{
double d; // 8
char c; // 2 +(补2)
int i; // 4
};
printf("%d\n", sizeof(struct S3)); //16
- 第一个成员在与结构体变量偏移量为0的地址处。
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
- 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
结构体的内存对齐是拿空间来换取时间的做法
因此,在设计结构体时,应让占用空间小的成员尽量集中在一起
默认对齐数:
#pragma pack(2) 默认对齐数2
#pragma pack() 取消设置的默认对齐数,还原为默认
4.位段
例如:
//位域(节省空间)
typedef struct text
{
char a : 1;
char b : 1;
char c : 1;
}text;
void main()
{
printf("%d\n", sizeof(text)); // 1
}
开辟空间最小单位按照字节,“ :1 ”代表占用1位(从bit位角度),1个字节8个bit。
1.位域不能跨字节存储
2.位域不能跨类型存储
枚举
定义:
enum Color
{
red, //枚举用“ , ”分隔
green,
blue
};
void main()
{
printf("%d %d %d\n", red, green, blue); //结果: 0 1 2
printf("size = %d \n", sizeof(enum Color)); // 4
}
- 默认从零开始,依次加1,只能是整数;
- 若有赋值,则赋值后依次加1;
- 每次只能传送一个;
联合
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员),当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
union Un
{
char c;
int i;
};
void main()
{
union Un un;
printf("%d\n", sizeof(un)); // 4 (最大成员的大小)
}
可以用来判断大小端:(大小端在“数据的存储”有讲)
//判断大小端
union Un
{
int a;
char c;
};
void main()
{
union Un un;
un.a = 1;
if (un.c == 1)
{
printf("little\n");
}
else printf("big\n");
}