宏定义#define详解

1. # define主要功能

image
  • c语言中用到很多宏定义 ,为了头文件被重复用到#ifndef #define,#ifdefine edfif等条件编译
  • 宏不是语句,结尾不用加“;”,否则会被替换进进程中
  • "#'' 表示这是一条预处理指令
  • 如果写宏不止一行,则在结尾加反斜杠使多行能连接上,但第二行要对齐,否则空格也会作为替换文本的一部分

2.无参宏

  • 无参宏即宏名之后不带参数,只是简单的文本替换
  • typedef与#define区别
    • 两者都可以表示数据类型 1 #define INIT1 int 2 typedef in UINT2
    • 但有时候也会有区别比如定义指针类型的变量时
#define INT1 int *
typedef int * INT2;
INT1 a1, b1;
INT2 a2, b2;
INT1 a1,b1;被替换后为 int *a1,b1,
即一个指向int类型的指针一个int类型的变量;
INT2  a2,b2;   则是两个指向int类型的指针;

3.有参宏

  • 带参数的宏定义,宏名中不能有空格,宏名与形参表之间也不能有空格,而形参表中形参之间可以有空格
    • 有参宏实现一个数的平方
#define COUNT(M) M*M 
int x=6;
print(COUNT(x+1));
print(COUNT(++X));
结果输出:13   和56,而不是函数的输出49
  • 原因在于预编译器不进行技术,只是进行简单的文本替换,COUNT(x+1)被替换成COUNT(x+1*x+1);
  • CUNT(++x)被替换成++x++x即为78=56而不是想要的7*7=49,连续前置自加加两次;
  • 解决办法是用括号将整个替换文本及每个参数用括号括起来但即便是加上括号也不能解决第二种情况,所以解决办法是尽量不使用++,-等符号;
  • 函数实现一个数的平方
int count(int x)
{
return x*x
}

  • 有参宏与函数区别
    • 在宏定义#define COUNT(M) M*M中的形参不分配内存单元,不做类型定义,只是简单的文本替换,而函数int count(int x)中形参x是局部变量,会在栈区分配内存单元,所以要做类型定义,而且实参与形参之间是值传递。而宏只是符号代换,不存在值传递。

  • 宏定义也可以定义表达式或多个语句
#define AB(a,b) a=i+5;b=j+3;   宏定义多个语句
int i=3,j=5;
int m-0,n=0;
AB(m,n);       //宏替换后为m=i+5,n=j+3;
print("m=%d,n=%d",m,n);
输出结果:m=8,n=8

4.#运算符

  • '#' 的作用就是将#后边的宏参数进行字符串的操作,也就是将#后边的参数两边加上一对双引号使其成为字符串。例如a是一个宏的形参,则替换文本中的#a被系统转化为"a",这个转换过程即为字符串化。
#define TEST(param) #param
char *pStr=TEST(123);
printf("pSrt=%s\n",pStr);
输出结果为字符  ”123“

5.##运算符

  • '##' 运算符也可以用在替换文本中,它的作用起到粘合的作用,即将两个宏参数连接为一个数
#define TEST(param1,param2) (param1##param2)
int num =TEST(12,34);
printf("num=%d\n",num);
输出结果为:num=1234

6.可变宏:...和VA_ARGS

  • 作用主要是为了方便管理软件中的打印信息。在写代码或DEBUG时通常需要将一些重要参数打印出来,但在软件发行的时候不希望有这些打印,这时就用到可变参数宏了。
# define PR(...) printf(_VA_ARGS_)
PR("hello\n");
输出结果:hello

*   在宏定义中,形参列表的最后一个参数为省略号...,而“_VA_ARGS_”被用在替换文本中,来表示省略号...代表了什么。


#define PR1(X,...) printf("Message"#X":"_VA_ARGS_)
double mes=10;
PR1(1,"msg=%.2f\n",msg);

输出结果:Message1:msg=10.00

宏替换后为:printf(Message""1""msg=%.2f\n",msg);
  • 需要注意的是:省略号...只能用来替换宏的形参列表中的最后一个。如#define PR1(x,...,y)则是错误的。

7.成熟软件中常用的宏定义。

  • 防止头文件被重复包含
#ifndef COMDEF_H 
#define COMDEF_H
//头文件的内容

#endif
  • 得到一个制定地址上的一个字节或字
 #define MEM_B(X) (*((byte*)(x)))
 #define MEM_W(X) (*((word*)(x)))
  • 求最大值与最小值
 #define MAX(x,y)  ((x)>(y)?(x):(y))
 #define MIN(x,y)  ((x)<(y)?(x):(y))
  • 得到一个结构体中field所占用的字节数
 #define FSIZ(type,field)  sizeof(((type*)0)->field)
  • 得到一个field在结构体中的偏移量
 #define FPOS(type,field)\
                     ((dword)&(((type*)0)->field)
  • 按照LSB格式把两个字节转化为一个word
 #define FLIPW(ray) (((word)(ray)[0]*256)+(ray)[1])
  • 按照LSB格式将一个WORD转化为两个字节
 #define FLOPW(ray,val)  (ray)[0]=((val)/256);(ray)[1]=((val)&0xFF)
  • 得到一个变量的地址
 #define B_PTR(var) ((byte*)(void*)&(var))
 #define W_PTR(var) ((word*)(void*)&(var))
  • 得到一个字的高位与低位字节
 #define WORD_LO(xxx) ((byte)((word)(xxx)&255))
 #define WORD_HI(xxx) ((byte)((word)(xxx)>>8))
  • 用宏得到一个数组所含的元素个数
 #define ARR_SIZE(a) (sizeof(a)/sizeof((a)[0]))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,458评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,030评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,879评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,278评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,296评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,019评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,633评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,541评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,068评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,181评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,318评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,991评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,670评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,183评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,302评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,655评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,327评论 2 358

推荐阅读更多精彩内容