420 likes | 575 Views
第 3 章 C 语言基本语法. #include <reg52.h> // 包含文件 #include <stdio.h> void main(void) // 主函数 { SCON=0x52; TMOD=0x20; TH1=0xf3; TR1=1; // 此行及以上 3 行为 PRINTF 函数所必须
E N D
第3章 C语言基本语法 • #include <reg52.h> //包含文件 • #include <stdio.h> • void main(void) //主函数 • { • SCON=0x52; • TMOD=0x20; • TH1=0xf3; • TR1=1; //此行及以上 3 行为PRINTF 函数所必须 • printf(“Hello I am KEIL. \n”); //打印程序执行的信息 • printf(“I will be your friend.\n”); • while(1); • }
3.1 C 语言的标识符和关键字 用来标识变量名、符号常量名、函数名、 数组名、类型名等的有效字符序列称为 标识符。简单地说,标识符就是一个名字。 C 语言规定标识符只能由字母、数字和下划线三种 字符组成,且第一个字符必须为字母或下划线,要 注意的是C 语言中大写字母与小写字母被认为是两 个不同的字符
例: Char char PI pi abc123 _abc123 123abc abc_123
3.2 数据类型 数据——具有一定格式的数字或数值叫数据 数据类型——数据的不同格式叫做数据类型。 数据结构——数据按一定的数据类型进行的排列、组合及架构称为数据结构。 C51提供的数据结构是以数据类型的形式出现的,C51的数据类型如下所示: 位型(bit) 字浮型(char) 整型(int) 基本类型: 长整型(long) 浮点型(float) 双精度浮点型(double) 数据类型: 数组类型(array) 构造类型: 结构体类型(struct) 共用体(union) 枚举(enum) 指针类型: 空类型:
3.2.1 常量 常量——在程序运行的过程中,其值不能改变的量称为常量。 常量的数据类型只有整型、浮点型、字符型、字符串型和位标量。 #define CONST 60 #define PI 3.1415926 好处: 1、见名知意 2、改一全变
字符型常量 \o \n \r \t \b \\ 字符串常量 “test” “\\abc\\”
3.2.2 变量 变量——在程序运行中,其值可以改变的量称为变量。 一个变量主要由两部分构成:一个是变量名,一个是 变量值。每个变量都有一个变量名,在内存中占据一 定的存储单元(地址),并在该单元中存放该变量的值。 1.位变量(bit)——变量的类型是位,位变量的值可以是1(true)或0(false)。 bit flag; 2.字符变量(char)——字符变量的长度为1字节(Byte)即8位。 3.整型变量(int)——整型变量的长度为16位,长度为两个字节, 用于存放一个双字节数据。 4. long 长整型变量 long 长整型长度为四个字节,用于存放一个四字节数据。 5.浮点型变量(float)——浮点型变量为32位,占4字节。
6.* 指针型变量 指针型本身就是一个变量,在这个变量中存放的 指向另一个数据的地址。 7. sfr 特殊功能寄存器 sfr 也是一种扩充数据类型,点用一个内存单元, 值域为0~255。 8.sfr16 16 位特殊功能寄存器 sfr16 占用两个内存单元,值域为0~65535。 9. sbit 可寻址位 sbit 同位是C51 中的一种扩充数据类型,利用它可以访问 芯片内部的RAM中的可寻址位或特殊功能寄存器中的可寻 址位。 Sbit flag=0x20^1; Sbit flag=wo^1; Sbit flag=0x00h;
3.2.3 变量的存储种类 按变量的有效作用范围可以将其划分为局部变量和全局变量; 还可以按变量的的存储方式为其划分存储种类。在C语言中 变量有四种存储种类,即自动(auto)、外部(extern)、静态 (static)和寄存器(register)。这四种存储种类与全局变量和局 部变量之间的关系如图3.2所示 自动变量(auto) 内部变量(inner) 静态变量(static) 寄存器变量(register) 变量 全局变量(global) 外部变量(extern) 静态变量(static)
1、自动变量(auto) 定义一个变量时,在变量名前面加上存储种类说明符“auto”, 即将该变量定义为自动变量。自动变量是C语言中使用最为 广泛的一类变量。 auto int high; int high;
自动变量的作用范围在定义它的函数体或复合语句内部,自动变量的作用范围在定义它的函数体或复合语句内部, 只有在定义它的函数内被调用,或是定义它的复合语句 被执行时,编译器才为其分配内存空间,开始其生存期。 当函数调用结束返回,或复合语句执行结束时,自动变 量所占用的内存空间就被释放,变量的值当然也就不复 存在,其生存期结束。 当函数被再次调用或复合语句被再次执行,编译器 又会为它们内部的自动变量重新分配内存空间,但它不 会保留上次运行时的值,而必须被重新赋值。因此自动 变量始终是相对于函数或复合语句的局部变量。
2、外部变量(extern) 使用存储种类说明符“extern”定义的变量称为外部变量。 按照缺省规则,凡是在所有函数之前,在函数外部定义的变量都是外部变量,定义时可以不写extern说明符。 在一个函数体内说明一个已在该函数体外或别的程序模块文件中定义过的外部变量时,则必须要使用extern说明符。
个外部变量被定义之后,它就被分配了固定的内存空间。个外部变量被定义之后,它就被分配了固定的内存空间。 外部变量的生存期为程序的整个执行时间,即在程序的 执行期间外部变量可被随意使用,当一条复合语句执行 完毕或是从某一个函数返回时,外部变量的存储空间并 不被释放,其值也仍然保留。因此外部变量属于全局变 量。 例4-2
3、静态变量(static) 使用存储种类说明符“static”定义的变量称为静态变量。在例4-2的模块2程序文件中使用了一个静态变量:static int a=5;由于这个变量是在函数funl()内部定义的,因此称为内部静态变量或局部静态变量。局部静态变量不象自动变量那样只有当函数调用它时才存在,退出函数后它就消失,局部静态变量始终都是存在的,但只能在定义它的函数内部进行访问,退出函数之后,变量的值仍然保持,但不能进行访问。还有一种全局静态变量,它是在函数外部被定义的,作用范围从它的定义点开始,一直到程序结束。
当一个C语言程序由若干个模块文件所组成时,全局静态变量始当一个C语言程序由若干个模块文件所组成时,全局静态变量始 终存在,但它共能在被定义的模块文件中访问,其数据值可为 该文件内的所有函数共享,退出该文件后,虽然变量的值仍然保 持着,但不能被其它模块文件访问。局部静态变量是一种在两次 函数调用之间仍能保持其值的局部变量。有些程序需要在多次调 用之间仍然保持变量的值,使用自动变量无法实现这一点,使用 全局变量有时又会带来意外的副作用,这时就可采用局部静态变量。
4、寄存器变量(register) 为了提高程序的执行效率,C语言允许将一些使用频率最高的 那些变量,定义为能够直接使用硬件寄存器的所谓寄存器变量。 定义一个变量时在变量名前而冠以存储种类符号“register”即将 该变量定义成为了寄存器变量。 寄存器变量可以被认为是自动变量的一种,它的有效作用范围 也与自动变量相同。由于计算机中的寄存器是有限的,不能将 所有变量都定义成寄存器变量。通常在程序中定义的寄存器变 量时只是给编译器一个建议,该变量是否能真正成为寄存器变 量,要由编译器根据实际情况来确定。另一方面,c51编译器 能够识别程序中使用频率最高的变量,在可能的情况下,即使 程序中并未将该变量定义为寄存器变量,编译器也会自动将其 作为寄存器变量处理。
3.2.4 变量及其存储模式 一个变量应该有一个名字,在内存中占据一 定的存储单元,在该存储单元中存放变量的值。 在C 语言中,要求对所有用到的变量作强制定义, 也就是“先定义,后使用”。在C51中对变量进行 定义的格式如下: [存储种类] 数据类型 [存储器类型] 变量名表 存储模式如下: 存储模式决定了默认的存储器类型,此存储器 类型将应用于函数参数,局部变量和定义时未 包含存储器类型的变量。你可以在命令行用 SMALL,COMPACT和LARGE参数定义存储 模式。定义变量时,使用存储器类型显式定义 将屏蔽默认存储器类型。
1.小(SMALL)模式 所有变量都默认在8051的内部数据存储器中。这和 用data显式定义变量起到相同的作用 2.紧凑(COMPACT)模式 此模式中,所有变量都默认在8051的外部数据存储器的一页中。 3.大(LARGE)模式 在大模式下,所有的变量都默认在外部存储器中(xdata)。 需要特别指出的是,变量的存储种类与存储器类型是完全无关的。 为了能够直接访问这些特殊功能寄存器 ,C51编译器扩充了关 键字sfr和sfrl6,利用这种扩充关键字可以在C语言源程序中直 接对805l单片机的特殊功能寄存器进行定义。定义方法如下: sfr特殊功能寄存器名=地址常数; 例如:sfr P0=0x80;/* 定义I/O口P0,其地址为80H */
3.3 用typedef重新定义数据类型 在C语言程序中除了可以采用上面所介绍的 数据类型之外,用户还可以根据自己的需要 对数据类型重新定义。重新定义时需用到关 键字typedef,定义方法如下: typedef 已有数据类型 新的数据类型名; 其中“已有的数据类型”是指上面所介绍的 C语言中所有的数据类型,包括结构、指针 和数组等,“新的数据类型名”可按用户自己 的习惯或根据任务需要决定。关键字typedef 的作用只是将C语言中已有的数据类型作了 置换,因此可用置换后的新数据类型名来进 行变量的定义。
如: • typedef unsigned char uchar; • typedef char * POINTER; • POINTER point;
3.4 运算符与表达式 运算符就是完成某种特定运算的符号。运算符按其在 表达式中所起的作用,可分为赋值运算符、算术运算 符、增量与减量运算符、关系运算符、逻辑运算符、 位运算符、复合赋值运算符、逗号运算符、条件运算 符、指针和地址运算符、强制类型转换运算符和 sizeof运算符等。运算符按其在表达式中与运算对象 的关系可分为单目运算符,双目运算符和三目运算符。 单目就是指需要有一个运算对象,双目就要求有两个 运算对象,三目则要三个运算对象。表达式则是由运 算及运算对象所组成的具有特定含义的式子。C是一 种表达式语言,表达式后面加“;”号就构成了一个表 达式语句
1、赋值运算符:变量 = 表达式; 2. 算术运算符 + 加或取正值运算符 - 减或取负值运算符 * 乘运算符 / 除运算符 % 取余运算符 3. 增量和减量运算符 十十 增量运算符 (++i,i++) —一 减量运算符 (一一j,j一一 ) 4. 关系运算符 “<”(小于)、“<=”(小于等于)、“>”(大于)、“>=(大于等于)” 、“==”(等于)和“!=”(不等于)。 5. 逻辑运算符 “&&”(逻辑与)、“||”(逻辑或)和“!”(逻辑非)。 6. 位运算符 ~ 按位取反、& 按位与、| 按位或、^ 按位异或、<< 左移、>> 右移
7. 复合赋值运算符 += 加法赋值 >>= 右移位赋值 -= 减法赋值 &= 逻辑与赋值 *= 乘法赋值 |= 逻辑或赋值 /= 除法赋值 ^= 逻辑异或赋值 %= 取模赋值 -= 逻辑非赋值 <<= 左移位赋值 8. 逗号运算符 在C语言中逗号是一种特殊的运算符,也就是 逗号运算符,可以用它将两个或多个表达式连 接起来,形成逗号表达式。逗号表达式的一般形式为: 表达式1,表达式2,表达式3……表达式n 用逗号运算符组成的表达式在程序运行时, 是从左到右计算出各个表达式的值,而整个用 逗号运算符组成的表达式的值等于最右边表达式 的值,就是"表达式n"的值。
9. 条件运算符 条件运算符“?:”是C 语言中唯一的一个三目运算符. 条件表达式的一般形式如下: 逻辑表达式 ? 表达式1:表达式2 条件运算符的作用简单来说就是根据逻辑表达式的 值选择使用表达式的值。当逻辑表达式的值为真时 (非0值)时,整个表达式的值为表达式1的值;当 逻辑表达式的值为假(值为0)时,整个表达式的值 为表达式2的值。
10. 指针与地址运算符: C语言提供了两个专门的运算符: *取内容; & 取地址 变量= * 指针变量 指针变量= & 目标变量 取内容运算是将指针变量所指向的目标变量 的值赋给左边的变量;取地址运算是将目标 变量的地址赋给左边的变量。
11. 强制类型转换运算符 C语言中的“()”就是强制类型转换运算符,它的 作用是将表达式或变量的类型强制转换成为 所指定的类型。 强制类型转换运算符的一般使用形式为: (类型)=表达式 显式类型转换在给指针变量赋值时特别有用。 例如,预先在8051单片机外部数据存储器(xdata) 中定义了一个字符型指针变量px,如果想给这个 指针变量赋一初值oxB000,可以写成: px=(char xdata*)oxB00; 这种方法特别适合于用标识符来存取绝对地址。
12. sizeof 运算符 C语言提供了一种用于求取数据类型、变量 以及表达式的字节数的运算符:sizeof,该运算 符的一般使用形式为: Sizeof (表达式) 或sizeof (数据类型) 应该注意的是,sizeof是一种特殊的运算符, 不要错误地认为它是一个函数。实际上, 字节数的计算在程序编译时就完成了,而不 是在程序执行的过程中才计算出来的。
3.5 C程序设计的基本语句 3.5.1 表达式语句 C语言是一种结构化的程序设计语言。 C语言提供了相当丰富的程序控制语句。 表达式语句是最基本的一种语句。 在表达式后面加入分号“;”就构成表达式语句。 在C语言中有一个特殊的表达式语句, 称为空语句, 它仅仅是由一个分号“;”组成。
3.5.2 复合语句 由若干条语句组合而成的语句就叫复合语句。 复合语句之间用{}分隔,而它内部的各条语 句还是需要以分号“;”结束。复合语句的一般形式为: { 局部变量定义; 语句1; 语句2; 语句n; } 复合语句是允许嵌套的,也是就是在{}中的{}也是复合语句。 复合语句在程序运行时,{}中的各行单语句是依次顺序执行的。 以C语言中可以将复合语句视为一条单语句,也就是说在 语法上等同于一条单语句。
3.5.3 条件语句 条件语句又被称为分支语句,其关键字是由if构成。 C语言提供3种形式的条件语句: 1.if (条件表达式) 语句 当条件表达式的结果为真时,就执行语句,否则就跳过。 2.if (条件表达式) 语句1 else 语句2 当条件表达式成立时,就执行语句1,否则就执行语句2 3.if (条件表达式1) 语句1 else if (条件表达式2) 语句2 else if (条件表达式3) 语句3 else if (条件表达式m) 语句n else 语句m
3.5.4 开关语句 开关语句是实现多方向条件分支的语句, 其关键字是switch.它的一般形式如下: switch (表达式) switch (表达式) { case 常量表达式1: 语句1; break; case 常量表达式2: 语句2; break; case 常量表达式3: 语句3; break; case 常量表达式n: 语句n; break; default: 语句 }
运行中switch后面的表达式的值将会做为条件, 与case后面的各个常量表达式的值相对比, 如果相等时则执行后面的语句,再执行break (间断语句)语句,跳出switch语句。如果 case没有和条件相等的值时就执行default后 的语句。当要求没有符合的条件时不做任何 处理,则可以不写default语句。
3.5.5 循环语句 循环语句是几乎每个程序都会用到的,它的 作用就是用来实现需要反复进行多次的操作。 在C语言中构成循环控制的语句有 while,do-while,for和goto语句。一般形式如下: 1.while 语句; While 语句用到实现“当型”循环结构,其一般形式如下: while(表达式) 语句; 当表达式为非0 值(真)时,执行while 语句中的内嵌 语句。其特点是:先判断表达式,后执行语句。
2.do-while 语句; do-while 语句用来实现“直到型”循环, 特点是先执行循环体, 然后判断循环条件是否成立。 其一般形式如下: do 循环体语句 while(表达式);
3.for 语句; C语言中的for 语句使用最为灵活,不仅可以用 于循环次数已经确定的情况,而且可以用于循 环次数不确定而只给出循环结束条件的情况。 for 语句的一般形式为: for(表达式1;表达式2;表达式3) 语句 它的执行过程是: (1) 先求解表达式1 (2) 求解表达式2,其值为真,则执行for 语 句中指定的内嵌语句(循环体),然后执行 第(3)步,如果为假,则结束循环。 (3) 求解表达式3
(4) 转回上面的第(2)步继续执行。 for 语句典型的应用是这样一种形式: for(循环变量初值;循环条件;循环变量增值) 语句 如果变量初值在for 语句前面赋值,则for 语句中的表达式1 应省略,但其后的分号不能省略。表达式2 也可以省略,但是同样不能省略其后的分号,如果省略该式,将不判断循环条件,循环无终止地进行下去,也就是认为表达式始终为真。表达式3 也可以省略,但此时编程者应该另外设法保证循环能正常结束。
4.goto 语句 goto 语句是一个无条件转向语句,它的一般形式为: goto 语句标号; 其语句标号是个带冒号的标识符。 常见的是在C程序中采用goto 语句来跳出多重循环。
C 语言中的三种循环语句可以相互嵌套。 在一个循环程序中,可以通过循环语句中的表达式 来控制循环程序是否结束,除此之外,还可以通过 break 语句和continue 语句强行退出循环结构。 Continue 语句和break 语名的区别是:continue 语句只结束本次循环,而不是终止整个循环的 执行;而break 语句则是结束整个循环过程, 不会再去判断循环条件是否满足。
3.5.6 返回语句 返回语句用于终止函数的执行,并控制程序返回到调 用该函数时所处的位置。返回语句有两种形式: return(表达式);或者return; 如果return语句后面带有表达式,则要计算表达式 的值,并将表达式的值作为该函数的返回值。若使用 不带表达式的第2种形式,则被调用函数返回主调用 函数时,函数值不确定。