分类:
2009-04-24 19:25:57
#中主要任务
1》文件包含:
#include
#include "file.h"
2>宏定义
#define name body
必须在一行中,否则会出现错误,可以使用延续符\,注意延续符与新行之间不能有空行,否则会导致错误
a》常量定义:#define NO 9其中宏体可以使任意类型
b》模拟函数:
1》无参#define FLUSH while(getchar()!='\n')
2》带参:#define max(x,y) (x)>(y)?(x) y)
循环移位
#define ROTATE_LEFTA(x,n) ((x)<<(n)|((x)>>(32-x)))
c》嵌套宏
#define PRODUCT(a,b) (a)*(b)
#define SQUARE(a) PRODUCT(a,a)
当执行x=SQUARE(5)时执行x=PRODUCT(5,5)
d》取消宏定义
宏不能重定义,除非先使用#undef命令取消重定义
#define NO 9
#undef NO
#define NO 10
e>预定义的宏(不能用undef取消)
C标准中指定了一些预定义的宏,对于编程经常会用到。下面这个表中就是一些常常用到的预定义宏。
__DATE__
进行预处理的日期(“Mmm dd yyyy”形式的字符串文字)
__FILE__
代表当前源代码文件名的字符串文字
__LINE__
代表当前源代码中的行号的整数常量
__TIME__
源文件编译时间,格式微“hh:mm:ss”
__func__
当前所在函数名
对于__FILE__,__LINE__,__func__这样的宏,在调试程序时是很有用的,因为你可以很容易的知道程序运行到了哪个文件的那一行,是哪个函数。
下面一个例子是打印上面这些预定义的宏的。
执行结果:
fenglq@fenglq-desktop:~$ ./a.out
The file is pro.c.
The date is Apr 18 2009.
The time is 23:23:47.
This is line 9.
This function is main.
This function is why_me
The file is pro.c.
This is line 19.
f》与宏相关的操作符
1>#操作符
#define PRINT_VAL(a) printf(#a "contains:%d\n",(a))
将这个进行调用
PRINT_VAL(name)
预处理器扩展为
printf(name "contains:%d\n",name)
2>##归并操作符
#define FROM(T,N) T##N
3>define操作符
#define PI 3.14
defined(PI)的值为1
!defined(PI)的值为1
3)条件编译
a》在想要包含文件时包含,不想要时不包含
#if 0
#include "name.h"
#endf
b>
一个程序包含很多文件,这些包含了一些通用的代码,如果每个文件都包含,因为预处理器不允许宏的重复定义,编译时将会发生错误,为防止错误可以这样作
不使用#define GO 0
而是使用
#if !defined (GO)
#define GO 0
#endif
在这里c语言提供了两种缩写
#if defined name-----------------------#ifdef name
#if !defined name-----------------------#ifndef name
c》包含共享库文件时,如果每个都包含一次,会产生名称重复编译错误,可以用下面的方法解决
#ifndef PROG_LIB
#define PROG_LIB
#include "lib.h"
#endif
在大多数实现种可以用以上策略防止源程序对系统头文件,如stdio.h,进行多次包含,例如:
#ifndef STDIO
#define STDIO
OTHER
#endif
d>调试程序
当你没有gdb时,你怎么调试程序呢?其实说白了,调试程序就是大益处足够的信息,只要有足够的printf没有调不好的程序,但是当一个程序很大时这就不划算了,光是添加删除printf就够烦死人的,看下面的办法,这个例子用了前面见过的很多概念和方法。
输出:
fenglq@fenglq-desktop:~$ c99 -Wall pro.c
fenglq@fenglq-desktop:~$ ./a.out
Atline 14--x contains:1032
Atline 20--i contains:0
Atline 20--x contains:1065024
Atline 20--i contains:1
Atline 20--x contains:404754432
d>多路命令
类似于多路选择else-if只不过这里用的是#elif,下面是一个多路选择的例子
#define a 0
#define b 0
#define c 0
#define d 0
…………
#if(a)
#include "a.h"
#elif(b)
#include "b.h"
#elif(c)
#include "c.h"
#elif(d)
#include "d.h"
#endif
e>条件命令汇总
#if expression
#endif
#endif
#else
#elif
#ifdef name
#ifndef name
f>其他命令
1》行命令
#line 100 //设置当前行的下一行为第100行
#line 100 "filename.c" //设置当前行的下一行为第100行,并设置程序名为filename.c
详细请看下面的程序
执行结果:
fenglq@fenglq-desktop:~$ ./a.out
line 103
file mypro.c
line 105
2》错误命令
#error message
看下面程序
编译时将得到错误信息
fenglq@fenglq-desktop:~$ gcc -Wall pro.c
pro.c:4:3: 错误: #error FAlse not defined
3》pragma命令
#pragma tokens
功能是使编译器完成实现所定义的动作(高级应用)
4》空命令
#
视之为空命令,不会产生编译错误。