01、结构体定义

基本定义:结构体,通俗讲就像是打包封装,把一些有共同特征(比如同属于某一类事物的属性,往往是某种业务相关属性的聚合)的变量封装在内部,通过一定方法访问修改内部变量。

结构体的定义:

第一种:只有结构体定义

struct stuff{  char *name;  //姓名int num;  //学号int age;  //年龄float score;  //成绩
};

第二种:附加该结构体类型的“结构体变量”的初始化的结构体定义,如下代码也就是定义结构体时,直接定义一个变量

struct stuff{  char *name;  //姓名int num;  //学号int age;  //年龄float score;  //成绩
}xiaoming;

其实这就相当于先定义结构体,再用结构体定义一个结构体变量:

struct stuff{  char *name;  //姓名int num;  //学号int age;  //年龄float score;  //成绩
};
struct stuff xiaoming;  

第三种:使用typedef关键字,可以将结构体变量定义时少写一个struct,比较省事。

typedef struct stuff{  char *name;  //姓名int num;  //学号int age;  //年龄float score;  //成绩
}stuff_s;
stuff_s xiaoming;

使用typedef还可以进一步简化,将结构体名也省略,这也是常用的方式

typedef struct{  char *name;  //姓名int num;  //学号int age;  //年龄float score;  //成绩
}stuff_s;
stuff_s xiaoming;

STM32的标准外设库有大量这样的应用,如下

typedef struct
{uint32_t GPIO_Pin;GPIOMode_TypeDef GPIO_Mode;GPIOSpeed_TypeDef GPIO_Speed;GPIOOType_TypeDef GPIO_OType;GPIOPuPd_TypeDef GPIO_PuPd;
}GPIO_InitTypeDef;

关于结构体指针定义问题,有很多的“骚操作”的写法,我一般按照下面定义指针

stuff_s *cuerrent_student;

02、结构体初始化

在大部分应用中,一般都是定义结构体后,在代码中进行初始化,如下所示

typedef struct{  char *name;  //姓名int num;  //学号int age;  //年龄float score;  //成绩
}stuff_s;
stuff_s xiaoming;
void xiaoming_inf_init()
{xiaoming.name = "xiaoming";xiaoming.num = 1;xiaoming.age = 18.0;xiaoming.score = 100;
}

当然也有可以定义时就进行数据初始化的

typedef struct{  char *name;  //姓名int num;  //学号int age;  //年龄float score;  //成绩
}stuff_s;
stuff_s xiaoming={"xiaoming",1,18.0,100};

C99C11为结构提供了指定初始化器(designatedinitializer)。其初始化器使用点运算符和成员名。

关于C99和C11的知识可以看我之前的文章《C语言的发展》,在IAR和Keil中记得勾选C99的选项。

例如,只初始化xiaoming结构中的name成员,可以这样做:

stuff_s xiaoming=
{.name = "xiaoming"
};

也可以按照任意顺序使用指定初始化器:

stuff_s xiaoming=
{.age = 18.0,.name = "xiaoming"
};

这样的赋值方式,在linux方式中很常见,以platform驱动框架为例:

static struct platform_driver leds_platform_driver = {.driver = {.name = "imx6ul-led",.of_match_table = leds_of_match,},.probe = leds_probe,.remove = leds_remove,
};

03、访问结构体成员

结构体成员的访问需要借助结构体成员运算符(.),如下

stuff_s xiaoming,xiaohong;
void student_inf_init()
{xiaoming.name = "xiaoming";xiaoming.num = 1;xiaoming.age = 18.0;xiaoming.score = 100;xiaohong.name = "xiaohong";xiaohong.num = xiaoming.num+1;
}

使用指针时,使用(->)符号访问结构体成员

stuff_s xiaoming,xiaohong;
stuff_s *cuerrent_student;
void student_inf_init()
{xiaoming.name = "xiaoming";xiaoming.num = 1;xiaoming.age = 18.0;xiaoming.score = 100;cuerrent_student = &xiaohong;cuerrent_student->name = "xiaohong";cuerrent_student->num = xiaoming.num+1;
}

04、枚举与结构体的结合

简单介绍下枚举:有些数据的取值往往是有限的,只能是非常少量的整数,并且最好为每个值都取一个名字,以方便在后续代码中使用,比如一个星期只有七天,一年只有十二个月,一个班每周有六门课程等。

当然,你可以用宏定义

#define Mon 1
#define Tues 2
#define Wed 3
#define Thurs 4
#define Fri 5
#define Sat 6
#define Sun 7

如果用了枚举则如下

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

枚举是一种类型,通过它可以定义枚举变量:

enum week a, b, c;

那么枚举和结构体一起用会产生什么效果呢?假设我们要协议一个语音芯片的驱动,需要表示语音芯片的状态

typedef enum//语音芯片状态
{VOICE_INIT_OK =            0x4A,  //语音芯片上电初始化成功后,自动回传命令VOICE_RECEIVE_OK =           0x41,  //语音芯片收到正确的命令帧VOICE_ORDER_ERROR=         0x45,  //语音收到错误的命令帧VOICE_BUSY     =            0x4E,  //语音忙(正在合成状态)VOICE_FREE     =           0x4F  //语音空闲
} VOICE_STATUS;
typedef struct {VOICE_STATUS status ;                 //!< 语音芯片状态Ouint32  delayTicks;                   //!< 播放时间Ouint32  playtimes;                    //!< 播放次数
} voicechip_Para_S;
voicechip_Para_S voicechip_Para;

那么改变语音芯片状态时,我们可以按照下面这样写

voicechip_Para.status = VOICE_RECEIVE_OK;

