嵌入式学习day14

文章详细介绍了C语言中的结构体与共用体的使用,包括typedef别名、结构体嵌套、结构体大小计算,以及共用体的定义、引用、初始化。同时,提供了处理学校人员信息和车辆信息的实例,涉及到动态内存分配和释放。
摘要由CSDN通过智能技术生成

一.结构体

1.typedef和结构体

  1. 定义一个别名
  typedef struct studnet
    {
        char name[10];
        int age;
        char sex;    
    }stu; //把struct student 起别名为stu   struct studnet===》stu
    stu a;
  1. 定义多个别名
typedef struct studnet
{
    char name[10];
    int age;
    char sex;
} stu, *stu_p, stu_arr[3];
// stu: 是结构体类型  等价 struct student
// stu_p: 是结构体指针类型  等价struct studnet *
// stu_arr:是结构体数组的类型  等价struct studnet arr[3];

2.结构体嵌套

  1. 结构体嵌套普通结构体
//定义人的信息:姓名、生日(年月日),年龄
typedef struct Date
{
    int year;
    int moth;
    int day;
}date;
typedef struct person
{
    char name[10];
    //
    date birthday;
    int age;
}person;//struct person===》person

person a={"张三",{2000,12,30},23};
printf("姓名:%s",a.name);
printf("%d年%d月%d日\n",a.birthday.year,a.birthday.month,a.birthday.day);
//注意a是person的变量名,只能调用person中的成员变量
printf("年龄:%d",a.age);
  1. 结构嵌套结构体数组
// 定义人的信息:姓名,年龄,车(可以有多个)
typedef struct // 当使用typedef是结构体名可以省略不写,无名结构体
{
    char name[20];
    float price;
} car;
typedef struct
{
    char name[10];
    int age;
    car car_arr[2];
} person;
int main(int argc, const char *argv[])
{
    person a = {"张三", 45, {"大众", 120000, "五菱宏光", 5000}};
    printf("姓名:%s\n", a.name);
    printf("年龄:%d\n", a.age);
    printf("车辆信息是\n");
    for (int i = 0; i < 2; i++)
    {
        printf("%s\t%.2f\n", a.car_arr[i].name, a.car_arr[i].price);
    }
    return 0;
}

3. 结构体大小

  1. 结构体变量的地址表示结构体第一个成员的地址
typedef struct
{
    char name[10];
    int age;    
}stu;
stu a;
&a = &a.name
  1. 结构体地址是连续
  2. 结构体的大小是每个成员字节大小的总和
  3. 满足字节对齐原则:
  • 结构体的首地址是最宽成员的整数倍,否则使用空字节填充
  • 结构体的总字节数,是最宽成员字节的整除倍,否则使用空字节填充
  • 结构体每个成员的偏移量,是该成员字节大小的整数倍,否则使用空字节填充
typedef struct
{
    char name[10];
    int a;
    int b;
    int age;
}stu;
typedef struct
{
    int a;
    float b;
}A;


typedef struct{

    double a;
    char b;
    int c;
    char *p;
    char d;
    double k;
}C;


typedef struct{
    
    int a;
    char b;
    float *p;
}B;
typedef struct{
    char a;//0x00
    B k;//0x01
}D;


int main(int argc, const char *argv[])
{
    stu a;//a表示变量名
    printf("&a=%p \n&a.name=%p \n&a.age=%p\n",&a,a.name,&a.age);
    printf("&a.a=%p\n&a.b=%p\n",&a.a,&a.b);

    printf("A=%ld\n",sizeof(A));

    printf("stu=%ld\n",sizeof(stu));

    B b;
    printf("&b.a=%p\n&b.b=%p\n&b.p=%p\n",&b.a,&b.b,&b.p);
    printf("B=%ld\n",sizeof(B));
    C c;
    printf("&c.a=%p\n&c.b=%p\n&c.c=%p\n&c.p=%p\n&c.d=%p\n&c.k=%p\n",&c.a,&c.b,&c.c,&c.p,&c.d,&c.k);
    printf("C=%ld\n",sizeof(C));

    D d;

    printf("&d.a=%p\n&d.k.a=%p\n&d.k.b=%p\n&d.k.p=%p\n",&d.a,&d.k.a,&d.k.b,&d.k.p);
    printf("D=%ld\n",sizeof(D));
    return 0;
}

二.共用体union

共用体:公用同一块空间存储的构造类型

