C编译的伪指令

常用的预处理命令如下:

#define             
定义一个预处理宏
#undef              
取消宏的定义

#include           
包含文件命令
#include_next   与#include相似, 但它有着特殊的用途

#if                      编译预处理中的条件命令, 相当于C语法中的if语句
#ifdef                判断某个宏是否被定义, 若已定义, 执行随后的语句
#ifndef             与#ifdef相反, 判断某个宏是否未被定义
#elif                  若#if, #ifdef, #ifndef或前面的#elif条件不满足, 则执行#elif之后的语句, 相当于C语法中的else-if
#else                与#if, #ifdef, #ifndef对应, 若这些条件不满足, 则执行#else之后的语句, 相当于C语法中的else
#endif              #if, #ifdef, #ifndef这些条件命令的结束标志.
defined            与#if, #elif配合使用, 判断某个宏是否被定义

#line                标志该语句所在的行号
#                      将宏参数替代为以参数值为内容的字符窜常量
##                   将两个相邻的标记(token)连接为一个单独的标记
#pragma        说明编译器信息

#warning       显示编译警告信息
#error            显示编译错误信息

 

 

 

 

 

 

 

一般变量定义在*.c文件中,而*.h文件中声明变量或函数名和符号名.

避面重复编译的解决方法:
    比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件都要调用同一个头文件去编译,重复编译会产生大量的声明冲突。解决这个问题的方法使用#ifndef, #endif, #endif。
    一般格式是这样的:

    #ifndef <标识>

    #define <标识>

    ...  (插入头文件内容)

    #endif
    <标识>在理论上来说可以是自由命名的,但每个头文件的这个“标识”

都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划

线,并把文件名中的“.”也变成下划线,如:stdio.h 写成下面这样:

    #ifndef _STDIO_H_

    #define _STDIO_H_

    ...
    #endif 
条件编译
    一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”。有时,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。 条件编译常用 #ifdef,#else,#endif,#if等进行说明。
    一般有3种情况使用:
    情况1:
    #ifdef _XXXX
    ...程序段1...
    #else
    ...程序段2...
    #endif
    这表明如果标识符_XXXX已被#define命令定义过则对程序段1进行编译;否则对程序段2进行编译。
例如:

    #define NUM
    …
    #ifdef NUM
    printf("之前NUM有定义/n");
    #else
    printf("之前NUM没有定/n");
    #endif

    如果程序开头有#define NUM这行,即NUM有定义,碰到下面#ifdef NUM的时候,当然执行第一个printf。否则第二个printf将被执行。可以很方便的开启/关闭整个程序的某项特定功能。

    情况2:
    #ifndef _XXXX
    ...程序段1... 
    #else
    ...程序段2...
    #endif
    这里使用了#ifndef,表示的是if not def。当然是和#ifdef相反的状况(如果没有定义了标识符_XXXX,那么执行程序段1,否则执行程序段2)。
    情况3:
    #if 常量
    ...程序段1...
    #else
    ...程序段2...
    #endif
    这里表示,如果常量为真(非0,随便什么数字,只要不是0),就执行程序段1,否则执行程序段2。这种方法可以将测试代码加进来。当需要开启测试的时候,只要将常量变1就好了。而不要测试的时候,只要将常量变0。
define的使用
    简单的define定义

    #define  BUTDATA 1000

    一个简单的BUTDATA就定义好了,它代表1000,如果在程序里面写

if(i< BUTDATA){.........}, 编译器在处理这个代码之前会对BUTDATA进行处理替换为1000。

    这样的定义看起来类似于普通的常量定义CONST,但也有着不同,因为define的定义更像是简单的文本替换,而不是作为一个量来使用,这个问题在下面反映的尤为突出, 只是在编译过程中起替换。

    define的“函数定义”

    define可以像函数那样接受一些参数,如下

    #define max(x,y) (x)>(y)?(x):(y);

    这个定义就将返回两个数中较大的数, 因为这个“函数”没有类型检查,就好像一个函数模板似的,当然,它绝对没有模板那么安全就是了。可以作为一个简单的模板来使用而已。但是这样做的话存在隐患,例子如下:
    #define Add(a,b) a+b;
   在一般使用的时候是没有问题的,但是如果遇到如:c * Add(a,b) * d的时候就会出现问题,代数式的本意是a+b然后去和c,d相乘,但是因为使用了define(它只是一个简单的替换),所以式子实际上变成了
c*a + b*d

   另外举一个例子:
   #define pin (int*);
   pin a,b;
   本意是a和b都是int型指针,但是实际上变成int* a,b;
a是int型指针,而b是int型变量。
这是应该使用typedef来代替define,这样a和b就都是int型指针了。

所以我们在定义的时候,养成一个良好的习惯,建议所有的层次都要加括号。

宏的单行定义

    #define ctrlbuzz(x) b_buzz=x

    假设 x=0, b_buzz=0,

    假设 x=1, b_buzz=1,

 

    define的多行定义

    define可以替代多行的代码,

    #define MACRO(arg1, arg2) do { /
    stmt1; /
    stmt2; /
    /*...*/ /
    } while(0)

    关键是要在每一个换行的时候加上一个"/"

 

在大规模的开发过程中,特别是跨平台和系统的软件里,define最重要的功能是条件编译。

就是:
    #ifdef WIN
    ...
    #endif
    #ifdef LIN
    ...
    #endif

    可以在编译的时候通过#define设置编译环境

    如何定义宏、取消宏
    定义宏
    #define
[MacroName] [MacroValue]
    取消宏
    #undef [MacroName]
    一般定义宏
    #define PI (3.1415926)

    带参数的宏
    #define max(a,b) ((a)>(b)? (a),(b))
    关键是十分容易产生错误,包括机器和人理解上的差异等等。

你可能感兴趣的:(C编译的伪指令)