八、结构体、联合体、枚举
1.结构体
①. 概念:C语言描述复杂的对象,可以存放不同类型数据。
②. 模型:
struct 结构体的名字
{
成员属性1;
成员属性2;
成员属性3;
成员属性4;
....
}; -->一定要加分
例子:
struct student
{
char name[30];
unsigned char age;
char sex;
int num;
};
注意:
student = {“lisi”, 18, ‘M’, 100}; //数据类型是不可以赋值的
struct student= {“lisi”, 18, ‘M’, 100};//数据类型是不可以赋值的
struct student lisi = {“lisi”, 18, ‘M’, 100}; //正确用法:定义变量,申请了空间,才可以赋值。
③. 定义结构体变量-->是为了申请内存
1》全部初始化赋值1
struct student lisi= {“lisi”, 18, ‘M’, 100};
2》全部初始化赋值2
struct student lisi={.name="lisi", .age=18, .sex='M', .num=180};
struct student lisi={ .age=18, .name="lisi", .sex='M', .num=180};
3》部分初始化赋值3
struct student lisi={ .age=18, .num=180};
4》非初始化赋值
struct student lisi;
lisi.name = "lisi"; //数组非初始化赋值不能直接用数组名赋值为字符串
//相当于:char buf[20]; buf = “hello”; 不行,因为语法不支持
strcpy(lisi.name, "lisi"); //数组非初始化赋值可以用strcpy
lisi.age = 18;
lisi.sex = 'M';
lisi.high = 180;
④. 结构体大小
地址对齐:计算机为了提高访问结构体成员效率
在32位系统里面,最大地址对齐字节数是4个字节
在64位系统里面,最大地址对齐字节数是8个字节
确定结构体类型的大小:
1》先找出所占字节数最大成员,以他的字节数作为地址对齐字节数,
在32位系统里面如果地址对齐字节数超出4个字节,是以4个字节作为地址对齐的单位
在64位系统里面如果地址对齐字节数超出8个字节,是以8个字节作为地址对齐的单位
2》数组是以元素的类型作为地址对齐的单位
3》定义结构体成员时,可以尽量按照从小到大进行排列
4》结构体大小可能需要考虑二次地址对齐
⑤. 结构体数组
结构体数据类型+变量名[元素个数];
//1、定义学生结构体类型
struct student
{
char name[20];
char sex;
unsigned char age;
unsigned int num;
};
//2、定义结构体数组
struct student info[10];
bzero(info, sizeof(info));
//3、给数组成员赋值
⑥. 结构体指针
//1、定义学生结构体类型
struct student
{
char name[20];
char sex;
unsigned char age;
unsigned int num;
};
2、定义变量
struct student lisi;
3、定义结构体指针(一定要存储变量的内存地址后,才能解引用使用)
struct student *p = &lisi; //p==&lisi
//lisi.name = "lisi"; //数组非初始化赋值不能直接用数组名赋值为字符串
strcpy(lisi.name, "lisi");
lisi.age = 18;
lisi.sex = 'M';
lisi.num = 100;
strcpy((*p).name, "lisi");
(*p).age = 18;
(*p).sex = 'M';
(*p).num = 100;
strcpy(p->name, "lisi");
//p->name == (*p).name == (*(&lisi)).name ==lisi.name == (&lisi)->name
p->age = 18;
//p-> age == (*p). age == (*(&lisi)). age ==lisi. age == (&lisi)-> age
//p->age 不是表示age的地址,表示的是p这个地址里面的结构体成员age
//&(p->age ) 才是表示p这个地址里面的结构体成员age的地址
p->sex = 'M';
//p-> sex == (*p). sex == (*(&lisi)). sex ==lisi. sex == (&lisi)-> sex
p->num = 100;
注意:
1》怎么去定义结构体指针,然后存储结构体变量地址
2》怎么通过结构体指针访问结构体成员和获取结构体变量成员地址
3》通过结构体地址(指针)访问结构体成员的方式:
(*p).name == p->name == (&lisi)->name == lisi.name
(*p).age == p->age == (&lisi)->age == lisi.age
age的地址表示方式:
&(*p).age == &p->age == &(&lisi)->age == &lisi.age
4》一定要注意:
p->age 表示是结构体成员变量age的值,不是表示它的地址
它的地址表示方式: &p->age
5》结构体变量的值可以整体赋值给另外一个结构体变量
#include <stdio.h>
#include <strings.h>
#include <string.h>
//1、定义学生结构体类型
struct student
{
char name[20];
char sex;
unsigned char age;
unsigned int num;
};
int main(int argc, const char*argv[])
{
struct student lisi={"lisi", 'M', 18, 101};
struct student xiaoming;
bzero(&xiaoming, sizeof(xiaoming));
xiaoming = lisi;
/* strcpy(xiaoming.name, lisi.name);
xiaoming.sex = lisi.sex;
xiaoming.age = lisi.age;
xiaoming.num = lisi.num; */
printf("xiaoming信息:\n");
printf("name:%s\n", xiaoming.name);
printf("sex:%c\n", xiaoming.sex);
printf("age:%hhu\n", xiaoming.age);
printf("num:%d\n\n", xiaoming.num);
printf("lisi信息:\n");
printf("name:%s\n", lisi.name);
printf("sex:%c\n", lisi.sex);
printf("age:%hhu\n", lisi.age);
printf("num:%d\n", lisi.num);
return 0;
}
6》可以直接在定义结构体数据类型时,定义结构体变量
#include <stdio.h>
#include <strings.h>
#include <string.h>
//1、定义学生结构体类型
struct student
{
char name[20];
char sex;
unsigned char age;
unsigned int num;
}lisi; //顺便定义了一个结构体全局变量lisi
int main(int argc, const char*argv[])
{
struct student lisi={"lisi", 'M', 18, 101};
printf("lisi信息:\n");
printf("name:%s\n", lisi.name);
printf("sex:%c\n", lisi.sex);
printf("age:%hhu\n", lisi.age);
printf("num:%d\n", lisi.num);
return 0;
}
⑦. 结构体嵌套
//0、定义一个成绩结构体
struct score
{
int Chinese;
int Math;
int PE;
};
//1、定义学生结构体类型
struct student
{
char name[20];
char sex;
unsigned char age;
unsigned int num;
struct score myscore; //定义表示成绩的成员
};
//2、定义结构体变量
struct student lisi;
bzero(&lisi, sizeof(lisi))
//3、给它成员赋值
strcpy(lisi.name, "lisi");
lisi.age = 18;
lisi.sex = 'M';
lisi.num = 180;
lisi.myscore.Chinese = 99; //访问结构体里面的结构体成员
lisi.myscore.Math = 100;
lisi.myscore.PE = 90;
2.联合体
①. 概念:联合体成员共用一块内存,使用时,在成员选择一个
②. 定义联合体数据类型
union 联合体名字
{
成员属性1;
成员属性2;
成员属性3;
....
};
③. 联合体的内存大小
最大成员所占字节数就是它的内存大小
union sore
{
int a;
short b;
char c;
double d;
};
union sore mysore;
printf("%d\n", sizeof(mysore)); //8个字节--》double最大(八个字节)
④. 联合体成员不能混用--》最好选择其中一个成员使用,否则会出现数据混乱
⑤. 通过联合体判断主机字节序
主机字节序:计算机存储数据的顺序
小端序:低位数据存储到低位地址,高位数据存储到高位地址 大端序:高位数据存储到低位地址,低位数据存储到高位地址
3. 枚举 --》自定义数据类型--》本质表示定义多个无符号整型数
enum num
{
a,
b,
c,
d,
e,
};
等价于定义了5个unsigned int类型变量
unsigned int a=0, b=1, c=2, d=3, e=4;
注意:1》定义枚举类型就是表示定义多个无符号整型数,不需要定义枚举变量就可以直接使用
本文详细介绍了C语言中的结构体、联合体和枚举三种数据类型。结构体允许存储不同类型的数据,其大小受地址对齐规则影响;联合体则所有成员共享同一块内存;枚举用于定义一组整型常量。文中还展示了结构体数组、结构体指针的使用,以及结构体嵌套和联合体判断主机字节序的应用。
727

被折叠的 条评论
为什么被折叠?