1. 定义格式

格式 :

union 公用体名
{
    数据类型 成员1;
    数据类型 成员2;
    ....
    数据类型 成员n;
};
  1. union:共用体关键字
  2. 共用体名:满足命名规范,可有可无,当没有共用体名时,称为无名共用体
  3. {}: 必须存在
  4. ; 必须存在
  5. 成员的数据类型:基本类型、构造类型、空类型、指针类型
  6. 成员:成员的个数任意
  7. 共用体名位置任意,但是建议全局
  8. 共用体名描述,计算机不分配空间,当存在共用体名变量时,计算机分配空间

2. 共用体引用

普通共用体使用 “.” 调用

3. 共用体初始化

注意:共用体公用同一块存储空间,共用体的大小是最宽成员的字节大小

union A
{
    int a;
    char b;
    double c;
} a = {100, 20}; // 总字节字节是8字节
union A
{
    int a;
    char b;
    double c;
} a = {100}; // 默认是初始化的是第一个成员

union A b = {.b = 'a'};
int main(int argc, const char *argv[])
{
    printf("&a=%p\na.a=%p\na.b=%p\na.c=%p\n", &a, &a.a, &a.b, &a.c);

    printf("a.b=%c\n", a.b);
    printf("b.b=%c\n", b.b);
    return 0;
}

4. 共用体和结构体结合

  • 在struct里面

typedef struct
{
    int a;
    union
    {
        float b;
        char c;
    };
} A;
// A person = {100, .c = 'K'};
// person.a = 100;
// person.c = 'K';
  • 在struct外面
union AA
{
    float b;
    char c;
};
typedef struct
{
    int a;
    union AA s;
} A;
// A person = {200, .s.c = 'A'}

作业

作业1:有若干个学校人员的信息,包括学生和教师。其中学生的数据包括:姓名、性别、职业s/S、分数。教师的数据包括:姓名、性别、职业t/T、职务。要求用同一个表格来处理以上数据。

1,定义函数在堆区申请空间n
struct B p= (struct B * )malloc(sizeof(struct B) n );
2,定义函数实现录入学校人员信息
3,定义函数输出学校人员信息
4,定义函数计算学生平均成绩
5,定义函数计算老师的个数
6,释放存储空间

main.c

#include "head.h"
int main()
{
    int n;
    printf("请输入人数:\t");
    scanf("%d", &n);
    personnel *per;
    per = Create(n);                  // 申请空间
    Input(per, n);                    // 输入信息
    Output(per, n);                   // 输出信息
    float average;                    // 平均成绩
    int num;                          // 老师数目
    average = average_scores(per, n); // 平均数目
    num = techer_num(per, n);         // 教师数目
    printf("学生的平均分为%.2f\n", average);
    printf("老师的个数为%d\n", num);
    free_fun(per);
    system("pause");
    return 0;
}

1.c

#include "head.h"

personnel *Create(int n) // 申请空间
{
    personnel *p = (personnel *)malloc(sizeof(personnel) * n);
    if (p == NULL)
        return NULL;
    return p;
}
void Input(personnel *p, int n) // 定义函数实现录入学校人员信息
{

    for (int i = 0; i < n; i++)
    {
        printf("请输入姓名:\t");
        scanf("%s", (p + i)->name);
        printf("请输入性别:\t");
        scanf(" %c", &(p + i)->sex);
        printf("请输入职业:\t");
        scanf(" %c", &(p + i)->occupation);
        if ((p + i)->occupation == 's' || (p + i)->occupation == 'S')
        {
            printf("请输入分数\t");
            scanf("%f", (p + i)->score);
        }
        else if ((p + i)->occupation == 'T' || (p + i)->occupation == 't')
        {
            printf("请输入职务\t");
            scanf("%s", (p + i)->post);
        }
    }
}
void Output(personnel *p, int n) // 定义函数,输出学校人员信息
{
    printf("姓名\t性别\t职业\t分数/职务\n");
    for (int i = 0; i < n; i++)
    {
        printf("%s\t%c\t%c\t", (p + i)->name, (p + i)->sex, (p + i)->occupation);
        if ((p + i)->occupation == 's' || (p + i)->occupation == 'S')
        {
            printf("%f\n", (p + i)->score);
        }
        else if ((p + i)->occupation == 'T' || (p + i)->occupation == 't')
        {
            printf("%s\n", (p + i)->post);
        }
    }
}
float average_scores(personnel *p, int n) // 定义函数计算学生平均成绩
{
    float sum = 0;
    int count = 0;
    for (int i = 0; i < n; i++)
    {
        if ((p + i)->occupation == 's' || (p + i)->occupation == 'S')
        {
            sum += (p + i)->score;
            count++;
        }
    }
    return sum / count;
}
int techer_num(personnel *p, int n) // 定义函数计算老师的个数
{
    int count = 0;
    for (int i = 0; i < n; i++)
    {
        if ((p + i)->occupation == 't' || (p + i)->occupation == 'T')
            count++;
    }
    return count;
}
personnel *free_fun(personnel *p) // 释放空间;
{
    if (p != NULL)
    {
        free(p);
        p = NULL;
    }
    return p;
}
}

