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

第六十节: 指针在变量(或常量)中的基础知识。 【60.1 指针与普通变量的对比。 】 普通变量和 指针都是变 量, 都要占用 R AM 资源。 普通 变量的 unsi gned char 类型占用 1 个字节, unsi gned int 类型占用 2 个字 节, unsig ned long 类型占用 4 个字 节。 但是 指针不一样, 指针是一种 特殊的变量, u nsigned char*,unsi gned in t*,uns…

100%1 / 836
b 1。
c 24。
d 12。
e 3。
【59.9 如何在单片机上练习本章节 C 语言程序?】
直接复制前面章节中第十一节的模板程序,练习代码时只需要更改C 语言学习区域”代码就可以了,
其它部分的代码不要动。编译后,把程序下载进带串口 51 习板,通过电脑端的串口助手软件就可以观
察到不同的变量数值,详细方法请看第十一节内容。
第六十节: 指针在变量(或常量)中的基础知识。
【60.1 指针与普通变量的对比。
普通变量和指针都是变量,都要占用 RAM 资源。普通变量的 unsigned char 类型占用 1 个字节,unsigned
int 类型占用 2 个字节,unsigned long 类型占用 4 个字节。但是指针不一样,指针是一种特殊的变量,unsigned
char*,unsigned int*,unsigned long*这三类指针 C51 编译器下都是一样占用 3 个字节。不同系统的指针
到底占用多少字节是由 C 编译根据片的件寻范围决定,比 32 位单机的针往都是 4
个字节,而某些 64 位的 PC 机,指针可能是 8 个字节,这些内容大家只要有个大概的了解即可指针是普通
变量的载体,平时我们处理普通变量,都是可以“直接”操作普通变量本身。而学了指针之后,我们就多一
种选择,可以通过指针这个载体来“间接”操作某个普通变量“直接”不是比“间接”更好更高效吗?
什么要用“间接”?其实在某些场合,指针的“间接”操作更加灵活更加高效,这个要看具体的应用。
指针既然是普通变量的“载体”那么普通变量就是“物“载体”与“物”之间可以存在一对多的
系。也就是说,一个篮子(载体),可以盛放鸡蛋(物),也可以盛放青菜(物),也可以盛放水果(物)
但是,在这里,一个篮子在一个时间段内,只能承载一种物品如果想承载其它物品,必须先把当前物品“卸
下来,然后再“装”其它物品”这里有两个关键动作“装“卸”就是指针在处理普通变量时的“绑定
某个指针与某个变量发生“绑定”,就已经包含了先“卸”后“装”这两个动作在其中
题外话多说一句,刚才提到,unsigned int 类型占用 2 个字节,这个是 C51 编译器下的情况。如果
是在 stm32 单片机的编译器下,unsigned int 类型是占用 4 个字节。
【60.2 指针的定义。
跟普通变量一样,指针也必须先定义再使用。为了与普通变量区分开来,指针在定义的时候多加了一个
星号“*”,例子如下:
unsigned char* pu8; //针对 unsigned char 类型变量的指针。凡是指针都是占 4 个字节!
unsigned int* pu16; //针对 unsigned int 类型变量的指针。凡是指针都是 4 个字节!
unsigned long* pu32; //针对 unsigned long 类型变量的指针。凡是指针都是 4 个字节!
既然指针都是 4 个字节,为什么还要区分 unsigned char*,unsigned int* pu16,unsigned long* pu32
这三种类型?因为指针是为普通变(或常量)而生,所以要根据普通变量或常量)的类型定义对应的指
针。
【60.3 指针与普通变量是如何关联和操作的?】
指针在操作某个变量的时候,必须先跟某个变量关联起来,这里的关联就是“绑定“绑定”后,才可
以通过指针这个“载体”来“间接”操作变量。指针与普通变量在“绑定”的时候,需要用到“&”这个
号。例子如下:
unsigned char* pu8; //针对 unsigned char 类型变量的指针。凡是指针都是占 4 个字节!
unsigned char a=0; //普通的变量
pu8=&a; //指针与普通变量发生关联(或者说绑定
*pu8=2; //通过指针这个载体来处理 a 这个变量,此时 a 从原来的 0 变成了 2。
【60.4 指针处理“批量数据”的基础知识。
之所以有通过载体来“间接”操作普通变量的存在价值,其中很重要的原因是指针在处理“批量数据”
时特别给力,这里的“批量数据”是有条件的,要求这些数据的地址必须挨家挨户连起来的,不能是零零散
散的“散户”,比如说,数组就是由一堆 RAM 间里地址连续的变量组合而成,指针在很多时候就是为数
组而生的。先看一个例子如下:
unsigned char* pu8; //针对 unsigned char 类型变量的指针。凡是指针都是占 4 个字节!
unsigned char Buffer[3]; //普通的数组,内含 3 个变量,它们地址是相连的。
pu8=&Buffer[0]; //指针与普通变量 Buffer[0]发生关联(或者说绑定)
*pu8=1; //通过指针这个载体来处理 Buffer[0]这个变量,此时 Buffer[0]变成了 1。
pu8=&Buffer[1]; //指针与普通变量 Buffer[1]发生关联(或者说绑定)
*pu8=2; //通过指针这个载体来处理 Buffer[1]这个变量,此时 Buffer[1]变成了 2。
pu8=&Buffer[2]; //指针与普通变量 Buffer[2]发生关联(或者说绑定)
*pu8=3; //通过指针这个载体来处理 Buffer[2]这个变量,此时 Buffer[2]变成了 3。
分析:上述例子中,并没有体现出指针的优越性,因为数组有 3 个元素,居然要绑定了 3 次,如果数组
1000 个元素,难道要绑定 1000 次?显然这样是繁琐低效不可取的。而要发挥指针的优越性,我们现在必
须深入了解一下指针的本质是什么,指针跟普通变量发“绑定”的本质是什么普通变量由“地址”“地
址所装的数据”构成,指针是特殊的变量,它是由什么构成呢?其实,指针是由“地址”和“地址所装的变
量(或常量)的地址”组成。很明显,一个重要的区别是,普通变量装的数据,而指针装的是地址。正因为
指针装的是地址,所以指针可以有两种选择,第一种可以处理“装的地址第二种可以处理“装的地址的
所在数据”这两种能力,就是指针的精华和本质所在,也是跟普通变量的区别所在。那么指针处理“装
地址”的语法是什么样子的?请看例子如下:
unsigned char* pu8; //针对 unsigned char 类型变量的指针。凡是指针都是占 4 个字节!
unsigned char Buffer[3]; //普通的数组,内含 3 个变量,它们地址是相连的。
pu8=&Buffer[0]; //处理“装的地址”。把 Buffer[0]变量的地址装在指针这个载体里。
*pu8=1; //处理“装的地址的所在数据”。此 Buffer[0]变成了 1。
pu8++; //处理“装的地址”。这里是“地址”自加 1,相当于指针此时装的是 Buffer[1]的地址。
*pu8=2; //处理“装的地址的所在数据”。此 Buffer[1]变成了 2。
pu8++; //处理“装的地址”。这里是“地址”自加 1,相当于指针此时装的是 Buffer[2]的地址。
*pu8=3; //处理“装的地址的所在数据”。此 Buffer[2]变成了 3。
上述例子中利用“地址”自加 1 的操作,省去了 2 条赋值式的“绑定操作(比如 pu8=&Buffer[0]
这类语句)因此“绑定”本质其实就是更改指针所装的“变量(或常量)的地址”的操作。此例子中虽然
还没体现了出指针在数组处理时的优越性,但是利用指针处理“装的地址”这项功能,在实际项目中很容