51单片机之C语言-4.1数据类型

这个不就是表示3了吗?也就是说,如果你要放这个数,我把这个数先转成二进制形式(可以直接使用电脑自带的计算机来转换),然后找单片机的存储器要2个格子放进去1或者0就行了。这样理解对不对呢?不对。你向单片机要格子的时候,单片机要么给你8个格子,要么16个,也就是8整数倍。为什么是这样?因为单片机存储器的最小单元是一个字节(8位).也就是说,即便你只想放一个数字1,单片机也会给你8个格子。这里我们可以这样来理解存储器:
本文引用地址:https://www.eepw.com.cn/article/201611/319550.htm
每一行8个单元格,每个单元格能放0或者1.ROM由很多个这样的单元格组成。具体的我们后面再讲。于是这样我们存放3,30,40,120等等就容易了,都是放在同一行的单元格中。这样每一行能存放的大小范围为0-255.也就是说在0-255直接任意大小的数据都很好存储了。像这样的数据我们就叫char型。但是又有了个问题,如果我要存放-3这个负数,怎么办?我们说过这些单元格只能放1或者0,不能放负号进去,怎么办?于是我们想了个办法,就从8个单元格中取一个出来,用0表示正,1表示负。取哪一个单元格,最高位也就是最左边的那个为最高位。假如我现在在最高位放一个1,那么单片机怎么知道这个最高位是1还是表示负数,比如:
1111_0110这个是多少,246还是-118,怎么区别?看看我们是怎么告诉单片机的,
unsignedchar 表示最高位为数字,signed char表示最高位为正负。
好了,问题来了。如何我现在要存放256怎么办?8个单元格肯定不够用了,需要9个单元格,前面说了,要么8个单元格,要么16个单元格,单片机不给你9个单元格,这样我们只好用16个单元格,即使只用了9个单元格,有点浪费. 这16个格子就表示int整型。同样的,正负也是占用最高位的一个格子,unsigned int 表示最高位的单元格是数字,signed int最高单元格表示正负。举个例子:65367

如果是unsigned int,则表示65367
如果是signed int,表示-32599
很容易的可以算出,unsigned int的范围:0-65535
signedint的范围: -32768 – 32767
现在我们知道了8个单元格就是char,16单元格就是int(范围限于本单片机).那么有没有24个单元格呢?没有,只有32个格子,这个是固定的。32格子就是长整型了,用long表示。同样的,可以知道,
unsignedlong 范围:0 – 4294967295,
signedlong 范围:-2147483648 – 2147483647
通过以上的分析,我们可以知道,如果要使用的数据只需要占用8个格子,就没有必要占用16个格子,这样可以节省存储空间。
另外这里补充两个程序中经常用到的两个指令 define和typedef
1. 无参宏定义
#define 标志符 字符串
其中的"#"表示这是一条预处理命令。凡是以"#"开头的均为预处理命令。"标志符"为所定义的宏名。"字符串"可以是常数,表达式,格式串等。
例如:
#define M (y*y+3*y)
它的作用是指定标志符M来代替表达式(y*y+3*y). 在编写源程序时,所有的(y*y+3*y)都可由M代替。
注意#define M(y*y+3*y)后面不可以有分号";",否则M将分号一起替换
2. 类型定义符typedef
C语言不仅提供了丰富的数据类型,而且还允许由用户自己定义类型说明符,也就是说允许由用户为数据类型取"别名"。类型定义符typedef即可用来完成此功能。typedef定义的一般形式为:typedef 原类型名 新类型名例如 typedef char NAME[20];表示Name是字符数组类型,数组长度为20,注意后面带有分号。然后可以用NAME说明变量,如:NAME a1, a2, s1,s2;完全等效于:char a1[20], a2[20],s1[20],s2[20]宏定义define与类型说明符typedef的区别在单片机编程中我们经常看到:#define uchar unsigned char#define uint unsigned int也可以使用typedef来定义:typtedef unsigned char uchar;typedef unsigned int uint;但是碰到如下情况就不能互换了,#define PIN1 int *typedef (int *) PIN2;从形式上看这两者相似,但在实际使用中却不相同。下面用PIN1,PIN2说明变量时就可以看出它们的区别:PIN1 a, b;在宏代换后变成:int *a,b;表示a是指向整形的指针变量,而b是整型变量。然而:PIN2 a,b;表示a,b都是指向整型的指针变量。因为PIN2是一个类型说明符。由这个例子可见,宏定义虽然也可表示数据类型,但毕竟是作为字符代换。在使用时要非常小心,以避免出错。以上我们概述了数据类型,现在我们各举一个例子说明,例1 比较unsigned char; unsigned int; unsigned long 占用存储空间的大小运行程序之前需要设置keil优化等级,将优化等级设置为0过程如下:在keil界面-> project->Options for target target 1...点击C51,选择Level为0
代码如下:
#include "reg52.h"
sbit LED0=P1^3;
void main(void)
{
unsigned char i;
i=0x30;
LED0=i;
while(1);
}
//输出结果信息 Program Size: data=10.0 xdata=0 code=27
#include "reg52.h"
sbit LED0=P1^3;
void main(void)
{
unsigned int i;
i=0x30;
LED0=i;
while(1);
}
//Program Size: data=11.0 xdata=0 code=32
#include "reg52.h"
sbit LED0=P1^3;
void main(void)
{
unsigned long i;
i=0x30;
LED0=i;
while(1);
}
//Program Size: data=13.0 xdata=0 code=46
//unsigned char: Program Size: data=10.0 xdata=0 code=27//unsigned int: Program Size: data=11.0 xdata=0 code=32//unsigned long:Program Size: data=13.0 xdata=0 code=46可见同样一个数据0x30, 使用不同的数据类型定义,将占据不同的存储空间例2 define的使用
#include "reg52.h"
#define uchar unsigned char //注意后面没有分号
sbit LED0=P1^3;
void main(void)
{
uchar i;
i=0x30;
LED0=i;
while(1);
}
例3 typedef的使用
#include "reg52.h"
typedef unsigned char uchar;//注意后面有分号
sbit LED0=P1^3;
void main(void)
{
uchar i;
i=0x30;
LED0=i;
while(1);
}
评论