1、第第5 5章章 嵌入式嵌入式C C语言程序设计基础语言程序设计基础5.1 5.1 嵌入式嵌入式C C语言的预处理伪指令语言的预处理伪指令5.2 5.2 嵌入式嵌入式C C语言的基本数据类型语言的基本数据类型 5.3 5.3 程序的控制结构程序的控制结构 5.4 5.4 函函 数数 5.5 5.5 数组数组 5.6 5.6 指指 针针 5.7 5.7 构造数据类型构造数据类型 5.8 5.8 汇编语言与汇编语言与C/C+C/C+的混合编程的混合编程5.9 5.9 嵌入式嵌入式LinuxLinux下下C C语言编程语言编程文件的操作文件的操作5.1嵌入式嵌入式C语言的预处理伪指令语言的预处理伪指令
2、1 1文件包含伪指令文件包含伪指令文件包含伪指令可将头文件包含到程序中,文件包含伪指令可将头文件包含到程序中,头文件中定义的内容符号常量,复合变量原型、头文件中定义的内容符号常量,复合变量原型、用户定义的变量原型和函数的原型说明等。编用户定义的变量原型和函数的原型说明等。编译器编译预处理时用文件包含的正文件内容替译器编译预处理时用文件包含的正文件内容替换到实际程序中。换到实际程序中。(1 1)文件包含伪指令的格式)文件包含伪指令的格式#include#include .h;标准头文件;标准头文件#include#include“头文件名头文件名.h.h”;自定义头文件;自定义头文件#inclu
3、de#include 宏标识符宏标识符 5.1嵌入式嵌入式C语言的预处理伪指令语言的预处理伪指令(2 2)包含文件伪指令的说明)包含文件伪指令的说明 常在头文件名后用常在头文件名后用.h.h作为扩展名,可带或不作为扩展名,可带或不带路经。带路经。头文件可分为标准头文件和自定义头文件。头文件可分为标准头文件和自定义头文件。尖括号内的头文件为标准头文件,由开发环尖括号内的头文件为标准头文件,由开发环境或系统提供。境或系统提供。双引号内的头文件为用户自定义头文件。搜双引号内的头文件为用户自定义头文件。搜索时,首先在当前目录中搜索,其次按环境索时,首先在当前目录中搜索,其次按环境变量变量include
4、include指定的目录顺序搜索。指定的目录顺序搜索。搜索到头文件后,就将该伪指令直接用头文搜索到头文件后,就将该伪指令直接用头文件内容替换。件内容替换。5.1嵌入式嵌入式C语言的预处理伪指令语言的预处理伪指令例例5.1 5.1 标准头文件定义标准头文件定义#include#include#include#include string.hstring.h和和stdio.hstdio.h是标准头文件,按环境变量是标准头文件,按环境变量 includeinclude指定的目录顺序搜索指定的目录顺序搜索string.hstring.h和和stdio.hstdio.h。例例5.2 5.2 用户自定义头
5、文件定义用户自定义头文件定义#include#include“s3c2410-adc.hs3c2410-adc.h”s3c2410-adc.h s3c2410-adc.h头文件是用户自定义有关三星头文件是用户自定义有关三星s3c2410s3c2410的的ARMARM处理器的处理器的A/DA/D转换器各寄存器。转换器各寄存器。5.1嵌入式嵌入式C语言的预处理伪指令语言的预处理伪指令2 2宏定义伪指令宏定义伪指令宏定义伪指令分为:简单宏、参数宏、条件宏、预定义宏及宏定义伪指令分为:简单宏、参数宏、条件宏、预定义宏及宏释放。宏释放。(1 1)简单宏)简单宏格式如下:格式如下:#define#defi
6、ne 宏标识符宏标识符 宏体宏体 宏体是由单词序列组成。宏体超长时,允许使用续行符宏体是由单词序列组成。宏体超长时,允许使用续行符“”进行续行,续行符和其后的换行符进行续行,续行符和其后的换行符 n n 都不会进入宏体。都不会进入宏体。在定义宏时,应尽量避免使用在定义宏时,应尽量避免使用C C语言的关键字和预处理器语言的关键字和预处理器的预定义宏,以免引起灾难性的后果。的预定义宏,以免引起灾难性的后果。在源文件中,用预处理器伪指令定义过宏标识符之后,在源文件中,用预处理器伪指令定义过宏标识符之后,就可用宏标识编写程序。当源文件被预处理器处理时,每遇到就可用宏标识编写程序。当源文件被预处理器处理
7、时,每遇到该宏标识符,预处理器便将宏展为宏体。该宏标识符,预处理器便将宏展为宏体。5.1嵌入式嵌入式C语言的预处理伪指令语言的预处理伪指令(2 2)参数宏)参数宏格式如下:格式如下:#define#define 宏标识符(形式参数表)宏标识符(形式参数表)宏体宏体 形式参数表为逗号分割的形式参数。形式参数表为逗号分割的形式参数。宏体是由单词序列组成。宏体超长时,允许使用宏体是由单词序列组成。宏体超长时,允许使用续行符续行符“”进行续行,续行符和其后的换行符进行续行,续行符和其后的换行符 n n 都不会进入宏体。都不会进入宏体。使用参数宏时,形式参数表应换为同样个数的实使用参数宏时,形式参数表应
8、换为同样个数的实参数表,这一点类似于函数的调用。参数宏与函数参数表,这一点类似于函数的调用。参数宏与函数的区别在于参数宏的形参数表中没有类型说明符。的区别在于参数宏的形参数表中没有类型说明符。预处理器在处理参数宏时使用预处理器在处理参数宏时使用2 2遍宏展开。第遍宏展开。第1 1遍遍展开宏体,第展开宏体,第2 2遍对展开后的宏体用实参数替换形遍对展开后的宏体用实参数替换形式参数。式参数。例例5.3 5.3 在在LinuxLinux系统的系统的/include/asm-arm/arch-/include/asm-arm/arch-s3c2410/S3C2410.hs3c2410/S3C2410.
9、h头文件中定义了各头文件中定义了各Nand FlashNand Flash控制寄控制寄存器,其源代码如下:存器,其源代码如下:#definebNAND_CTL(Nb)_REG(0 x4e000000+(Nb)#define NFCONF bNAND_CTL(0 x00)#define NFCONF bNAND_CTL(0 x00)#define NFCMD bNAND_CTL(0 x04)#define NFCMD bNAND_CTL(0 x04)#define NFADDR bNAND_CTL(0 x08)#define NFADDR bNAND_CTL(0 x08)#define NFDA
10、TA bNAND_CTL(0 x0c)#define NFDATA bNAND_CTL(0 x0c)#define NFSTAT bNAND_CTL(0 x10)#define NFSTAT bNAND_CTL(0 x10)#define NFECC bNAND_CTL(0 x14)#define NFECC bNAND_CTL(0 x14)5.1嵌入式嵌入式C语言的预处理伪指令语言的预处理伪指令5.1嵌入式嵌入式C语言的预处理伪指令语言的预处理伪指令例例5.4 5.4 在在LinuxLinux下下ARM S3C2410XARM S3C2410X芯片的芯片的A/DA/D转换的驱动转换的驱动程序
11、的头文件程序的头文件s3c2410-adc.hs3c2410-adc.h中定义了下面三个宏。中定义了下面三个宏。#defineADC_WRITE(ch,prescale)(ch)16)&0 x7)#define ADC_WRITE_GETCH(data)(data)16)&0 x7)/*/*获得获得ADCADC通道号通道号*/#define ADC_WRITE_GETPRE(data)(data)&0 xff)#define ADC_WRITE_GETPRE(data)(data)&0 xff)/*/*获得获得ADCADC的预定标值的预定标值*/例例5.5 5.5 在在LinuxLinux下下
12、ARM S3C2410XARM S3C2410X芯片的芯片的A/DA/D转换的驱动程转换的驱动程序实现代码序实现代码s3c2410-adc.cs3c2410-adc.c中的系统资源和宏定义。中的系统资源和宏定义。#define DEVICE_NAME s3c2410-adc#define DEVICE_NAME s3c2410-adc“/*/*定义定义ADCADC设备的名字设备的名字*/#define ADCRAW_MINOR 1#define ADCRAW_MINOR 1 static int adcMajor=0;/*static int adcMajor=0;/*定义定义ADCADC设备
13、的主设备号设备的主设备号*/typedef struct typedef struct struct semaphore lock;/*struct semaphore lock;/*内核信号量,当多个用户程序同时内核信号量,当多个用户程序同时访问一个访问一个ADCADC控制器时,用控制器时,用lock lock 进行同步进行同步*/wait_queue_head_t wait;/*wait_queue_head_t wait;/*等待队列等待队列*/int channel;/*ADCint channel;/*ADC通道号通道号*/int prescale;/*int prescale;/*
14、预定标值预定标值*/ADC_DEV;ADC_DEV;5.1嵌入式嵌入式C语言的预处理伪指令语言的预处理伪指令static ADC_DEV adcdev;static ADC_DEV adcdev;#define START_ADC_AIN(ch,prescale)#define START_ADC_AIN(ch,prescale)do ADCCON=PRESCALE_EN|PRSCVL(prescale)|do ADCCON=PRESCALE_EN|PRSCVL(prescale)|ADC_INPUT(ch);ADC_INPUT(ch);ADCCON|=ADC_START;ADCCON|=AD
15、C_START;while(0while(0)/*设置设置S3C2410X的的ADC的通道为的通道为ch、预定标值为、预定标值为prescale*/PRESCALE_EN/PRESCALE_EN宏对应宏对应ARM S3C2410XARM S3C2410X芯片的芯片的A/DA/D转换控制寄转换控制寄存器的第存器的第1414位位 PRSCEMNPRSCEMN,即,即A/DA/D转换器预标器使能;转换器预标器使能;/PRSCVL/PRSCVL宏对应宏对应ARM S3C2410XARM S3C2410X芯片的芯片的A/DA/D转换控制寄存器的第转换控制寄存器的第6 6位,设置预定标值;位,设置预定标值
16、;/ADC_INPUT/ADC_INPUT 宏对应宏对应ARM S3C2410XARM S3C2410X芯片的芯片的A/DA/D转换控制寄存转换控制寄存器的第器的第3 53 5位,选择通道号;位,选择通道号;/ADCCON|=ADC_START;ADCCON 0/ADCCON|=ADC_START;ADCCON 0 为置为置1 1,准备采集数据,准备采集数据5.1嵌入式嵌入式C语言的预处理伪指令语言的预处理伪指令5.1嵌入式嵌入式C语言的预处理伪指令语言的预处理伪指令(3 3)条件宏定义)条件宏定义格式如下:格式如下:格式格式1 1:#ifdef#ifdef 宏标识符宏标识符#undef#un
17、def 宏标识符宏标识符#define#define 宏标识符宏标识符 宏体宏体#else#else#define#define 宏标识符宏标识符 宏体宏体#endif#endif格式格式2 2:#ifndef#ifndef 宏标识符宏标识符#define#define 宏标识符宏标识符 宏体宏体#else#else#undef#undef 宏标识符宏标识符#define#define 宏标识符宏标识符 宏体宏体#endif#endif其中:其中:格式格式1 1是测试存在,格式是测试存在,格式2 2是测试不存在。是测试不存在。elseelse可有,也可没有。可有,也可没有。5.1嵌入式嵌入式C
18、语言的预处理伪指令语言的预处理伪指令5.1嵌入式嵌入式C语言的预处理伪指令语言的预处理伪指令(4 4)宏释放)宏释放用于释放原先定义的宏标识符。经释放后的宏标识符用于释放原先定义的宏标识符。经释放后的宏标识符可再次用于定义其他宏体。可再次用于定义其他宏体。格式如下:格式如下:#undef#undef 宏标识符宏标识符例例5.6 5.6#define SIZE 512#define SIZE 512 buf=SIZE*blks /*buf=SIZE*blks /*宏扩展为宏扩展为buf=512*blks;*/buf=512*blks;*/undef SIZE undef SIZE#define
19、SIZE 128#define SIZE 128buf=SIZE*blks /*buf=SIZE*blks /*宏扩展为宏扩展为buf=128*blks;*/buf=128*blks;*/5.1嵌入式嵌入式C语言的预处理伪指令语言的预处理伪指令3 3条件编译伪指令条件编译伪指令格式如下:格式如下:#if#if(条件表达式(条件表达式1 1)#elif#elif(条件表达式(条件表达式2 2)#elif#elif(条件表达式(条件表达式3 3)#elif#elif(条件表达式(条件表达式n n)#else#else#endif#endif5.1嵌入式嵌入式C语言的预处理伪指令语言的预处理伪指令例
20、例5.7 5.7#if _B0SIZE=B0SIZE_BYTE#if _B0SIZE=B0SIZE_BYTEtypedef unsigned char PB0SIZEtypedef unsigned char PB0SIZE;#elif _B0SIZE=B0SIZE_SHORT#elif _B0SIZE=B0SIZE_SHORTtypedef unsigned short PB0SIZEtypedef unsigned short PB0SIZE;#elif _B0SIZE=B0SIZE_WORD#elif _B0SIZE=B0SIZE_WORDtypedef unsigned long PB
21、0SIZEtypedef unsigned long PB0SIZE;#endif#endif5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型 5.2.1 5.2.1 数据类型与表达式数据类型与表达式5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型(1)(1)类型修饰符类型修饰符 5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型(2)(2)访问修饰符访问修饰符C C语言有两个用于控制访问和修改变量方式的修饰符,语言有两个用于控制访问和修改变量方式的修饰符,分别是常量分别是常量(const)(const)和易变量和易变量(volatile)(volatile)。带。带co
22、nstconst修饰符定修饰符定义出的常量在程序运行过程中始终保持不变。义出的常量在程序运行过程中始终保持不变。例如:例如:const int numconst int num;例如:例如:const int num=100const int num=100;volatilevolatile修饰符用于提醒编译程序,该变量的值可以不修饰符用于提醒编译程序,该变量的值可以不通过程序中明确定义的方法来改变。通过程序中明确定义的方法来改变。constconst和和volatilevolatile可以同时使用。可以同时使用。例如,假设例如,假设0 x300 x30是一个只随外部条件而变化的口地是一个只随
23、外部条件而变化的口地址值,那么就恰好需要用下述说明来避免偶然因素所产址值,那么就恰好需要用下述说明来避免偶然因素所产生的副作用的影响。生的副作用的影响。const volatile unsigned char*port=0 x30const volatile unsigned char*port=0 x30;5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型2.2.构造数据类型构造数据类型 n数组数组是一组连续、有序的存放在一起的具有相是一组连续、有序的存放在一起的具有相同类型的数据。同类型的数据。n结构体结构体是将不同类型的数据按一定顺序存放在是将不同类型的数据按一定顺序存放在一起的数
24、据结构。一起的数据结构。n共用体共用体是将不同类型的数据都存放在同一起始是将不同类型的数据都存放在同一起始地址的内存单元中,共用一段内存以节省内存单地址的内存单元中,共用一段内存以节省内存单元。元。n枚举枚举是只有几种可能的值,将其一一列举出来。是只有几种可能的值,将其一一列举出来。实际是用符号来表示若干个可取的整型值,它是实际是用符号来表示若干个可取的整型值,它是整型的一个子集。整型的一个子集。5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型3.3.指针类型指针类型 n指针可以有效地表示复杂的数据结构;能动指针可以有效地表示复杂的数据结构;能动态分配内存;能方便地使用字符串;有效而态
25、分配内存;能方便地使用字符串;有效而方便地使用数组;在调用函数时能得到多于方便地使用数组;在调用函数时能得到多于一个的值;能直接处理内存地址等。一个的值;能直接处理内存地址等。n指针类型迥异于前述各种数据类型,不管是指针类型迥异于前述各种数据类型,不管是简单类型的数据,还是构造类型数据,均是简单类型的数据,还是构造类型数据,均是代表数据的,而指针类型是代表地址的。代表数据的,而指针类型是代表地址的。5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型5.2.2 5.2.2 常量常量1.1.数值常量数值常量 (1)(1)整型常量整型常量整型常量也称为整型常数或整数。整型常量也称为整型常数或整
26、数。C C整型常量按进制分可分为十进制整数,八进整型常量按进制分可分为十进制整数,八进制整数和十六进制整数。制整数和十六进制整数。(2)(2)实型常量实型常量实型常量有单精度实型常量和双精度实型常量。实型常量有单精度实型常量和双精度实型常量。可用小数形式或指数形式表示。可用小数形式或指数形式表示。(3)(3)字符常量字符常量5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型2.2.字符串常量字符串常量 字符串常量简称字符串,是用一对双引号括字符串常量简称字符串,是用一对双引号括起来的字符序列。起来的字符序列。例如例如“ChinaCh
27、ina”就是一个字符串常量。就是一个字符串常量。若数字被定义为字符型之后就不能参与数值若数字被定义为字符型之后就不能参与数值运算,如运算,如55和和5 5是不同的。是不同的。55是字符常量,不是字符常量,不能直接参与运算,而只能以其能直接参与运算,而只能以其ASCIIASCII码值码值(0 x350 x35)来参与运算。)来参与运算。5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型3.3.符号常量符号常量(1 1)不带参数的宏定义)不带参数的宏定义宏定义命令宏定义命令definedefine的一般形式是:的一般形式是:define define 宏名宏名 字符串字符串 用来终止宏名作用
28、域命令用来终止宏名作用域命令undefundef的一般形式是:的一般形式是:undef undef 宏名宏名例例5.85.8:define PI 3.14159define PI 3.14159/*/*定义定义PIPI为常量,其值是为常量,其值是3.14159*/3.14159*/main()main()undef PI /*undef PI /*终止宏名终止宏名PIPI的作用域的作用域*/f1()f1()5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型(2 2)带参数的宏定义)带参数的宏定义它不是进行简单的字符串替换,还要进行参数替换。它不是进行简单的字符串替换,还要进行参数替换。其
29、定义的一般形式为:其定义的一般形式为:define define 宏名宏名(参数表参数表)字符串字符串其中字符串中包括参数表中所指定的参数。在使用时,其中字符串中包括参数表中所指定的参数。在使用时,要将程序中宏名后的实际参数代入字符串中参数的位置。要将程序中宏名后的实际参数代入字符串中参数的位置。例如:例如:define S(a,b)a*bdefine S(a,b)a*b area=S(3,2)area=S(3,2);经编译预处理,经编译预处理,该语句被展开成该语句被展开成 area=3*2area=3*2;5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型 说明:说明:(1)(1)宏名
30、和参数表左括号之间不能有空格,宏名和参数表左括号之间不能有空格,否则按不带参宏替否则按不带参宏替换了。换了。(2)(2)字符串中应注意括号的使用,以保证运算次序。如上例改成字符串中应注意括号的使用,以保证运算次序。如上例改成area=S(1+2,2)area=S(1+2,2);经展开后变成经展开后变成area=1+2*2area=1+2*2;这就不合要求了。这就不合要求了。此时,此时,可改写成可改写成 define S(a,b)(a)*(b)define S(a,b)(a)*(b)area=S(1+2,2)area=S(1+2,2)经展开后变成经展开后变成 area=(1+2)*(2)area
31、=(1+2)*(2);就不会出现错误了。就不会出现错误了。5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型5.2.3 5.2.3 变量变量 1.1.变量的定义变量的定义 变量定义的一般形式如下:变量定义的一般形式如下:存储类型存储类型 类型说明符类型说明符 修饰符修饰符 标识符标识符 =初初值值,标识符,标识符=初值初值 ;变量的定义由变量的定义由5 5部分组成,方括号中的可有可无,部分组成,方括号中的可有可无,变量定义的具体情况而定。变量定义的具体情况而定。5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型(1 1)类型说明符)类型说明符 对于数字与字符,其常用的类型主要有对于
32、数字与字符,其常用的类型主要有8 8种:种:charchar、unsigned unsigned charchar、intint、unsignedunsigned、longlong、unsigned longunsigned long、floatfloat、doubledouble。void void 类型(抽象型),在具体化时可用类型强制来指定类型类型(抽象型),在具体化时可用类型强制来指定类型说明符中的任意一类。说明符中的任意一类。通过通过typedeftypedef定义的类型别名。为了增加程序的可读性和移植定义的类型别名。为了增加程序的可读性和移植程序时的方便,程序时的方便,C C语言允
33、许用户为语言允许用户为C C语言固有的类型用语言固有的类型用typedeftypedef起别名。起别名。格式如下:格式如下:typedef Ctypedef C固有的简单类型或复合类型别名标识符固有的简单类型或复合类型别名标识符 ;用别名代替原来的类型,在说明中用作类型说明符。别名一般用用别名代替原来的类型,在说明中用作类型说明符。别名一般用大写字符,例如:大写字符,例如:typedef long BIGtypedef long BIGBIG x=80000;BIG x=80000;5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型(2)(2)标识符标识符 变量名可以是变量名可以是C C
34、语言中允许的合法标识符。语言中允许的合法标识符。每一个变量都必须进行类型说明,也就是变量要先定义,后使每一个变量都必须进行类型说明,也就是变量要先定义,后使用。用。当一个变量被指定为某一确定类型时,将为它分配若干相应字当一个变量被指定为某一确定类型时,将为它分配若干相应字节的内存空间。如在节的内存空间。如在3232位体系的位体系的ARMARM系统中,系统中,charchar型为型为1 1字节,字节,intint型为型为4 4字节,字节,floatfloat为为4 4字节,字节,doubledouble为为8 8字节。当然,不同的字节。当然,不同的体系结构的系统可能稍有差异。体系结构的系统可能稍
35、有差异。变量可以在程序内的三个地方定义:变量可以在程序内的三个地方定义:在函数内部,在函数内部,在函数的在函数的参数(形参)定义中或在所有的函数外部。由此定义的变量分参数(形参)定义中或在所有的函数外部。由此定义的变量分别称为局部变量,别称为局部变量,形式参数和全局变量。在不同地方定义的形式参数和全局变量。在不同地方定义的变量,其作用域范围不同。在同一层次定义的变量不能与数组、变量,其作用域范围不同。在同一层次定义的变量不能与数组、指针、函数和其它变量同名。指针、函数和其它变量同名。变量是用来存放数据的,由于数据有不同的类型,因此要定义变量是用来存放数据的,由于数据有不同的类型,因此要定义相应
36、类型的变量去存放它。这些数据称为相应变量的值。相应类型的变量去存放它。这些数据称为相应变量的值。5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型 (3)(3)存储类型存储类型 存储类型指定被说明对象所在内存区域的属性。存储类型指定被说明对象所在内存区域的属性。存储空间分为代码区与数据区两个部分。变量存储在数据区,存储空间分为代码区与数据区两个部分。变量存储在数据区,数据区又可分为静态存储区与动态存储区。数据区又可分为静态存储区与动态存储区。n静态存储是指在程序运行期间给变量分配固定存储空间的方式。静态存储是指在程序运行期间给变量分配固定存储空间的方式。如全局变量存放在静态存储区中,程序
37、运行时分配空间如全局变量存放在静态存储区中,程序运行时分配空间,程序程序运行完释放。运行完释放。n动态存储是指在程序运行时根据实际需要动态分配存储空间的动态存储是指在程序运行时根据实际需要动态分配存储空间的方式。如形式参数存放在动态存储区中,在函数调用时分配空方式。如形式参数存放在动态存储区中,在函数调用时分配空间,调用完成释放。间,调用完成释放。n对于静态存储方式的变量可在编译时初始化,默认初值为对于静态存储方式的变量可在编译时初始化,默认初值为0 0或或空字符。对动态存储方式的变量如不赋初值,则它的值是一个空字符。对动态存储方式的变量如不赋初值,则它的值是一个不确定的值。不确定的值。n在在
38、C C语言中,具体的存储类别有自动(语言中,具体的存储类别有自动(autoauto)、寄存器)、寄存器(registerregister)、静态()、静态(staticstatic)及外部()及外部(externextern)四种。静态存储)四种。静态存储类别与外部存储类别变量存放在静态存储区,自动存储类别变类别与外部存储类别变量存放在静态存储区,自动存储类别变量存放在动态存储区,寄存器存储类别直接送寄存器。量存放在动态存储区,寄存器存储类别直接送寄存器。5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型 局部变量的存储方式局部变量的存储方式 局部变量一般用自动方式存储,用保留字局部变量
39、一般用自动方式存储,用保留字autoauto加以定加以定义,此时称为自动变量,是动态存储,在函数的调用过义,此时称为自动变量,是动态存储,在函数的调用过程中存在,由编译系统自动处理。例如:程中存在,由编译系统自动处理。例如:void f()void f()auto int i,j;auto int i,j;auto float x,y;auto float x,y;/*/*局部变量局部变量i i,j j,x x,y y以自动方式存储以自动方式存储*/C C语言规定,自动变量可省去说明符语言规定,自动变量可省去说明符autoauto。如果希望。如果希望函数调用完后局部变量的值被保留,不释放其所占
40、存储函数调用完后局部变量的值被保留,不释放其所占存储单元,这时必须将其存储方式定义为静态存储方式,用单元,这时必须将其存储方式定义为静态存储方式,用保留字保留字staticstatic加以定义。加以定义。5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型 全局变量的存储方式全局变量的存储方式 全局变量一般用外部存储方式存储,用保留全局变量一般用外部存储方式存储,用保留字字externextern加以定义。加以定义。变量的作用域是构成整个程序的所有程序文变量的作用域是构成整个程序的所有程序文件,也就是定义的外部变量可供其它程序文件使件,也就是定义的外部变量可供其它程序文件使用。用。5.2嵌
41、入式嵌入式C语言的基本数据类型语言的基本数据类型例如例如5.9 5.9 程序由两个程序文件程序由两个程序文件file1.cfile1.c与与file2.cfile2.c组成。组成。/*file1.c*/*file1.c*/extern int a;/*extern int a;/*定义定义externextern存储方式变量存储方式变量a*/a*/main()main()int pow();int pow();int n;int n;int p;int p;scanfscanf(%d,&n%d,&n);p=powp=pow(n n);printfprintf(p=%dn,pp=%dn,p);5
42、.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型/*file2.c*/*file2.c*/extern int a;/*extern int a;/*申明本文件中使用的是已定申明本文件中使用的是已定义的外部变量义的外部变量a*/a*/int powint pow(x x)int x;int x;int i,t=1;int i,t=1;forfor(i=1;i=x;i+i=1;i、=、=、=、=31);printf(%dn,531);运行输出结果为运行输出结果为0 0。因为两个。因为两个是同一优先级,是同一优先级,5353的结果为的结果为1 1,而,而1111的关系不满足,所以最后结果为的
43、关系不满足,所以最后结果为0 0。又如又如:printf(%dn,1=1135);printf(%dn,1=1135);运行输出结果为运行输出结果为1 1。因为。因为的优先级比的优先级比=高,则高,则11351135的结的结果为果为1 1,而,而1=11=1的关系满足,所以最后结果为的关系满足,所以最后结果为1 1。5.2嵌入式嵌入式C语言的基本数据类型语言的基本数据类型3.位运算符位运算符 5.3程序的控制结构程序的控制结构 5.3 5.3 程序的控制结构程序的控制结构 程序控制语句用于控制程序的流程,以程序控制语句用于控制程序的流程,以实现程序的各种结构方式。包括:实现程序的各种结构方式。
44、包括:条件判断语句:条件判断语句:if if,switchswitch循环执行语句:循环执行语句:do whiledo while,whilewhile,forfor转向语句:转向语句:breakbreak,gotogoto,continuecontinue,returnreturn5.3程序的控制结构程序的控制结构5.3.1 选择结构选择结构 用用if语句可以实现简单选择结构。其语法形式为语句可以实现简单选择结构。其语法形式为if(表达式表达式)语句语句1else 语句语句2 执行顺序是:首先计算表达式的值,若表达式执行顺序是:首先计算表达式的值,若表达式值为值为true,则执行语句,则执行
45、语句1;否则执行语句;否则执行语句2。if语句中的语句语句中的语句2可以为空,当语句可以为空,当语句2为空时,为空时,else可以省略,成为如下形式:可以省略,成为如下形式:if(表达式表达式)语句语句1 其中,语句其中,语句1和语句和语句2不仅可以是一条语句,而且不仅可以是一条语句,而且可以是大花括号括起来的多条语句,即复合语句。可以是大花括号括起来的多条语句,即复合语句。5.3程序的控制结构程序的控制结构5.3.2 switch语句语句switch语句的语法形式如下:语句的语法形式如下:switch(表达式表达式)case常量表达式常量表达式1:语句:语句1case常量表达式常量表达式2:
46、语句:语句2case常量表达式常量表达式n:语句:语句ndefault:语句语句 n+15.3程序的控制结构程序的控制结构5.3.3 循环结构循环结构 嵌入式嵌入式Lunux C语言中有三种循环控制语句,语言中有三种循环控制语句,即即while,do while,for循环语句。循环语句。while和和do while是两种不同的循环结构,即当型循环和直型循是两种不同的循环结构,即当型循环和直型循环,其格式如下:环,其格式如下:1while语句(当型循环)语句(当型循环)while语句的语法形式为:语句的语法形式为:while(表达式表达式)循环体语句循环体语句 5.3程序的控制结构程序的控制
47、结构5.3.3 循环结构循环结构 2do-while语句(直型循环)语句(直型循环)语法形式:语法形式:do 循环体语句循环体语句 while(表达式表达式);执行顺序是:当流程执行到执行顺序是:当流程执行到do后,立即执行循后,立即执行循环体语句,然后再判断循环条件表达式的值。当表环体语句,然后再判断循环条件表达式的值。当表达式为达式为true时,继续执行循环体;否则结束循环,时,继续执行循环体;否则结束循环,该语句结构使循环至少执行一次。该语句结构使循环至少执行一次。5.3程序的控制结构程序的控制结构3 3forfor语句语句 forfor语句的使用最为灵活,既可以用于循环次数确定语句的使
48、用最为灵活,既可以用于循环次数确定的情况,也可以用于循环次数未知的情况。的情况,也可以用于循环次数未知的情况。forfor语句的语语句的语法形式如下:法形式如下:for(for(表达式表达式1 1;表达式;表达式2 2;表达式;表达式3)3)for for语句的执行流程为:语句的执行流程为:(1)(1)首先计算表达式首先计算表达式1 1的值。的值。(2)(2)再计算表达式再计算表达式2 2,如果表达式,如果表达式2 2的值为的值为falsefalse,则退,则退出循环。出循环。(3)(3)如果表达式如果表达式2 2的值为的值为truetrue,则执行一次循环体,然,则执行一次循环体,然后计算表
49、达式后计算表达式3 3的值。的值。(4)(4)转回转回(2)(2),表达式,表达式2 2的值决定是否继续执行循环体。的值决定是否继续执行循环体。5.3程序的控制结构程序的控制结构5.3.4 其他控制语句其他控制语句1break语句语句 break 语句只用于语句只用于switch语句或循环体中,作用是使语句或循环体中,作用是使程序从程序从switch语句内跳出或结束本次循环,转去执行后面的语句内跳出或结束本次循环,转去执行后面的语句。由于语句。由于break语句的转移方向是明确的,所以不需要语句语句的转移方向是明确的,所以不需要语句标号与之配合。标号与之配合。2continue语句语句 con
50、tinue语句仅用于循环体中,其作用是结束本次循语句仅用于循环体中,其作用是结束本次循环,接着开始判断循环条件,决定是否继续执行下一次循环。环,接着开始判断循环条件,决定是否继续执行下一次循环。3goto语句语句goto语句的语法格式为语句的语法格式为goto goto语句的作用是跳转到语句标号处执行程序。语句的作用是跳转到语句标号处执行程序。5.4函数函数5.4 函函 数数 1函数定义函数定义 一个完整的函数定义由两部分组成,即函数头与函数一个完整的函数定义由两部分组成,即函数头与函数体。函数定义的一般语法形式为:体。函数定义的一般语法形式为:(形式参数表形式参数表)说明性语句序列;说明性语