原创 c编译的伪指令

2009-5-1 17:58 2012 9 9 分类: MCU/ 嵌入式
    一般变量定义在*.c文件中,而*.h文件中声明变量或函数名和符号名.

避面重复编译的解决方法:

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

    一般格式是这样的:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


    #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))
    关键是十分容易产生错误,包括机器和人理解上的差异等等。

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
9
关闭 站长推荐上一条 /3 下一条