C语言学习笔记八、结构体、联合体、枚举

八、结构体、联合体、枚举

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》定义枚举类型就是表示定义多个无符号整型数,不需要定义枚举变量就可以直接使用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值