在程序运转进程中,其值不克不及被改动的量称之为常量。常量分为分歧的类型,有整型常量如 1、2、3、100;浮点型常量 3.14、0.56、-4.8;字符型常量a、b、0;字符串常量“a”、“abc”、“1234”、“1234abcd”等。
仔细的同窗会发现,整型和浮点型常量我们直接写的数字,而字符型常量用单引号来表现一个字符,用双引号来表现一个字符串,特别人人要留意a和“a”是纷歧样的,这个等会我们要具体引见。
常量普通有两种表示方式:
成都创新互联公司是一家专业提供隆阳企业网站建设,专注与网站设计制作、网站设计、H5建站、小程序制作等业务。10年已为隆阳众多企业、政府机构等服务。创新互联专业网站设计公司优惠进行中。
直接常量:直接以值的方式表现的常量称之为直接常量。上述举例这些多是直接常量,直接写出来了。
符号常量:用标识符定名的常量称之为符号常量,就是为下面的直接常量再取一个名字。运用符号常量一是便利了解,进步程序可读性,更主要的是便利程序的后续保护,习气上符号常量我们都用大写字母和下划线来定名。
比方,我们可以把 3.14 取名为 PI(即π)。再比方,我们上节课的串口程序,我们用的波特率是 9600,假如用符号常量来停止提早声明的话,那我们要修正成其它速度的话,就不必在程序中找 9600 修正了,直接修正声明处就可以了,两种办法举例阐明。用 const 声明。比方我们在程序开端地位界说一个符号常量 BAUD。
界说方式是:
const 类型 符号常量名字=常量值;
如
const unsigned int BAUD = 9600; /*留意开头有个分号*/
我们就可以在程序中直接把 9600 改成 BAUD,如许我们假如要改波特率的话,直接在程序扫尾地位改一下这个值就可以了。用预处置敕令#define 来完成,预处置敕令我们先来看法#define。
界说方式是:
#define 符号常量名 常量值
如
#define BAUD 9600 /*留意开头没有分号*/
如许界说今后,只需在程序中呈现 BAUD 的话,意思就是完整替代了后边的 9600 这个数字。
不知人人能否记得,我们之前界说数码管真值表的时分,用了一个 code 症结字。
unsigned char code LedChar[] = { //数码管显示字符转换表 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E };
我们事先说加了 code 之后,这个真值表的数据只能被运用,不克不及被改动,假如我们直接写 LedChar[0] = 1;如许就错了。实践上 code 这个症结字是 51 单片机特有的,假如是其它类型的单片机我们只需求写成 const unsigned char LedChar[]={}就可以了,主动保管到 FLASH里,而 51 单片机只用 const 而不加 code 的话,这个数组会保管到 RAM 中,而不会保管到FLAHS 中,鉴于此,在 51 这集体系下,const 反倒变得不那么主要了,它的感化被 code 代替了,这里人人晓得这么回事即可。
我们来对各类类型的常量做进一步阐明。
整型常量和浮点型常量就没若干可说的了,之前我们使用的都很纯熟了,整型直接写数字就是十进制如 128,前边 0x 扫尾的表现是十六进制 0x80,浮点型直接写带小数点的数据就可以了。
字符型常量是由一对单引号括起来的单个字符。它分为两种方式,一种是通俗字符,一种是本义字符。
通俗字符就是那些我们可以直接书写直接看到的无形的字符,比方阿拉伯数字 0~9,英文字符 A~z,以及标点符号等。它们多是 ASCII 码表中的字符,而它们在单片机中都占用一个字节的空间,其值就是对应的 ASCII 码值。比方a的值是 97,A的值是 65,0的值是48,假如界说一个变量 unsigned char a = a,那么变量 a 的值就是 97。
除了上述这些字符以外,还有一些特别字符,它们一些是有形的,像回车符、换行符这些多是看不到的,还有一些像\”这类字符它们曾经有特别用处了,想象一下假如写 '''认为编译器会怎样去说明呢。针对这些特别符号,为了可以让它们正常进入到我们的程序代码中,C 言语就规则了本义字符,它是以反斜杠(\)扫尾的特定字符序列,让它们来表现这些特别字符,比方我们用\n 来代表换行。我们用一个复杂表格来阐明一下常用的本义字符的意思,如表 12-2 所示。
表 12-2 常用本义字符及寄义
字符方式 | 寄义 |
---|---|
\n | 换行 |
\t | 横向跳格(相当于 Tab) |
\v | 竖向跳格 |
\b | 退格 |
\r | 光标移到行首 |
\\ | 反斜杠字符\ |
\ | 单引号字符 |
\” | 双引号字符 |
\f | 走纸换页 |
\0 | 空值 |
表格不需求人人记住,用到了,过去查就可以了。
字符串常量是用双引号括起来的字符序列,普通我们都称之字符串。如“a”、“1234”、“welcome to www.kingst.org”等多是字符串常量。字符串常量在内存中按次序逐一存储字符串中的字符的 ASCII 码值,而且特殊留意,最初还有一个字符\0,\0字符的 ASCII 码值是 0,它是字符串完毕标记,在写字符串的时分,这个\0是隐蔽的,我们看不到,然则实践倒是存在的。所以“a”就比a多了一个 \0,“a”的就占了 2 个字节,而 a只占一个字节。
还有一 个地 方要注 意, 就是字 符串 中的空 格, 也是一 个字 符,比 如 “welcome to www.kingst.org”一共占了 26 个字节的空间。个中 21 个字母,2 个.,2 个 (空格字符)以及一个\0。
为了比照字符串、字符数组、常量数组的差别,我们写个了复杂的演示程序,界说了 4个数组辨别是:
unsigned char array1[] = "1-Hello!\r\n"; unsigned char array2[] = {'2', '-', 'H', 'e', 'l', 'l', 'o', '!', '\r', '\n'}; unsigned char array3[] = {51, 45, 72, 101, 108, 108, 111, 33, 13, 10}; unsigned char array4[] = "4-Hello!\r\n";
在串口调试助手下,发送十六进制的 1、2、3、4,运用字符方式显示的话,会辨别往电脑上送这 4 个数组中对应的谁人数组。我们只是在肇端地位做了辨别,其它均没有差别。人人可以比拟一下后果。
此外还要阐明一点,数组 1 和数组 4,数组 1 我们是发完好的字符串,而数组 4 我们仅仅发送数组中的字符,没有发完毕符号。串口调试助手用字符方式显示是没有差别的,然则人人假如改用十六进制显示,人人会发现数组 1 比数组 4 多了一个字节 \0 的 ASCII 值 00。
#includebit cmdArrived = 0; //敕令抵达标记,即接纳到上位机下发的敕令 unsigned char cmdIndex = 0; //敕令索引,即与上位机商定好的数组编号 unsigned char cntTxd = 0; //串口发送计数器 unsigned char *ptrTxd; //串口发送指针 unsigned char array1[] = "1-Hello!\r\n"; unsigned char array2[] = {'2', '-', 'H', 'e', 'l', 'l', 'o', '!', '\r', '\n'}; unsigned char array3[] = {51, 45, 72, 101, 108, 108, 111, 33, 13, 10}; unsigned char array4[] = "4-Hello!\r\n"; void ConfigUART(unsigned int baud); void main(){ EA = 1; //开总中缀 ConfigUART(9600); //设置装备摆设波特率为 9600 while (1){ if (cmdArrived){ cmdArrived = 0; switch (cmdIndex){ case 1: ptrTxd = array1; //数组 1 的首地址赋值给发送指针 cntTxd = sizeof(array1); //数组 1 的长度赋值给发送计数器 TI = 1; //手动方法启动发送中缀,处置数据发送 break; case 2: ptrTxd = array2; cntTxd = sizeof(array2); TI = 1; break; case 3: ptrTxd = array3; cntTxd = sizeof(array3); TI = 1; break; case 4: ptrTxd = array4; cntTxd = sizeof(array4) - 1; //字符串实践长度为数组长度减 1 TI = 1; break; default: break; } } } } /* 串口设置装备摆设函数,baud-通讯波特率 */ void ConfigUART(unsigned int baud){ SCON = 0x50; //设置装备摆设串口为形式 1 TMOD &= 0x0F; //清零 T1 的掌握位 TMOD |= 0x20; //设置装备摆设 T1 为形式 2 TH1 = 256 - (11059200/12/32)/baud; //盘算 T1 重载值 TL1 = TH1; //初值等于重载值 ET1 = 0; //制止 T1 中缀 ES = 1; //使能串口中缀 TR1 = 1; //启动 T1 } /* UART 中缀效劳函数 */ void InterruptUART() interrupt 4{ if (RI){ //接纳到字节 RI = 0; //清零接纳中缀标记位 cmdIndex = SBUF; //接纳到的数据保管到敕令索引中 cmdArrived = 1; //设置敕令抵达标记 } if (TI){ //字节发送终了 TI = 0; //清零发送中缀标记位 if (cntTxd > 0){ //有待发送数据时,持续发送后续字节 SBUF = *ptrTxd; //收回指针指向的数据 cntTxd--; //发送计数器递加 ptrTxd++; //发送指针递增 } } }