ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
【26.1 连乘。】 上一节的乘法例子中,右边的乘数只有两个。实际上,C语言规则没有限制乘数的个数,它的通用格式如下: “保存变量”=“乘数1”\*“乘数2”...\*“乘数N”; 当右边的乘数个数超过两个的时候(这里暂时把平时所说的被乘数也归类为乘数),这种情况就是“连乘”。每个乘数的属性没有限定,可以是常量,也可以是变量。比如: unsigned char x=3; //定义一个变量x,初始化默认为3. unsigned char y=6; //定义一个变量y,初始化默认为6. unsigned char k=2; //定义一个变量k,初始化默认为2. a=2\*5\*3; //乘数全部是常量。a的结果为30。 b=k\*x\*y; //乘全部是变量。b的结果为36。 c=x\*5\*y; //乘数,有的是常量,有的是变量。c的结果为90。 连乘的运行顺序是,赋值符号“=”右边的乘数挨个相乘,把每一次的运算结果放在一个临时的隐蔽中间变量里,这个隐蔽的变量我们看不到,是单片机系统内部参与运算时的专用寄存器,等右边所有乘数连乘的计算结果出来后,再把隐蔽变量所保存的计算结果赋值给左边的“保存变量”。 【26.2 自乘与自乘简写。】 什么是自乘?当赋值符号“=”右边的乘数只要其中有一个是“保存变量”本身时,这种情况就是“自乘”,常见格式如下: “保存变量”=“保存变量”\*“乘数1”; “保存变量”=“保存变量”\*(“乘数1”\*“乘数2”...\*“乘数N”); 上述自乘计算式可以简写成如下格式: “保存变量”\*=“乘数1”; “保存变量”\*=“乘数1”\*“乘数2”...\*“乘数N”; 这种格式就是“自乘简写”。现在举几个例子如下: unsigned char d=5; //定义一个变量d,初始化默认为5. unsigned char e=5; //定义一个变量e,初始化默认为5. unsigned char f=5; //定义一个变量f,初始化默认为5. unsigned char x=3; //定义一个变量x,初始化默认为3. unsigned char y=6; //定义一个变量y,初始化默认为6. unsigned char k=2; //定义一个变量k,初始化默认为2. d\*=6; //相当于d=d\*6;最后d的结果为30。 e\*=x; //相当于e=e\*x;最后e的结果为15。 f\*=2\*y\*k; //相当于f=f\*(2\*y\*k);最后f的结果为120。 【26.3 有没有“自乘1”的特殊写法?】 之前在讲加法的自加和减法的自减运算时,还给大家介绍了它们另外一种特殊的简写方式。比如减法运算,当右边只有2减数,当一个减数是“保存变量”,另一个是常数1时,格式如下: “保存变量”=“保存变量”-1; 这时候,可以把上述格式简写成如下两种格式: “保存变量”--; \--“保存变量”; 这两种格式也是俗称的“自减1”操作。比如: g--; //相当于g=g-1或者g-=1; \--h; //相当于h=h-1或者h-=1; 那么,本节所讲的自乘运算,有没有“g\*\*”或者“\*\*h”这种特殊的“自乘1”写法?答案很明显,C语言里没有“自乘1”这种特殊写法。因为任何一个数“自乘1”还是等于它本身,所以在乘法运算中这种特殊写法就没有存在的意义。多说一句,如果某天有朋友在某个地方看到“\*\*h”这类语句,它的本意跟“自乘”没关系,而是跟C语言的另一块知识点“指针”有关。 【26.4 乘法的溢出。】 乘法的溢出规律跟加减法的溢出规律是一样的。举一个例子如下: unsigned char m=30; unsigned char n=10; unsigned char a; a=m\*n; 分析:m与n相乘,相当于30乘以10,运算结果是300(十六进制是0x012c)保存在一个隐藏中间变量,根据前面加减法运算的规律,我猜测这个隐藏中间变量可能是unsigned int类型,然后再把这个中间变量赋值给单字节变量a,a只能接收十六进制的低8位字节0x2c,所以运算后a的数值由于溢出变成了十六进制的0x2c(十进制是44)。由于乘法的溢出规律跟加减法的溢出规律是一样的,所以不再多举例子。在实际项目中,为了减少溢出的现象,我建议,不管加减乘除,凡是参与运算的变量全部都应该转化成unsigned long变量,转化的方法已经在前面章节讲过,不再重复讲解这方面的内容。 【26.5 例程练习和分析。】 现在编写一个程序来验证刚才讲到的连乘和自乘简写: 程序代码如下: /\*---C语言学习区域的开始。-----------------------------------------------\*/ void main() //主函数 { unsigned char a; unsigned char b; unsigned char c; unsigned char d=5; //定义一个变量d,初始化默认为5. unsigned char e=5; //定义一个变量e,初始化默认为5. unsigned char f=5; //定义一个变量f,初始化默认为5. unsigned char x=3; //定义一个变量x,初始化默认为3. unsigned char y=6; //定义一个变量y,初始化默认为6. unsigned char k=2; //定义一个变量k,初始化默认为2. //第1个知识点:连乘。 a=2\*5\*3; //乘数全部是常量。a的结果为30。 b=k\*x\*y; //乘数全部是变量。b的结果为36。 c=x\*5\*y; //乘数,有的是常量,有的是变量。c的结果为90。 //第2个知识点:自乘的简写。 d\*=6; //相当于d=d\*6;最后d的结果为30。 e\*=x; //相当于e=e\*x;最后e的结果为15。 f\*=2\*y\*k; //相当于f=f\*(2\*y\*k);最后f的结果为120。 View(a); //把第1个数a发送到电脑端的串口助手软件上观察。 View(b); //把第2个数b发送到电脑端的串口助手软件上观察。 View(c); //把第3个数c发送到电脑端的串口助手软件上观察。 View(d); //把第4个数d发送到电脑端的串口助手软件上观察。 View(e); //把第5个数e发送到电脑端的串口助手软件上观察。 View(f); //把第6个数f发送到电脑端的串口助手软件上观察。 while(1) { } } /\*---C语言学习区域的结束。-----------------------------------------------\*/ 在电脑串口助手软件上观察到的程序执行现象如下: 开始... 第1个数 十进制:30 十六进制:1E 二进制:11110 第2个数 十进制:36 十六进制:24 二进制:100100 第3个数 十进制:90 十六进制:5A 二进制:1011010 第4个数 十进制:30 十六进制:1E 二进制:11110 第5个数 十进制:15 十六进制:F 二进制:1111 第6个数 十进制:120 十六进制:78 二进制:1111000 分析: 通过实验结果,发现在单片机上的计算结果和我们的分析是一致的。 【26.6 如何在单片机上练习本章节C语言程序?】 直接复制前面章节中第十一节的模板程序,练习代码时只需要更改“C语言学习区域”的代码就可以了,其它部分的代码不要动。编译后,把程序下载进带串口的51学习板,通过电脑端的串口助手软件就可以观察到不同的变量数值,详细方法请看第十一节内容。