资源预览内容
第1页 / 共28页
第2页 / 共28页
第3页 / 共28页
第4页 / 共28页
第5页 / 共28页
第6页 / 共28页
第7页 / 共28页
第8页 / 共28页
第9页 / 共28页
第10页 / 共28页
亲,该文档总共28页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
嵌入式Linux下C程序设计,主讲:成宝宗,编译预处理,主讲:成宝宗,主要内容,宏的定义 文件包含 条件编译 程序综合举例,“预处理”是指在对C语言源程序进行编译之前,要先对程序中的“宏定义、文件包含、条件编译”等特殊命令进行预先处理。 宏定义:定义一个标识符来表示一个字符串,称为“宏定义”,该标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”的地方都用字符串去代换。 宏定义分类:分为有参数宏定义和无参数宏定义两种。,宏的定义 不带参数的宏定义 宏定义的一般格式为: #define 文本串 /*#define就是宏定义命令*/ 功能:将宏名的值定义为指定的文本串。 在预处理时凡出现宏名的地方,都用指定的文本串替换。 在预处理时将宏名替换成指定的文本串的过程称为“宏展开”,或称为“宏替换”。,【例】 求圆周长、面积和相同半径圆球体积。 #define PI 3.14159 void main() float r,l,s,v; printf(“input radius:”); scanf(“%f”, ,程序运行结果: input radius:6 l= 37.70 s=113.10 v=508.94,注意: (1) 宏名为了与变量名区别一般用大写字母表示。 (2) 宏展开时只用文本串替换宏名,不作正确性检查。 (3) 宏定义行末尾不能加分号。加分号,宏展时会当作文 本串字符一同代入。 (4) 宏名的有效范围是:从定义位置开始到本文件结束 (5) 可以用#undef命令终止宏定义的作用域。 (6) 在宏定义时,可以引用已定义的宏名。,【例】在宏定义时引用已定义的宏名 #define R 4.0 #define PI 3.14159 #define L 2*PI*R #define S PI*R*R void main() printf(“L=%6.2fnS=%6.2fn”,L,S); ,运行结果如下: L= 25.13 S= 50.27,【例】分析下列程序 #define OK 100 void main() printf(OK); printf(n); ,运行结果为: OK,为什么不是100?,带参数的宏定义 带参数的宏定义格式如下: #define (参数表) 文本串 功能:定义一个带参数的宏。 例如: #define S(x,y) 3*x+2*y area=S(3,2); 宏展开:用实参从左到右逐个字符进行替换文本串中的形参字符。如图8.1所示。 执行:area=S(3,2) 宏展开后变成: area=3*3+2*2;,【例】 求圆的面积。 #define PI 3.14159 #define S(r) PI*r*r void main() float a,area; a=3.6; area=S(a); printf(“area=%6.2fn”,area); ,运行结果: area= 40.72,说明: (1) 宏名与括弧之间不能有空格。 (2) 宏调用时,实参的个数必须与形参的个数相同。 (3) 带参数的宏替换时不作语法检查。 (4) 宏定义时最好在参数两侧加括号和整个字符串外加括号,防止宏替换出错。,【例】分析以下程序运行结果 #define SQ(y) (y)*(y) void main() int a,sq; printf(input a number: ); scanf(%d, ,比较下面【例6】和【例7】程序的不同之处。,【例6】 #define SQ(y) y*y void main() int a,sq; printf(input a number: ); scanf(%d, 运行结果为: input a number:3 sq=7 /*宏代换后得到:sq=a+1*a+1; */,【例7】 #define SQ(y) (y)*(y) void main() int a,sq; printf(input a number: ); scanf(%d, */,宏调用和函数调用的主要区别:,文件包含:就是将指定文件全部内容包含(装入)到本文件中来。 一般格式: #include“文件名” 或 #include 功能: 将指定的源文件全部内容包含进来,即装入#include命令所处位置上使其成为一个程序。,2 文件包含,对文件包含命令还要说明以下几点: 1.指定文件名可以用双引号或尖括号括起来。 例如: #includestdio.h #include 二者的区别: 用尖括弧时,直接在库函数头文件目录中查找包含文件,称为标准方式; 用双引号时,在用户当前目录中寻找包含的文件,若找不到,再按标准方式查找。 一般情况下:包含库函数用尖括弧节省时间; 包含用户自己编写的文件用双引号。 2. 一个#include命令只能指定一个被包含文件。 3. 文件包含允许嵌套,即在一个被包含的文件中又可以包含另一个文件。,功能:一个源文件可将另一个源文件的内容全部包含进来 一般形式: #include “文件名” 或 #include ,处理过程:预编译时,用被包含文件的内容取代该预处理命令,再对“包含”后的文件作一个源文件编译, 直接按标准目录搜索 “” 先在当前目录搜索,再搜索标准目录 可指定路径,文件包含,源文件(*.c) 头文件(*.h),宏定义 数据结构定义 函数说明等,文件包含可嵌套,被包含文件内容,例 文件包含举例,【例8】给定半径,计算圆的周长和圆的面积。 设计三个包含文件,或称为头文件: 第1个为:myin1.h #include #define PI 3.14159 第2个为:myin2.h float getlen(float r) return 2*getsr(r)/r; 第3个为:myin3.h float getsr(float r) return PI*r*r; ,主函数的程序如下: #include “myin1.h” #include “myin3.h” #include “myin2.h” void main() float x=3.0; printf(“L=%fn”,getlen(x); printf(“S=%fn”,getsr(x); ,因为:函数的调用关系,头文件的包含顺序应该必须是:myin1.h,然后myin3.h,最后是myin2.h。,一般情况下,对源程序进行全部编译。 条件编译:根据具体条件和需要只编译源程序中的某些部分为条件编译。 条件编译用途:可以用源程序产生不同版本。,3 条件编译,1条件编译的三种形式: 形式一: #ifdef 标识符 程序段1 #else 程序段2 #endif 功能:标识符已被 #define命令定义过则对程序段1进行编译;否则对程序段2进行编译。,形式二: #ifndef 标识符 程序段1 #else 程序段2 #endif 功能:如果标识符未被#define命令定义过则对程序段1进行编译,否则对程序段2进行编译。,形式三: #if 常量表达式 程序段1 #else 程序段2 #endif 功能是,如常量表达式的值为真(非0),则对程序段1 进行编译,否则对程序段2进行编译。,#include #define LETTER 0 int main( ) char str = C language; char c; int i; for (i = 0; stri != 0; i+) c = stri; #if LETTER if (c=a ,运行结果: C LANGUAGE 上题如果将第一行改为:#define LETTER 0 则在预处理时,对第二个IF语句处理,使大写变为小写。,目的:掌握宏定义、宏调用,以及宏展的处理过程,掌握文件包含的概念和使用。 实训内容: 1试分析以下宏替换后的形式,计算输出结果。 要求:先计算运行结果,然后利用程序验证。 #include #define CX(y) 2.5+y #define PR(a) printf(%d,(int)(a) #define PR1(a) PR(a); putchar(n) int main(void) int x=2; PR1(CX(5)*x); return 0; ,5练习,2.写出下面程序的运行结果,(2) #define M 3 #define N M+1 #define NN N*N/2 int main( ) printf(“%dn”, NN) printf(“%dn”, 5*NN) ; ,(1) #define min(x, y) xy? x:y int main() int x=5 , y=10 , z ; z=10*min(x , y); printf(“%d”, z) ; ,3编程题: (1)定义一个宏,将大写字母变成小字母。 (2)定义一个宏,输入二数取其中最大数。 (3)定义带参宏用于求某数平方。,
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号