从单片机基础到程序框架(全集 2019pdf版).pdf - 第315页

} /*---C 语言学习区 域的结束。 ----- ----------- ---------- ----------- ---------- */ 在电脑串口 助手软件上观 察到的程序执 行现象 如下: 开始... 第 1 个数 十进制:5 十六进制:5 二进制:101 第 2 个数 十进制:3 十六进制:3 二进制:11 第 3 个数 十进制:10 十六进制:A 二进制:101 0 分析: 变量 Gt Mould_1 占用 5 个…

100%1 / 836
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 习板,通过电脑端的串口助手软件就可以观
察到不同的变量数值,详细方法请看第十一节内容。
第七十三节: 结构体数据的传输存储和还原。
【73.1 结构体数据的传输存储和还原。
结构体本质是一个数组数组内可能包含了许多不同数据长度类型的成员,当整个结构体数据需要存
或者传输(通信)给另外一个单片机时,这时候有两种选择一种是一个成员一个成员的挨个处理,这种“以
成员为单位”的处理方式比较繁琐麻烦,另外一种是把整个结构体变量当作一个“以字节为单位”的普通数
组来处理,但是有两个关键的问题来了,第一个问题是如何把结构体“拆分”成“以字节为单位”来进行搬
动数据,第二个问题是假如我们把整个结构体数据“字节为单位的方式“整体打包”传递给另外一个单
片机,当这个接收方的单片机接收到我们这一组数据后,如何把这“一包”以字节为单位的数组再“还原”
成相同的结构体变量,以便在程序处理中也能直接按“结构体的方式”来处理某个具体的成员。其实这两
个问题都涉及到“指针的强制转换”。具体讲解的例子,请直接阅读下面 73.2 段落的源代码例子和注释。
【73.2 例程练习和分析。
现在编写一个练习程序把一个结构体变量“以字节的方式”存储到另外一个普通数组里然后再把这
个“以字节为单位”的普通数组“还原”成“结构体的方式”,以便直接操作内部某个具体的成员。
/*---C 语言学习区域的开始。-----------------------------------------------*/
struct StructMould_1
{
unsigned char u8Data_A;
unsigned long u32Data_B;
unsigned int u16Data_C;
};
struct StructMould_1 GtMould_1; //“生成”一个变量。
unsigned char Gu8Buffer[sizeof(GtMould_1)]; //定义一个内存跟结构体变量大小一样的普通数组
unsigned char *pu8; //定义一个把结构体变量“拆分”成“以字节为单位”的指针
struct StructMould_1 *ptStruct; //定义一个结构体指针,用于“还原”普通数组为“结构体
unsigned int i; //定义一个用于 for 循环的变量
void main() //主函数
{
//先把该结构体变量内部具体成员分别以“成员的方式”初始化为 5,6,7
GtMould_1.u8Data_A=5;
GtMould_1.u32Data_B=6;
GtMould_1.u16Data_C=7;
pu8=(unsigned char *)&GtMould_1; //把结构体变量强制转换成“以字节为单位”的指
for(i=0;i<sizeof(GtMould_1);i++)
{