结构体(1)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档



一、结构体定义

struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在学习小组
    float score;  //成绩
};

结构体是一种集合,它里面包含了多个变量或数组,

结构体是一种数据类型,可以用来定义变量

struct stu stu1, stu2;

stu1 它是 stu 类型,由 5 个成员组成。

结构体和数组类似,也是一组数据的集合。数组使用下标[ ]获取单个元素,结构体使用点号.获取单个成员。

#include <stdio.h>
int main(){
    struct{
        char *name;  //姓名
        int num;  //学号
        int age;  //年龄
        char group;  //所在小组
        float score;  //成绩
    } stu1;

    //给结构体成员赋值
    stu1.name = "Tom";
    stu1.num = 12;
    stu1.age = 18;
    stu1.group = 'A';
    stu1.score = 136.5;

    //读取结构体成员的值
    printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", stu1.name, stu1.num, stu1.age, stu1.group, stu1.score);

    return 0;
}

Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!

二、结构题数组

struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在小组 
    float score;  //成绩
}class[5];

表示一个班级有5个学生。

#include <stdio.h>

struct {
    char* name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在小组
    float score;  //成绩
}class[] = {
    {"Li ping", 5, 18, 'C', 145.0},
    {"Zhang ping", 4, 19, 'A', 130.5},
    {"He fang", 1, 18, 'A', 148.5},
    {"Cheng ling", 2, 17, 'F', 139.0},
    {"Wang ming", 3, 17, 'B', 144.5}
};

int main() {
    int i, num_140 = 0;
    float sum = 0;
    for (i = 0; i < 5; i++) {
        sum += class[i].score;
        if (class[i].score < 140) num_140++;
    }
    printf("sum=%.2f\naverage=%.2f\nnum_140=%d\n", sum, sum / 5, num_140);
    return 0;
}

计算全班学生的总成绩、平均成绩和以及 140 分以下的人数

sum=707.50
average=141.50
num_140=2

三、结构体指针

//结构体
struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在小组
    float score;  //成绩
} stu1 = { "Tom", 12, 18, 'A', 136.5 };
//结构体指针
struct stu *pstu = &stu1;//指向结构体的指针

获取结构体成员的两种形式:

1.(*pointer).memberName///(*pstu).name

2.pointer->memberName///pstu->name

这是->的唯一用途

#include <stdio.h>
int main(){
    struct{
        char *name;  //姓名
        int num;  //学号
        int age;  //年龄
        char group;  //所在小组
        float score;  //成绩
    } stu1 = { "Tom", 12, 18, 'A', 136.5 }, *pstu = &stu1;

    //读取结构体成员的值
    printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", (*pstu).name, (*pstu).num, (*pstu).age, (*pstu).group, (*pstu).score);
    printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", pstu->name, pstu->num, pstu->age, pstu->group, pstu->score);

    return 0;
}

Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!
Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!

结构体指针作为函数参数

#include <stdio.h>

struct stu {
    char* name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在小组
    float score;  //成绩
}stus[] = {
    {"Li ping", 5, 18, 'C', 145.0},
    {"Zhang ping", 4, 19, 'A', 130.5},
    {"He fang", 1, 18, 'A', 148.5},
    {"Cheng ling", 2, 17, 'F', 139.0},
    {"Wang ming", 3, 17, 'B', 144.5}
};

void average(struct stu* ps, int len);

int main() {
    int len = sizeof(stus) / sizeof(struct stu);
    average(stus, len);//因为是数组,所以可以不加&
    return 0;
}

void average(struct stu* ps, int len) {
    int i, num_140 = 0;
    float average, sum = 0;
    for (i = 0; i < len; i++) {

        sum += (ps + i)->score;

        if ((ps + i)->score < 140)
        {
            num_140++;
        }
    }
    printf("sum=%.2f\naverage=%.2f\nnum_140=%d\n", sum, sum / 5, num_140);
}

sum=707.50
average=141.50
num_140=2

四、枚举

enum week{ Mon, Tues, Wed, Thurs, Fri, Sat, Sun };

枚举值默认从 0 开始,week 中的 Mon、Tues … Sun 对应的值分别为 0、1 … 6。

enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };

举值就从 1 开始递增,Mon、Tues … Sun 对应的值分别为 1、2 … 7。

五、共用体

union data{
    int n;
    char ch;
    double f;
};
union data a, b, c;

共用体 data 中,成员 f 占用的内存最多,为 8 个字节,所以 data 类型的变量(也就是 a、b、c)也占用 8 个字节的内存

这是与结构体不同的地方。

#include <stdio.h>

union data{
    int n;
    char ch;
    short m;
};

