结构体:是一种构造数据类型
结构体的用途:把不同的数据类型整合起来,成为一个自定义的数据类型
定义结构体
第一种方式
struct User{
//年龄
int age;
//用户名
char name[10];
};
第二种方式
struct User{
int age;
char name[10];
} u = {18,"Zero"},u1;
第三种方式
struct User{
int age;
char name[10];
} u1,u2,u3;
第四种方式
struct Order{
int count;
char name[10];
};
struct User{
int age;
char name[10];
Order order;
};
第五种方式
struct User{
int age;
char name[10];
struct Order{
int count;
char name[10];
} order;
};
第六种方式,数组:
struct User{
int age;
char name[10];
} u1[2],u2[2] = {{18,"Zero"},{20,"迷离"}};
匿名结构体
一般情况下,定义的同时至少有一个申明变量,否则没有什么意义
好处:你可以控制结构体变量数量(限量版),一定程度上避免了出现结构体重名情况
struct{
int age;
double height;
char name[10];
} u1,u2;
使用结构体
struct User u = {18,"Zero"};
printf("%d, %s\n",u.age,u.name);
第二种使用方式-成员赋值
struct User u;
u.age = 20;
u.name = "Dream";//错误的赋值方式
strcpy(u.name,"Dream");
第四第五种定义方式使用:
struct User u = {18,"Zero",{999,"女装"}};
struct User u;
u.age = 100;
strcpy(u.name,"Zero");
u.order.count = 1000;
strcpy(u.order.name,"男装");
第六种定义方式(数组方式)使用:
u1[0].age = 100;
strcpy(u1[0].name,"Zero");
结构体和指针
struct User{
int age;
int height;
char name[20];
};
使用
struct User u = {18,180,"Zero"};
struct User *p = &u;
printf("%d, %d, %s",(*p).age,(*p).height,(*p).name);
(*p).age 等价于 p->age(简写)
结构体和内存(字节对齐)
结构体在内存中也是一块区域(有顺序,线性排列)
结构体字节对齐规则:
- 结构体变量的大小需要满足被最宽基本数据类型的成员大小所整除(int double float)
- 结构体变量的成员的首地址偏移量必须是最宽的基本数据类型的整数倍
例如:int 4字节 double8字节,常理说应该12字节。但是结构体必须满足 (结构体 % 最宽成员大小 = 0)最宽数据类型整倍数。所以 结构体大小为16.
struct User{
int age;
double height;
};
int main(){
struct User u = {18,165};
//打印结构体大小
//按常理来说:12字节,但是结果却是:16字节
//12%8?不成立 16%8=0成立
printf("大小: %lu\n",sizeof(u));
//为什么C语言要这么设计?
//初衷:就是为了提高读取效率(提高读取性能)
//刘翔跨栏(110):每隔10米一个栏,如果每一个栏之间的距离不统一,那么跨栏难度系数会加大
//遵循规律(节奏)
getchar();
return 0;
}
结构体动态内存分配
数组(动态内存分配)-数组大小是3
struct User *p = (struct User *)malloc(sizeof(struct User) * 3);
接下来可以通过数组方式操作结构体
typedef 别名简化操作
定义:第一种写法
struct User{
int age;
double height;
char name[10];
};
typedef struct User mUser;
定义:第二种写法
typedef struct User{
int age;
double height;
char name[10];
} mUser,AgeUser;
使用
mUser user;
user.age = 18;
user.height = 165.00;
联合体(共同体:union关键字)
作用:使多个不同类型的变量共用一块内存区域,联合体变量任何时候只有一个成员变量在内存中存在
好处:节约内存
联合体大小(在C语言中系统分配内存的机制)
条件一:最大的成员字节大小
条件二:还必须是最大的成员的基本数据类型的字节数的整数倍
union Student{
int id;
float height;
char sex;
char name[10];
};
使用:
union Student stu;
strcpy(stu.name,"XXXX");
stu.id = 100;
联合体-匿名联合体
好处:你可以控制结构体变量数量(限量版),一定程度上避免了出现结构体重名情况
第一种定义方式-匿名结构体
union{
int age;
char name[10];
} u;
使用:u.age = 100;
第二种方式:
static union{
int age;
char name[10];
};
使用:
age = 100;
strcpy(name,"Zero");
printf("%d\n",age);
printf("%s\n",name);
枚举
枚举(定义:enum)—int类型
总结:基本上和Java差不多
好处:限定了值,保证取值的安全性
enum MessageType{
//文本类型
Text = 10,
//图片类型
Image = 20,
};
使用:
enum MessageType d = Text;
printf("Text: %d\n",d);
枚举取别名
typedef enum MessageType{
//文本类型
Text = 10,
//图片类型
Image = 20,
} Message;
使用:
Message d = Text;
匿名枚举
enum{
//文本类型
Text = 10,
//图片类型
Image = 20
} Message;
使用:
Message = Text;