新闻中心

EEPW首页>嵌入式系统>设计应用> 51单片机之C语言-4.1数据类型

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

作者: 时间:2016-11-21 来源:网络 收藏
从这一章起我们开始学习单片机C语言,既然是语言那么就应该有基本词汇和相关的语法。我们先来看看数据类型。讲数据之前先简单说说单片机的存储结构。我们知道单片机要运行之前,我们需要给他写指令,指令存放在ROM存储器上。我们再细想一下,既然存放在ROM上,那么我们来想一个问题,比如我的指令中有个数字‘3’要,这个‘3’是怎么存放的?相信这个很容易,单片机中存放的都是二进制,那么首先要转成二进制11B,格式如下:

这个不就是表示3了吗?也就是说,如果你要放这个数,我把这个数先转成二进制形式(可以直接使用电脑自带的计算机来转换),然后找单片机的存储器要2个格子放进去1或者0就行了。这样理解对不对呢?不对。你向单片机要格子的时候,单片机要么给你8个格子,要么16个,也就是8整数倍。为什么是这样?因为单片机存储器的最小单元是一个字节(8位).也就是说,即便你只想放一个数字1,单片机也会给你8个格子。这里我们可以这样来理解存储器:

本文引用地址://m.amcfsurvey.com/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"

sbitLED0=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);

}



评论


技术专区

关闭