130 likes | 337 Views
程序设计基础( C 语言). 东北大学高级语言程序设计课程组 课程网站: www.neu.edu.cn/cxsj. 程序设计基础( C 语言). 预编译和宏定义. 预编译处理命令概述. 1. 概念 预编译是在编译前对源程序进行的一些预加工 预编译由编译系统中的预处理程序 , 按源程序中的预处理 命令进行. 2. 预编译处理命令 C 语言的预编译处理命令均以 “ # ” 打头 , 末尾不加分号 预处理命令可以出现在程序的任何位置 , 其作用域是从出现点到所在源程序的末尾.
E N D
程序设计基础(C语言) 东北大学高级语言程序设计课程组 课程网站:www.neu.edu.cn/cxsj
程序设计基础(C语言) 预编译和宏定义
预编译处理命令概述 1. 概念 预编译是在编译前对源程序进行的一些预加工 预编译由编译系统中的预处理程序, 按源程序中的预处理 命令进行 2. 预编译处理命令 C语言的预编译处理命令均以 “ # ”打头, 末尾不加分号 预处理命令可以出现在程序的任何位置, 其作用域是从出现点到所在源程序的末尾 3. 优点 : 能改善程序设计的环境, 有助于编写易移植, 易调试的程序
#define命令进行宏定义 称为宏名 一、 不带参数的宏定义 1. 格式 : #define 标识符 替换文本 称为宏体 2. 说明 : (1) 标识符也称宏名, 一般用大写字母表示 (2) 预处理时将程序中所有的宏名用宏体替换, 该过程称 “宏展开”; 但在程序中用 “ ” 括起来的字符串中, 即使 有的字符串与宏名相同, 也不进行替换 #define SIZE 20 void main ( ) { int x ; x =SIZE+15 ; printf( “SIZE=%d \n”,x ) ; } 输出结果: SIZE=35
(3) 宏定义只是一种简单的字符替代, 不进行语法检查 若将#define SIZE 20的零写成英文字母‘o’ , 程序中的 x =SIZE+15 ; 会替换为 x = 2o+15; 这时才会发现错误 (4) 宏定义不是C语句, 行末不加分号, 每条宏命令要单独占一行 (5) #define命令出现在函数的外部, 宏名的有效范围为 定义命令之后到本文件结束 (6) 可以用#undef 命令终止宏定义的作用域
(7) 宏定义可以嵌套使用 例 #define L 10 #define W 20 #define S L*W (8) 宏定义与变量定义不同, 它只作字符替换, 不分配内存空间 3. 使用宏替换的优点: 提高程序的可读性, 易于修改 二、 带参数的宏定义 1. 格式 : #define 宏名( 形参表) 替换文本
2. 说明 (1) 宏定义时宏名与括号之间没有空格, 若有空格则会把空格后的所有字符都看成是宏体 (2) 带参数的宏在替换时,不仅宏名被宏体替换, 同时形参被实参替换 (3) 建议带运算符的宏体和形参要用 ( ) 括起来 例 #define PI 3.14159 #define S(r) PI*r*r void main ( ) { float a , area ; a = 3.6 ; area =S(a); printf( “ %f \n”, area) ; } 宏替换: area = 3.14159*a*a ;
#define PI 3.14159 #define S(r) PI* r * r #define PI 3.14159 #define S(r) PI*(r)*(r) 宏替换: area = 3.14159*(a+b)*(a+b) ; void main ( ) { float a , b , area ; a = 3.6 ; b = 1.2 ; area = S(a+b); printf( “ %f \n”, area) ; } 宏替换: area = 3.14159*a+b*a+b ;
3. 带参数的宏与函数的区别 (1) 函数调用时,先求出实参表达式的值,再代入形参 带参数的宏定义只是进行简单的字符替换 (2) 函数调用是在程序运行时处理, 分配临时的内存单元 宏展开是在编译时进行的, 在展开时不分配内存单元 (3) 对函数的形参和实参都要定义类型, 且要求一致 宏不存在类型问题, 宏名无类型, 其参数也无类型 (4) 调用函数只可得到一个返回值, 使用宏可以设法得到几个结果 (5) 函数调用不会使源程序变长, 宏展开会使源程序增长 (6) 函数调用占用运行时间, 宏展开不占运行时间, 只占编译时间
#define PI 3.14 #define CIR(R,L,S,V) L=2*PI*R;S=PI*R*R;V=4.0/3.0*PI*R*R*R main() {float r,l,s,v; scanf("%f"&r); CIR(r,l,s,v); printf("r=%6.2f,l=%6.2f, S=%6.2f,v=%6.2f\n",r,l,s,v); } 宏展开后: main() {float r,l,s,v; scanf("%f",&r); l=2*3.14*r; s=3.14*r*r; v=4.0/3.0*3.14*r*r*r; printf("r=%6.2f,l=%6.2f,s=%6.2f,v=%6.2f\n",r,l,s,v); }
条件编译 1. 条件编译: 对源程序中的一部分内容在满足一定条件时 才进行编译, 即对一部分内容指定编译的条件 2. 条件编译的形式 • #ifdef 标识符 程序段1 #else 程序段2 #endif 作用: 指定的标识符已经被#define命令 定义过, 则在程序编译阶段只编译 程序段1, 否则只编译程序段2 注 : #else部分可以没有
(2) #ifndef 标识符 程序段1 #else 程序段2 #endif 作用: 若指定的标识符没有被#define 命令定义过, 则编译程序段1, 否则编译程序段2 (3) #if 表达式 程序段1 #else 程序段2 #endif 作用: 当表达式的值为真时编译程序段1 否则编译程序段2
#define LETTER 1 main() { char str[20]="C Language",c; int i; i=0; while((c=str[i])!='\0') { i++; #if LETTER if(c>='a'&&c<='z') c=c-32; #else if(c>='A'&&c<='Z') c=c+32; #endif printf("%c",c); } }