🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
【72.1 结构体指针的重要用途。】 结构体指针有两个重要用途,一个是结构体数据的传输存储和还原,另一个是作为结构体数据在涉及函数时的参数入口。 什么是“结构体数据的传输存储和还原”?结构体本质是一个数组,数组内可能包含了许多不同数据长度类型的成员,当整个结构体数据需要存储或者传输(通信)给另外一个单片机时,这时候有两种选择,一种是一个成员一个成员的挨个处理,这种“以成员为单位”的处理方式比较繁琐麻烦,另外一种是把整个结构体变量当作一个“以字节为单位”的普通数组来处理,但是关键的问题来了,假如我们把整个结构体数据以“字节为单位”的方式“整体打包”传递给另外一个单片机,当这个接收方的单片机接收到我们这一组数据后,如何把这“一包”以字节为单位的数组“还原”成相同的结构体变量,以便在程序处理中也能直接按“结构体的方式”处理某个具体的成员,这时就涉及到结构体指针的应用。 什么是“作为结构体数据在涉及函数时的参数入口”?结构体数据一般内部包含了很多成员,当要把这一包数据传递给某个函数内部时,这个函数要给结构体数据预留参数入口,这时,如果函数以结构体成员的角度来预留入口,那么有多少个成员就要预留多少个函数的参数入口,可阅读性非常差,操作起来也麻烦。但是,如果以指针的角度来预留入口,那么不管这个结构体内部包含多少个成员,只需要预留一个指针参数入口就够用了,这就是绝大多32位单片机的库函数都采样结构体指针作为函数的参数入口的原因。 结构体指针这两个重要用途后续章节会深入讲解,本节的重点是先让大家学会结构体指针的基础知识,为后续章节做准备。 【72.2 结构体指针的基础。】 操作结构体内部某个具体变量时,有两种方式,一种是成员调用的方式,另一种是指针调用的方式。C语言语法为了区分这两种方式,专门设计了两种不同的操作符号。成员调用方式采样小数点“.”的符号,指针调用方式采用箭头“->”的符号。例子如下: struct StructMould\_1 { unsigned char u8Data\_A; unsigned long u32Data\_B; }; struct StructMould\_1 GtMould\_1; //“生成”一个变量。 //占用5个字节。 struct StructMould\_1 \*ptMould\_1; //定义一个结构体指针。 //占用3个字节。 void main() //主函数 { GtMould\_1.u8Data\_A=5; //“成员调用”的方式,用小数点符号“.” ptMould\_1=&GtMould\_1; //ptMould\_1指针与变量GtMould\_1建立关联。 ptMould\_1->u8Data\_A=ptMould\_1->u8Data\_A+5; //“指针调用”的方式,用箭头符号“->” while(1) { } } 分析:上述例子中,信息量很大,知识点有两个。 第一个知识点:为什么结构体变量GtMould\_1占用5个字节,而结构体指针\*ptMould\_1只占用3个字节?结构体变量GtMould\_1所占的内存是由结构体成员内部的数量决定的,而结构体指针\*ptMould\_1是由C编译器根据芯片硬件寻址范围而决定的,在一个相同的C编译器系统中,所有类型的指针所占用的字节数都是一样的,比如在本教程中所用8位单片机的C51编译器系统中,unsigned char \*,unsigned int \*,unsigned long \*,以及本节的struct StructMould\_1 \*,都是占用3个字节。32位单片机的指针往往都是4个字节,而某些64位的PC机,指针可能是8个字节,这些内容大家只要有个大概的了解即可。 第二个知识点:结构体成员GtMould\_1.u8Data\_A经过第一步的“成员调用”直接赋值5,紧接着经过“指针调用”的累加5操作,最后GtMould\_1.u8Data\_A的数值是10(5+5)。 【72.3 例程练习和分析。】 现在编写一个练习的程序: /\*---C语言学习区域的开始。-----------------------------------------------\*/ struct StructMould\_1 { unsigned char u8Data\_A; unsigned long u32Data\_B; }; struct StructMould\_1 GtMould\_1; //“生成”一个变量。 //占用5个字节。 struct StructMould\_1 \*ptMould\_1; //定义一个结构体指针。 //占用3个字节。 void main() //主函数 { GtMould\_1.u8Data\_A=5; //“成员调用”的方式,用小数点符号“.” ptMould\_1=&GtMould\_1; //ptMould\_1指针与变量GtMould\_1建立关联。 ptMould\_1->u8Data\_A=ptMould\_1->u8Data\_A+5; //“指针调用”的方式,用箭头符号“->” View(sizeof(GtMould\_1)); //在电脑端观察变量GtMould\_1占用多少个字节。 View(sizeof(ptMould\_1)); //在电脑端观察指针ptMould\_1占用多少个字节。 View(GtMould\_1.u8Data\_A); //在电脑端观察结构体成员GtMould\_1.u8Data\_A的最后数值。 while(1) { } } /\*---C语言学习区域的结束。-----------------------------------------------\*/ 在电脑串口助手软件上观察到的程序执行现象如下: 开始... 第1个数 十进制:5 十六进制:5 二进制:101 第2个数 十进制:3 十六进制:3 二进制:11 第3个数 十进制:10 十六进制:A 二进制:1010 分析: 变量GtMould\_1占用5个字节。 指针ptMould\_1占用3个字节。 结构体成员GtMould\_1.u8Data\_A的最后数值是10。 【72.4 如何在单片机上练习本章节C语言程序?】 直接复制前面章节中第十一节的模板程序,练习代码时只需要更改“C语言学习区域”的代码就可以了,其它部分的代码不要动。编译后,把程序下载进带串口的51学习板,通过电脑端的串口助手软件就可以观察到不同的变量数值,详细方法请看第十一节内容。