编译预处理
在对一个源程序进行编译时,系统将自动调用预处理程序对源程序中的预处理部分作处理,处理完毕后自动编译源程序
宏定义
不带参数的宏定义
#define 标识符 字符串
#define PI 3.1415926
“标识符”是为所定义的宏名
“字符串”为宏名将要被替换的字符串,可以是常量字符串、表达式字符串、格式字符串等
宏定义
常量宏定义
//【例9. 1】常量的宏定义。
#include <stdio.h>
#define PI 3.1415926
void main()
{ float r,l,s,v;printf("Input radius: ");scanf("%f",&r);l=2.0*PI*r; //宏展开为 l=2.0*3.1415926*r;s=PI*r*r; //宏展开为 s=3.1415926*r*r;v=4.0/3*PI*r*r*r; //宏展开为 v=4.0/3*3.1415926*r*r*r;printf("l=%.4f\ns=%.4f\nv=%.4f\n",l,s,v);
}
表达式的宏定义
//【例9. 2】表达式的宏定义。
#include <stdio.h>
#define M (y*y+3*y)
void main()
{ int s,y;printf("Input a number: ");scanf("%d",&y);s=3*M+4*M+5*M; //宏展开为 s=3*(y*y+3*y)+4*(y*y+3*y)+5*(y*y+3*y);printf("s=%d\n",s);
}
函数名和格式字符串的宏定义
//【例9. 3】函数名和格式字符串的宏定义。
#include <stdio.h>
#define P printf
#define F "%4d\t%.2f\n"
void main()
{ int a=3, c=5, e=11;float b=4.6, d=7.9, f=22.08;P(F,a,b); //宏展开为 printf("%4d\t%.2f\n",a,b);P(F,c,d); //宏展开为 printf("%4d\t%.2f\n",c,d);P(F,e,f); //宏展开为 printf("%4d\t%.2f\n",e,f);
}
宏
define PI 3.l4l5926
把数字“1”写成了小写字母“l”
#define PI 3.1415926;
……
area=PI*r*r;
……
宏展开后为: area=3.1415926;*r*r;
//【例9. 4】双引号中与宏名相同的字符不作替换。
#include <stdio.h>
#define PI 3.1415926
void main()
{ printf("PI\n"); //不进行宏展开printf("%f\n",PI); //进行宏展开
}
•(8)宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用# undef命令。
//【例9. 5】使用# undef结束宏的作用域。
#include <stdio.h>
#define PI 3.1415926
void main()
{ float r=2,area;area=PI*r*r;
//宏展开为area=3.1415926*r*r; printf("area=%f",area);
}
#undef PI
f1()
{ float r=2,area;area=PI*r*r;
//PI不能被宏展开,此处语法报错,PI没有定义printf("area=%f",area);
}
带参数的宏定义
//【例9. 6】带参数的宏定义。
#include <stdio.h>
#define MAX(a,b) (a>b)?a:b
void main()
{ int x,y,max;printf("Input two numbers:");scanf("%d,%d",&x,&y);max=MAX(x,y); //宏展开为 max=(x>y)?x:y;printf("max=%d\n",max);
}
语句: max=MAX(x,y);
宏展开后为:max=(a,b) (a>b)?a:b(x,y); 是错误的。
(2)宏定义中的形参是标识符,语句中的实参可以是表达式
【例9. 7】语句中的实参为表达式。
#include <stdio.h>
#define SQ(y) (y)*(y)
void main()
{ int a,sq;printf("Input a number: ");scanf("%d",&a);sq=SQ(a+1); //宏展开为 sq=(a+1)*(a+1);printf("sq=%d\n",sq);
}
(3)在宏定义中,形参通常要用括号括起来以避免出错。
宏定义:
#define SQ(y) (y)*(y)
中(y)*(y)表达式的y都用括号括起来,因此结果是正确的
如果去掉括号,定义形式如下:
#define SQ(y) y*y
语句: sq=SQ(a+1);
宏展开后为:sq=a+1*a+1;
按以下形式定义:
#define SQ(y) (y)*(y)
语句:sq=1.0/SQ(a+1);
宏展开后为:
sq=1.0/(a+1)*(a+1); //先算除法,再算乘法
要想先算乘法后算除法,应该在宏定义中的整个字符串外加括号,按如下形式定义:
#define SQ(y) ((y)*(y))
带参数的宏和函数的区别
//【例9. 8】通过宏展开得到若干结果。
#include <stdio.h>
#define SSSV(L,W,H,SA,SB,SC,VV) SA=L*W;SB=L*H;SC=W*H;VV=W*L*H;
void main()
{ int l=3,w=4,h=5,sa,sb,sc,vv;SSSV(l,w,h,sa,sb,sc,vv); //宏展开后为sa=l*w;sb=l*h;sc=w*h;vv=w*l*h;printf("sa=%d\nsb=%d\nsc=%d\nvv=%d\n",sa,sb,sc,vv);
}
调用函数只可得到一个返回值,而宏可以设法得到几个结果。
文件包含
文件包含命令的一般形式为:
#include "文件名"
或
#include <文件名>
//【例9. 9】文件包含命令的使用。
(1)文件file1.c内容如下:
#include <stdio.h>
#include "file2.c"
void main()
{ int a,b,c;printf("Input two numbers: ");scanf("%d,%d",&a,&b);c=max(a,b);printf("max=%d\n",c);
}
//(2)文件file2.c内容如下:
int max(int x,int y)
{ int z;if(x>y) z=x;else z=y;return(z);
}
条件编译
条件编译-形式一
#ifdef 标识符
程序段1
#else
程序段2
#endif
#ifdef 标识符
程序段
#endif
功能是:如果所指定标识符在之前已被 #define命令定义过,则在编译时编译程序段1;否则编译程序段2。
【例9. 10】给定半径r,求圆的面积s。要求设置条件编译:若π值已定义,则直接计算面积;若π值未定义,则定义π值后再计算面积。
#include <stdio.h>
void main()
{ float r,s;
printf("Input radius: ");
scanf("%f",&r);
#ifdef PI //条件编译
s=PI*r*r; //程序段1
#else
#define PI 3.1415926 //程序段2
s=PI*r*r;
#endif
printf("s=%f\n",s);
}
(1)程序中在条件编译前未定义π值(即PI),所以编译程序段2
(2)若程序开头加入宏定义“#define PI 3.1415926”,则编译程序段1
条件编译-形式二
#ifndef 标识符
程序段1
#else
程序段2
#endif
功能是:如果标识符之前未被#define命令定义过,则对程序段1进行编译,否则对程序段2进行编译
【例9. 11】按形式二修改【例9. 10】的程序。
#include <stdio.h>
void main()
{ float r,s;
printf("Input radius: ");
scanf("%f",&r);
#ifndef PI //条件编译
#define PI 3.1415926 //程序段1
s=PI*r*r;
#else
s=PI*r*r; //程序段2
#endif
printf("s=%f\n",s);
}
(1)程序中在条件编译前未定义π值(即PI),所以编译程序段1
(2)若在程序的开头加入宏定义“#define PI 3.1415926”,则编译程序段2
条件编译-形式三
#if 表达式
程序段1
#else
程序段2
#endif
功能是:若表达式的值为真(非0),则编译程序段1,否则编译程序段2
【例9. 12】设置条件编译。求圆的面积或正方形的面积。
#include <stdio.h>
#define PI 3.1415926
#define R 1
void main()
{ float c,s;
printf ("Input a number: ");
scanf("%f",&c);
#if R //条件编译
s=PI*c*c; //程序段1
printf("Area of circle is : %f\n",s);
#else
s=c*c; //程序段2
printf("Area of square is : %f\n",s);
#endif
}
程序宏定义中,定义R为1,因此在条件编译时,表达式R的值为真,故编译程序段1,求圆的面积
说明
#ifdef COMPUTER_A
#define INTEGER_SIZE 16
#else
#define INTEGER_SIZE 32
#endif