C语言结构体总结篇

结构体

1、定义结构体与声明结构体变量

①、

struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在学习小组
    float score;  //成绩
};
struct stu stu1, stu2; //声明
//或者
struct{  //没有写 stu
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在学习小组
    float score;  //成绩
} stu1, stu2;

②、一般这样创建结构体

typedef struct
{
    int a;
    char b;
    double c; 
    char *p;
    
} Simple1;
//现在可以用Simple2作为类型声明新的结构体变量
Simple1 u1, u2[20], *u3;

2、访问结构体成员

一般变量

  • 变量名.成员 比如 u1.b;

指针变量

  • 变量名->成员 比如 u3->c;

3、初始化结构体成员

①、声明结构体变量以后单独初始化每个成员
在这里插入图片描述
②、通过集合符号对结构体变量进行初始化
在这里插入图片描述
③、如果结构体里面嵌套结构体,初始化括号加在嵌套里面
在这里插入图片描述

4、结构体嵌套

结构体里面可以声明无限个结构体
在这里插入图片描述

5、结构体存储

按字节对长的知识
在这里插入图片描述
12字节
在这里插入图片描述
12字节
在这里插入图片描述
20字节
在这里插入图片描述
20个字节

6、结构体封装

C语言结构体不能直接封装函数,但可以通过封装函数指针的方式来实现,下面便是我实现的具体方式,可以很方便的移植到任何编译器上测试。

/* serial.h文件 */
//定义封装函数的结构体,并声明外部引用
//对串口操作函数封装。
typedef struct 
{
	void begin(long);
	void end();
	int (*peek)();
	uint8_t (*read)(void);
	void (*flash)();
	int (*availiable)();
	void (*checkRx)();
}MarlinSerial;
 
extern MarlinSerial MSerial;
 
/* serial.c文件 */
 
MarlinSerial MSerial; //定义MarlinSerial类型的结构体MSerial 
 
Serial_Init()
{
  MSerial.read = &Serial_Read;
}
 
 uint8_t Serial_Read(void)
{ 
   printf("hello word!"); //在这里仅作测试所用,未列出真正的串口读取函数
} 
 
/* main.c文件 */
int main(void)
{
    Serial_Init();
    MSerial.read(); //调用串口读取函数,目前功能为打印字符串
    while(1)
    {
       //
    }
}

重点应用

1、结构体指针

结构体指针定义与赋值(指向相同结构体的内存)

  • C语言指针可以指向内存中的函数,变量,数组,结构体等
  • 定义指向结构的指针,方式与定义指向其他类型变量的指针相似

我们要知道只要是存储在内存里的变量、数组,又或者是函数。编译器都会为它们分配一个地址,我们都可以通过指针变量指向这个地址,只要把指针变量定义成对应的数据类型就可以指向了。

比如说要指向字符型变量就定义成这样:unsigend char *p,当然也可以用void不指定类型,使用的时候再进行强制转换。

要指向函数就定义函数指针变量,那么结构体也能够定义变量,所以我们也可以定义结构体类型指针来指向它。

同样的定义访问结构体指针常用有2种方法:

①、

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

②、

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

在这里插入图片描述

  • 注意,结构体变量名和数组名不同,数组名在表达式中会被转换为数组指针,而结构体变量名不会,无论在任何表达式中它表示的都是整个集合本身,要想取得结构体变量的地址,必须在前面加&,所以给
    pstu 赋值只能写作:

struct stu *pstu = stu1;

而不能写作:

struct stu *pstu = stu1;

获取结构体指针成员

  • (*pointer).memberName
  • pointer->memberName

举例:


#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;
}

结构体指针作为函数参数

像其他普通参数一样,结构体指针变量能传递给函数。传递结构体指针比传递值有优势。如前所述,当指针变量被传递并且如果值被修改,则在调用者作用域内更新是有效的。假定我们有一个超过15个数据成员的非常大的结构体变量,相比传递地址(这时使用指针变量),如果按值传递发送这个变量到函数将花费更多时间。

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

#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);
}

2、结构体数组

参考添加链接描述

所谓结构体数组,是指数组中的每个元素都是一个结构体。在实际应用中,C语言结构体数组常被用来表示一个拥有相同数据结构的群体,比如一个班的学生、一个车间的职工等。

结构体数组定义

  • C语言中,定义结构体数组和定义结构体变量的方式类似,请看下面的例子
struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在小组 
    float score;  //成绩
}class[5];

结构体数组初始化

struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在小组 
    float score;  //成绩
}class[5] = {
    {"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}
};

结构体数组的使用也很简单,例如,获取 Wang ming 的成绩:

class[4].score;

修改 Li ping 的学习小组:

class[0].group = ‘B’;

举例

#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;
}

3、自引用结构体

结构体能将指针变量作为其成员字段。具体一点,我们能声明一个与包含它的结构体相同的指针变量类型的成员字段。
在这里插入图片描述
这部分在数据结构理解

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值