c语言基础知识:浅谈define

#define 定义宏 宏常量,在预处理时直接简单替换

定义宏的语法

#define 宏名称 要替换的内容

#define N 10
#define PI 3.14
#define LEN 10;           //注意不要有分号  分号也会一并替换放到代码中
#define L M 10            //表达的含义是  L  代表 M  10
#define MACRO             //单纯定义宏  没有需要替换的内容
                          //一般情况下,要替换的内容只包含一行,如果要换行,用/而不是{}
#define HELLO printf("Hello world\n");  \
              printf("你好,世界!\n");   \
              printf("中国万岁!\n")

Hello;

宏定义之后可以删除

#undef  宏               //把已经定义的宏删除

宏的作用域

宏可以在全局作用域(函数外)定义,也可以在局部作用域(函数内)定义

#define定义宏函数

定义带参数的宏

#define MACRO_NAME(ARGLIST) CONTENT

//MACRO_NAME  宏名称
//在定义函数时,函数名和 ()之间可以有空格的,但是宏函数名和()之间不能空格
#define POW1  (x)  x*x
#define POW2(x) x*x

int res = 0;
res = POW1(5);   //最终替换之后   res = (x) x*x(5);  //后续编译肯定报错
res = POW2(5);   // res = 5*5;

宏函数的参数列表,宏参数不能有类型的名,直接就是宏的参数名,在预处理时,宏参数会用实参替换宏函数的参数也是用逗号隔开。

#define SWAP1(a,b,type)  do{type tmp = a; a = b; b = tmp;}while(0)

//type va_arg(va_list ap, type);         //va_arg(ap,int)

int main(){
    int a=1024,b=9527;
    SWAP1(a,b,int);  //传递类型实参  int
    double m = 3.14,b = 5.78;
    SWAP2(m,n,double);
    return 0;
}

在宏函数中,凡是使用到宏参数的地方,都应该对宏参数加();在宏定义中,应该对需要替换的内容整体加()

#define SQU(a) a*a
#define SQUA(a) (a)*(a)
#define SQUAR(a) ((a)*(a))
int res = SQU(2+3);   //替换之后   2+3*2+3          == > 11  
res = SQU(5);         //替换之后   5*5              == > 25
res = 50/SQUA(2+3);   //替换之后   50/(2+3)*(2+3)   == > 50
res = 50/SQUAR(2+3);  //替换之后   50/((2+3)*(2+3)) == > 2

宏函数没有返回值

宏函数不能使用return,那如何实现复杂的宏函数

#define MACRO_FUC(arg)  ({可以写很复杂的逻辑;  最终的结果;})

//运行过程中,会把(宏替换内容)最终的结果当作最终的内容   进行赋值 或者 其它处理都可以

#define MACRO(a,b)  ({  \
          int m = a ,n = b;\
          while(m%n){\
              int t = m%n;\
              m = n; \
              n = t; \
          }  \
          n;  \
})
//这里取n的值作为宏最后的内容

int x = 6,b = 9;
int res = MACRO(x,y);   //res=3

宏的一些应用

#创建字面值字符串

#define STR(s)  #s   //在s首尾加上"",把数值、标识符变成字面值字符串

STR(1234);        //"1234"
STR(abc1234);     //"abc1234"
STR("abc");       //""abc""

##创建标识符

#defince CONCAT(n,m)  n##m  //把标识符连接到一起形成一个新的标识符

int CONCAT(age,1) = 18;   //int age1 = 18;
printf("%d\n",age1);    

可变长参数的宏

当需要打印比较多的参数内容时,尤其是某些信息需要重复打印成百上千次时,用printf打印就比较麻烦。例如输出日志信息,当文件较多时,为了方便查找问题,不可避免的需要在日志信息中打印除了错误之外的信息(文件信息,位置信息,时间信息等等),为了方便能在每次打印语句自动输入这些信息,可以用可变长参数的宏实现。

printf("file[%s] line[%d]:  %s connected server!\n",__FILE__,__LINE__,ip);    //xxxx.c  207  xx.xx.xx.xx connected server!      一般实现语句
#define log(format,...)  printf("[%s %d] "format,__FILE__,__LINE__,##__VA_ARGS__)
#define log(format,args...)  printf("[%s %d] "format,__FILE__,__LINE__,##args)
//使用宏定义后就简单很多
log("%s connected server!\n",ip);

以上就是define宏的简单介绍以及一些应用。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值