int main(){
    union data a;
    printf("%d, %d\n", sizeof(a), sizeof(union data) );
    a.n = 0x40;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
    a.ch = '9';
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
    a.m = 0x2059;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
    a.n = 0x3E25AD54;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
   
    return 0;
}

4, 4
40, @, 40
39, 9, 39
2059, Y, 2059
3E25AD54, T, AD54

共用体成员之间会相互影响,修改一个成员的值会影响其他成员。

NameNumSexProfessionScore / Course
HanXiaoXiao501fs89.5
YanWeiMin1011mtmath
LiuZhenTao109ftEnglish
ZhaoFeiYan982ms95.0
#include <stdio.h>
#include <stdlib.h>

#define TOTAL 4  //人员总数

struct{
    char name[20];
    int num;
    char sex;
    char profession;
    union{
        float score;
        char course[20];
    } sc;
} bodys[TOTAL];

int main(){
    int i;
    //输入人员信息
    for(i=0; i<TOTAL; i++){
        printf("Input info: ");
        scanf("%s %d %c %c", bodys[i].name, &(bodys[i].num), &(bodys[i].sex), &(bodys[i].profession));
        if(bodys[i].profession == 's'){  //如果是学生
            scanf("%f", &bodys[i].sc.score);
        }else{  //如果是老师
            scanf("%s", bodys[i].sc.course);
        }
        fflush(stdin);
    }

    //输出人员信息
    printf("\nName\t\tNum\tSex\tProfession\tScore / Course\n");
    for(i=0; i<TOTAL; i++){
        if(bodys[i].profession == 's'){  //如果是学生
            printf("%s\t%d\t%c\t%c\t\t%f\n", bodys[i].name, bodys[i].num, bodys[i].sex, bodys[i].profession, bodys[i].sc.score);
        }else{  //如果是老师
            printf("%s\t%d\t%c\t%c\t\t%s\n", bodys[i].name, bodys[i].num, bodys[i].sex, bodys[i].profession, bodys[i].sc.course);
        }
    }
    return 0;
}

据表格写代码,Score / Course在这的类型用到共用体

Input info: HanXiaoXiao 501 f s 89.5↙
Input info: YanWeiMin 1011 m t math↙
Input info: LiuZhenTao 109 f t English↙
Input info: ZhaoFeiYan 982 m s 95.0↙

Name            Num     Sex     Profession      Score / Course
HanXiaoXiao     501     f       s               89.500000
YanWeiMin       1011    m       t               math
LiuZhenTao      109     f       t               English
ZhaoFeiYan      982     m       s               95.000000
struct llm_act_info
{
    /// Pointer to parameters received from the Host (advertising, scanning or initiating)
    void const *                    host_params;
/// Interval element linked to this activity
struct sch_plan_elt_tag    plan_elt;

union
{
    /// Scanning specific activity info
    struct llm_scan_info  scan;
    /// Advertising specific activity info
    struct llm_adv_info  adv;
    /// Periodic advertising specific activity info
    struct llm_per_adv_info  per_adv;
    /// Periodic sync specific activity info
    struct llm_sync_info sync;
    /// Connection specific activity info
    struct llm_con_info  con;
} info;
/// State
uint8_t                         state;
};

项目中用到的共用体

六、位域

struct bs{
    unsigned m;
    unsigned n: 4;
    unsigned char ch: 6;
};//n、ch它们分别占用 4、6 位(Bit)的内存//m 它占用 4 个字节(Byte)的内存

有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。例如开关只有通电和断电两种状态,用 0 和 1 表示足以,也就是用一个二进位。正是基于这种考虑,C语言又提供了一种叫做位域的数据结构

七、位运算

&:参与&运算的两个位都为 1 时,结果才为 1

|:参与|运算的两个二进制位有一个为 1 时,结果就为 1

‘异’或^:参与^运算两个二进制位不同时,结果为 1,相同时结果为 0

~:~1为0,~0为1

<<:高位丢弃,低位补0

:低位丢弃,高位补 0 或 1。如果数据的最高位是 0,那么就补 0;如果最高位是 1,那么就补 1。

八、typedef和const

struct stu stu1;
使用typedefstruct stu 起了一个别名 STU
    
STU stu1;
typedef int INTEGER;
INTEGER a, b;
a = 1;
b = 2;

INTEGER a, b;等效于int a, b;

typedef 和 #define 差不多,但是有区别。

const被它修饰的变量不能改变,和 #define 差不多

const修饰指针会有不同

const int *p1;
int const *p2;
int * const p3;

在最后一种情况下,指针是只读的,也就是 p3 本身的值不能被修改;在前面两种情况下,指针所指向的数据是只读的,也就是 p1、p2 本身的值可以修改(指向不同的数据),但它们指向的数据不能被修改。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值