判断语音芯片状态时,我们可以按照下面写

if((voicechip_Para.status == VOICE_FREE)

当然,你用宏定义是可以的,代码也很整洁。这里希望你能理解文章最开始的那句话:结构体是某种业务相关属性的聚合。

05、骚操作

关于结构体有很多骚操作,如果全部总结下来,这篇文章就会很臃肿,例如结构体嵌套的骚操作,可以一边定义结构体B,一边就使用上:

struct A{  struct B{
int c;  }b;  struct B sb;
}a;

对于这样的情况,我一般主张能看懂就行,自己写代码时就少点这样的骚操作

struct B{  int c;
}b;
struct A{  struct B sb;
}a;

点击查看专题:C语言进阶

STM32编程中枚举和结构体的结合相关推荐

  1. Swift 中枚举、结构体、类(enum、struct、class)

    Swift 中枚举.结构体.类(enum.struct.class) Swift中的枚举与OC相比不会自动分配初始值,值的类型不会限定为整数,可以给定关联值类型和具体值(整型.浮点型.字符型(Swif ...

  2. 【C#】枚举_结构体_数组

    最近看C#视频,关于这部分,先看了一遍,又照着敲了一遍,自己敲的过程发现了一些有意思的东西. 枚举:定义一个枚举类型的变量,这个变量有很多相同类型的值.比如性别Gender这个变量可以有男和女这两个值 ...

  3. 关于VC网络编程中用 char 发送结构体的说明

    关于VC网络编程中用 char 发送结构体的说明     在VC中要发送struct的程序,如果需要中间打包的话,首先因该将结构体转换为字节型的.然后再用 send (SOCKET s,const c ...

  4. C#基础6:枚举与结构体

    PS:注释和讲解全在代码中 1. 枚举与结构体 using System; using System.Collections.Generic; using System.Linq; using Sys ...

  5. c语言如何宏定义枚举型结构体,C语言学习笔记--枚举结构体

    枚举 枚举是一种用户定义的数据类型,它用关键字enum以如下语法格式来声明: enum 枚举类型名字 {名字0,名字1,...,名字n}: 枚举类型名字通常并不真的使用,要用的是大括号里面的名字,因为 ...

  6. c语言send发送结构体,Socket编程中用send发送结构体

    Socket编程中用send发送结构体 原创 2010年04月28日 19:17:00 标签:socket /编程 /struct /google /string /input 11868 最近在开发 ...

  7. 小小的区分枚举与结构体

    参考洋桃电子老师讲的,添加了自己的理解 目录 一.枚举 1.枚举的定义 2.理解枚举 3.枚举在C语言中的使用格式 4.枚举的注意事项 4.枚举与数组的区别 二.结构体 1.结构体与枚举和数组之间的区 ...

  8. Java中如何实现结构体?如何对结构体进行排序?

    ***今天在做老师布置的编程题时,遇到了本题.感觉这道题如果用C++来解决的话,用结构体比较好吧!哈哈哈,可能还有其他的好方法,但我目前想到的是用结构体来解决比较合理.Java中有结构体吗?如果有,它 ...

  9. 遍历结构体_三菱ST语言编程(3)——结构体变量

    上篇文章介绍了数组,是一组相同类型数据的列表,那么不同类型的数据能否组合到一起用一个标签表示呢?答案当然是可以的,而实现这个功能的就是结构体(struct). 建立结构体 在三菱结构化编程的界面中左侧 ...

最新文章

  1. 华为云提供针对Nuget包管理器的缓存加速服务
  2. 神策 2021 数据驱动大会嘉宾阵容首曝 + 精彩观点前瞻
  3. Storm on yarn 安装
  4. Loj#6039-「雅礼集训 2017 Day5」珠宝【四边形不等式,dp】
  5. linux带宽最小的远程桌面,【图片】linux下哪种远程桌面服务最快?_linux吧_百度贴吧...
  6. Windows下svn服务器安装
  7. Python修饰符--函数修饰符 “@”
  8. SIP协议 会话发起协议(二)
  9. Expected value at 1:0 异常解决方法
  10. asp 基础操作之增删改查
  11. 批量下载哨兵数据的方法探索
  12. 网易公开课专辑下载脚本python
  13. 【Python实用工具】查询本机IP地址
  14. AHU HuffmanTree编码数据结构实验
  15. 类似易企秀的UI框架 整屏滑动
  16. java 常用四舍五入保留小数点后两位方法
  17. 对话Nodebrick创始人:区块链游戏需要更多玩家,韩国开发者偏保守
  18. 利用“bert模型”预测英语“完形填空”答案
  19. 小米4c怎么添加语言怎么设置在哪,小米4c路由器设置教程
  20. JOOQ初学-简单的增删改查demo

热门文章

  1. 学习easyui疑问(二)
  2. Python取整(四舍五入、向上取整、向下取整)
  3. Mac latex vscode配置外部PDF阅读器并配置对应跳转
  4. typeorm mysql2_指南 - 使用 TypeORM 和 Express 的示例 - 《TypeORM v0.2.20 中文文档》 - 书栈网 · BookStack...
  5. 通信要学很多计算机课吗,辽宁科技学院通信工程专业要学哪些课程,好学吗?...
  6. html 去文本框中的双引号_前端·HTML基础
  7. flutter 图解_Flutter 54: 图解基本生命周期
  8. 黑科技!两行代码完美解决:同时设置overflow-x:hidden,overflow-y:visible无效的问题...
  9. linux各版本基线检查脚本(centos6、centos7、ubuntu系列)
  10. 史上最全的ASP.NET MVC路由配置,以后RouteConfig再弄不懂神仙都难救你啦~