c语言宏定义

目录

宏定义

带参数的宏

下一篇:c语言多个.c文件编译以及操作


宏定义

一、是什么?

编译预处理指令

#开头的是编译预处理指令

他们不是C语言的成分,但是C语言离不开它们

 

#define用来定义一个宏

//constdoublePI=3.14159;//c99的写法

//但是在更早的版本ANSI没有const可以用,用以下的形式

#definePI3.14159//定义一个叫PI的东西叫3.14159,也就是PI是这个宏的名字,3.14159是这个宏的值

intmain(intargc,charconst*argv[])

{

printf("%f\n",2*PI*3.0);

return0;

}

c语言在编译之前会做一次编译预处理,会把程序里所有的PI替换成后面的3.14159

使用gcc查看编译过程中的临时文件

gcc c_learn.c --save-temps

用这个命令保存编译过程中的临时文件

生成了以下这么多东西

真实的编译过程是.c->.i->.s->.o->a.out

我们用tail查看c_learn.i

会发现里面的PI全部替换成了3.14159

#define FORMAT "%f\n"

这个东西(字符串)都能换,就是纯粹的文本替换

 

特别注意:#define不能带分号; 因为这不是c的语句

 

二、这就是宏:

1、如果一个宏的值中有其他的宏的名字,也是会被替换的

2、如果一个宏的值超过一行,最后一行之前的行末需要加\

3、宏的值后面出现的注释不会被当作宏的值的一部分,空格等其他字符都会被当作宏的一部分

例子:

#define PI2 2*PI//pi*2这是注释

#define  PRT print("%f",PI); \          //这是换行宏定义\

             printf

 

#define PI 3.14159

#define PRT printf("%f\n",PI);\

printf("%f\n",PI*2)

int main(int argc,char const *argv[])

{

PRT;

return 0;

}

clion不能这么写,gcc可以这么写

 

 

三、没有值的宏

#define_DEBUG  //用于告诉编译器,我们有了这个宏了

这类宏用于条件编译的,后面有其他的编译预处理指令来检查这个宏是否已经被定义过了

就是用来判断这个宏存在不存在,编译不同的分支代码

 

四、预定义的宏

_LINE_     代表行号

_FILE_     代表源代码文件名

_DATE_     编译时候的日期

_TIME_     编译时候的时间

_STDC_     当它被定义后,编译器将按照ansic标准来编译你的c程序,这个东西不知道怎么用

都带"翅膀"

用来表达特殊的东西,让编译器替我们插入一些特殊的东西

测试

printf("%s:%d\n",__FILE__,__LINE__);

    printf("%s:%s\n",__DATE__,__TIME__);

 

带参数的宏

一、像函数的宏

#define cube(x) ((x)*(x)*(x))

cube是立方

参数是没有类型的

宏可以带参数

同样前面是名字 后面是值

示例:

#define cube(x) ((x)*(x)*(x))

int main(int argc,char const *argv[])

{

    printf("%d\n",cube(5));

    return 0;

}

也就是填入在括号里的东西都会将x替换

 int i=9;

    printf("%d\n",cube(i*5));

也可以带变量进去

 

看似很方便

但是很容易犯错误

例如:

错误定义的宏

#define RADTODEG1(x) (x*57.29578)//弧度转化成角度

#define RADTODEG2(x) (x)*57.29578

int main(int argc,char const *argv[])

{

    printf("%f\n",RADTODEG1(5+2));//我们以为是7*57.29578,结果是5+2*57.29578

    printf("%f\n",180/RADTODEG2(1));//以为是180/(57.29578*1)结果是180/1*57.29578

归根结底还是因为括号里面的东西是直接粗暴的替换了x

所以有以下原则

一切都要括号

整个值要括号

参数出现的每个地方都要括号

改进:

#define RADTODEG2(x) ((x)*57.29578)

 

同样可以带多个参数

例如:

#define MIN(a,b) ((a)>(b)?(b):(a))

也可以组合(嵌套其他宏)

 

还有最后一定不要加分号

 

这种宏在大型程序代码中使用非常普遍

可以非常复杂,如"产生"函数

在#和##这两个运算符的帮助下

存在中西方文华差异(西方用的多,中方少)

部分宏(带参数的)会被inline函数替代,inline虽然是个函数但没有函数调用时的额外开销,且会参数类型检查

 

其他编译预处理指令

例如:

条件编译

error

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值