head.h

#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
    char name[20];   // 姓名
    char sex;        // 性别
    char occupation; // 职业
    union
    {
        float score;   // 分数
        char post[10]; // 职务
    };
} personnel;
personnel *Create(int n);                  // 定义函数在堆区申请空间n
void Input(personnel *p, int n);           // 定义函数实现录入学校人员信息
void Output(personnel *p, int n);          // 定义函数,输出学校人员信息
float average_scores(personnel *p, int n); // 定义函数计算学生平均成绩
int techer_num(personnel *p, int n);       // 定义函数计算老师的个数
char *free_fun(personnel *p);                   // 释放空间;

#endif

作业2:在堆区申请5个连续的存储空间,实现车辆信息的输入(品牌,颜色,价格)

1>调用函数在堆区申请空间
2>调用函数实现输入
3>调用函数对价格排序
思路:和正常的冒泡是一样的
注意点:
1>if(条件) 条件是价格的比较 (p+j)->price (p+j+1)->price
2> 交换的是整个车的信息
例如: (p+j)表示整个车的地址
(p+j)表示整个车的信息
交换的是
(p+j) 和*(p+j+1) 对应的整体信息
3> 注意中间变量t的类型,应该是结构体类型
4>调用函数输出
5>释放堆区空间

main.c

#include "head.h"

int main()
{
    CAR *car;
    car = Create(5);  // 申请堆区空间
    Input(car, 5);    // 输入数据
    bubbling(car, 5); // 冒泡排序
    Output(car, 5);   // 输出排序后的结果
    free_fun(car);    // 释放空间

    system("pause");
    return 0;
}

1.c

#include "head.h"
CAR *Create(int n)
{
    CAR *p = (CAR *)malloc(sizeof(CAR) * n);
    if (p == NULL)
        return NULL;
    return p;
}
void Input(CAR *p, int n) // 实现输入
{
    for (int i = 0; i < n; i++)
    {
        printf("请输入第%d辆车信息\n", i + 1);
        printf("品牌\t");
        scanf("%s", p[i].brand);
        printf("颜色\t");
        scanf("%s", p[i].colour);
        printf("价格\t");
        scanf("%d", &p[i].price);
    }
}
void bubbling(CAR *p, int n) // 实现冒泡排序
{
    for (int i = 0; i < n - 1; i++)
    {
        int count = 0;
        CAR t;
        for (int j = 0; j < n - i - 1; j++)
        {
            if ((p + j)->price > (p + j + 1)->price)
            {
                t = *(p + j); // 此处为交换值,整体交换结构体数据
                *(p + j) = *(p + j + 1);
                *(p + j + 1) = t;
                count++;
            }
        }
        if (count == 0)
            break;
    }
}
void Output(CAR *p, int n) // 输出结果
{
    printf("排序后的结果为\n");
    printf("品牌\t颜色\t价格\n");
    for (int i = 0; i < n; i++)
    {
        printf("%s\t%s\t%d\n", (p + i)->brand, (p + i)->colour, (p + i)->price);
    }
}
CAR *free_fun(CAR *p) // 释放空间
{
    if (p != NULL)
    {
        free(p);
        p = NULL;
    }
    return p;
}

head.h

#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
    char brand[20];
    char colour[20];
    int price;

} CAR;

CAR *Create(int n);           // 申请堆区空间
void Input(CAR *P, int n);    // 实现输入
void bubbling(CAR *p, int n); // 实现冒泡排序
void Output(CAR *p, int n);   // 输出结果
CAR *free_fun(CAR *p);        // 释放空间

#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值