c宏二三事

1.     宏定义的次序

宏定义对定义位置之后的代码段有效。

#include <stdio.h>

int main(){

        char X = 'a';

        char c1 = X;

        printf("%c\n",c1);

        #define X 4

        int i = X;

        printf("%d\n",i);

}

输出结果为a4.

看如下代码:

#include <stdio.h>

#define TABLESIZE BUFSIZE

#define BUFSIZE 1024

int main(){

        printf("%d\n",TABLESIZE);

 

}

输出是1024

在定义TABLESIZE之前,BUFSIZE并没有定义,程序却能正确输出,原因在于,宏在使用的过程中才被解析,因此,在printf调用时,需要解析TABLESIZE,发现里面有另外一个宏BUFSIZE,继续解析BUFSIZE,最终输出1024.

2.     复杂宏函数定义方式

下面的例子通不过编译:

#include <stdio.h>

#define SAYHELLO(){printf("%s\n","hello");}

int main(){

        int isSayHello = 0;

        if(isSayHello)

                SAYHELLO();

        else

                printf("%s\n","good bye");

}

定义了宏函数SAYHELLO,并且在内部输出hello,在主函数中定义isSayHello变量,如果不为0就执行宏SAYHELLO,如果为0,就输出good bye。上面的代码是通不过编译的,编译器给出error: 'else' without a previous 'if'的错误,意思是说,else前面没有if语句。原因在于if语句后面是{printf("%s\n","hello");}语句,紧接着后面又跟了个;,表示空语句。

正确的书写方式为:

        if(isSayHello)

                SAYHELLO()

        else

                printf("%s\n","good bye");

c语言代码中,有一行调用后面竟然没有;,很多人看代码的时候都会认为是个异常,这种代码方式的确不美观,可以采用do … while的形式解决问题,如下:

#define SAYHELLO() do{printf("%s\n","hello");}while(0)

此时代码中就可以写成

if(isSayHello)

                SAYHELLO();

        else

                printf("%s\n","good bye");

更符合c语言的规则。

使用do…while(0)的形式主要是处理很复杂的代码片段,如果不复杂,直接放到后面或者加个()也是ok的。

3.     #号在宏中的作用

#号在宏中可以将参数做字符串输出。

#include <stdio.h>

#define WARN_IF(EXP)\

        do{if(EXP)\

                printf("%s\n",#EXP);}\

        while(0)

int main()

{

        int x = 0;

        WARN_IF(x==0);

}

输出结果:x==0

需要注意的是,如果参数是宏,那么只能输出宏的名字,而不是值。

#include <stdio.h>

#define STR(s) #s

#define SIZE 1024

int main()

{

        int x = 0;

        printf("%s\n",STR(SIZE));

}

输出结果为:SIZE

如果需要输出宏的值,可以使用如下形式:

#include <stdio.h>

#define STRX(S) STR(S)

#define STR(s) #s

#define SIZE 1024

int main()

{

        int x = 0;

        printf("%s\n",STRX(SIZE));

}

 

##在宏里面表示连接的意思,即使传入的参数是数字,也会被连接在一起。

#include <stdio.h>

#define COMPLEX(X) (X##X)

int main()

{

        int x = 0;

        printf("%d\n",COMPLEX(10));

}

输出1010

4.     可变参数的宏

#include <stdio.h>

#define PRINT(...) fprintf(stderr,__VA_ARGS__)

 

int main()

{

        int x = 0;

        PRINT("%s:%d\n","x",x);

}

输出:x:0

或者将宏写成

#define PRINT(args…) fprintf(stderr,args)

5 宏参数是函数

如果宏参数是函数的时候,你最好写成这个样子:

#define MIN(X,Y) \

        ({typeof(X) x_ = (X);\

          typeof(Y) y_ = (Y);\

          (x_<y_)?x_:y_;})

原因是,如果你写成这样:

#include <stdio.h>

#define MIN(X,Y) ((X)<(Y)?(X):(Y))

int getx(){

        static int x = 0;

        return x++;

}

 

int main()

{

        int y = 1;

 

        MIN(getx(),y);

 

        printf("%d",getx());

}

结果是2

调用一次宏,会调用两次函数。

参考:http://gcc.gnu.org/onlinedocs/cpp/Macros.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值