知识点5【结构体指针变量】

结构体指针变量 保存的是 结构体变量的地址。

1、结构体变量的地址 和 成员的地址

结构体指针变量_偏移量

结构体指针变量_结构体指针变量_02

2、结构体指针变量的定义

#include <stdio.h>
struct stu
{
    int num;
    char name[32];
    float score;
};

void test01()
{
    struct stu lucy;
    struct stu *p = &lucy;

    printf("请输入num name score:");
    //scanf("%d %s %f", &lucy.num, , &lucy.score);
    scanf("%d %s %f", &p->num, p->name, &p->score);

    printf("遍历lucy:%d %s %f\n", p->num, p->name, p->score);
}

案例1:结构体指针变量作为函数形参

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct stu
{
    int num;
    char name[32];
    float score;
};
void input_stu_arr(struct stu *edu, int n)
{
    int i=0;
    for ( i = 0; i < n; i++)
    {
        printf("请输入第%d个学生信息:", i+1);
        //scanf("%d %s %f", &(edu+i)->num, (edu+i)->name, &(edu+i)->score);
        scanf("%d %s %f",  &edu[i].num , edu[i].name, &edu[i].score);
    }
    return;
}
void sort_stu_arr(struct stu *edu, int n)
{
    int i=0;
    for ( i = 0; i < n-1; i++)
    {
        int min=i;
        int j=min+1;
        for ( ; j < n; j++)
        {
            if( edu[min].num > edu[j].num )
                min=j;
        }

        if(i!=min)
        {
            struct stu tmp=edu[min];
            edu[min] = edu[i];
            edu[i] = tmp;
        }
        
    }
    return;
}
void print_stu_arr(struct stu *edu, int n)
{
    int i=0;
    for ( i = 0; i < n; i++)
    {
        //printf("%d %s %f\n", edu[i].num, edu[i].name, edu[i].score);
        printf("%d %s %f\n", (edu+i)->num, (edu+i)->name, (edu+i)->score);
    }
    return;
}
void test02()
{
    struct stu edu[5];
    int n= sizeof(edu)/sizeof(edu[0]);
    memset(edu,0,sizeof(edu));

    //需求:定义函数 完成数组的输入
    input_stu_arr(edu, n);

    //需求:定义函数 完成数组的排序
    sort_stu_arr(edu, n);

    //需求:定义函数 完成数组的遍历
    print_stu_arr(edu, n);
}

结构体指针变量_偏移量_03

知识点6【结构体的函数指针成员】

int my_add(int x, int y)
{
    return x + y;
}
int my_sub(int x, int y)
{
    return x - y;
}
struct calc
{
    int x;
    int y;
    int (*func)(int, int);
};
void test03()
{
    struct calc ob1 = {10, 20, my_add};
    printf("%d\n", ob1.func(ob1.x, ob1.y));//30

    struct calc ob2 = {10, 20, my_sub};
    printf("%d\n", ob2.func(ob2.x, ob2.y));//-10
}

知识点7【结构体默认对齐规则】

1、知识点引入

结构体指针变量_基本类型_04

结构体指针变量_偏移量_05

2、结构体默认对齐规则

步骤1:确定结构体的分配单位(一行分配多少字节)

结构体中最大的基本类型的长度 作为分配单位。(double留意一下)

步骤2:确定每个成员位置的偏移量

偏移量 == 成员自身基本类型的整数倍

步骤3:收尾工作

结构体的总大小 必须是分配单位的整数倍

案例1:

结构体指针变量_偏移量_06

案例2:

struct A { char a; short c; int b; };

结构体指针变量_偏移量_07

案例3

struct A
{
    char a;
    int b;
    char c[5];
};

结构体指针变量_基本类型_08

3、结构体嵌套结构体的默认对齐规则

步骤1:确定结构体的分配单位(一行分配多少字节)

所有结构体中最大的基本类型的长度 作为分配单位。(double留意一下)

步骤2:确定每个成员位置的偏移量

成员偏移量 == 成员自身基本类型的整数倍

被嵌套的结构体整体偏移量 == 被嵌套的结构体中最大基本类型的整数倍。

步骤3:收尾工作

结构体的总大小 必须是分配单位的整数倍

结构体指针变量_分配单位_09

结构体指针变量_偏移量_10

结构体指针变量_结构体指针变量_11

知识点8【结构体强制对齐】

#pragma pack(n)

步骤1:确定结构体的分配单位(一行分配多少字节)

min(结构体中最大的基本类型的长度,n) 作为分配单位。(double留意一下)

步骤2:确定每个成员位置的偏移量

偏移量 == 成员自身基本类型的整数倍

步骤3:收尾工作

结构体的总大小 必须是分配单位的整数倍

结构体指针变量_结构体指针变量_12

知识点9【结构体位域】

1、位域的概述

无符号位域 一般成员类型为unsigned int,当然 unsigned char short long也是可以。

结构体指针变量_分配单位_13

结构体指针变量_结构体指针变量_14

结构体指针变量_基本类型_15

2、另起一个单元存储

结构体指针变量_基本类型_16

3、无意义位段

结构体指针变量_偏移量_17

4、综合案例

结构体指针变量_结构体指针变量_18

知识点10【共用体(联合体) 】

共用体的关键字union. 所有的成员 共用同一块空间。

结构体指针变量_分配单位_19

共用体的成员虽然共享同一块空间 但是操作该空间的实际大小 由成员自身大小决定。

案例1:以下结果_90_

结构体指针变量_偏移量_20

案例2:以下结果___

结构体指针变量_基本类型_21

知识点11【枚举】

枚举的关键字enum 将变量要赋的值 一一列举出来。

结构体指针变量_结构体指针变量_22

结构体指针变量_结构体指针变量_23

C语言不支持 bool

结构体指针变量_结构体指针变量_24