C语言宏的定义与使用方法是什么
导读:本文共2903字符,通常情况下阅读需要10分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要: 一、C语言中的宏定义#define是预处理器处理的单元实体之一#define 定义的宏可以出现在程序的任意位置#define 定义之后的代码都可以使用这个宏#define 定义的宏常量可以直接使用#define 定义的宏常量本质为字面量下面的宏常量定义正确吗?编写代码来测试:#defineERROR-1#definePATH1"D:\test\tes... ...
目录
(为您整理了一些要点),点击可以直达。一、C语言中的宏定义
#define是预处理器处理的单元实体之一
#define 定义的宏可以出现在程序的任意位置
#define 定义之后的代码都可以使用这个宏
#define 定义的宏常量可以直接使用
#define 定义的宏常量本质为字面量
下面的宏常量定义正确吗?
编写代码来测试:
#defineERROR-1#definePATH1"D:\test\test.c"#definePATH2D:\test\test.c#definePATH3D:\test\test.cintmain(){interr=ERROR;char*p1=PATH1;char*p2=PATH2;char*p3=PATH3;}
先使用gcc -E Test.c -o Test.i 进行预编译,预编译没有报错,结果如下:
#1"Test.c"#1"<built-in>"#1"<command-line>"#1"Test.c"intmain(){interr=-1;char*p1="D:\test\test.c";char*p2=D:\test\test.c;char*p3=D:\testtest.c;}
直接进行编译,发现 char* p2 = PATH2; char* p3 = PATH3; 报错
这说明宏定义是正确的,但是编译是过不了的,只是
#define PATH2 D:\test\test.c
#define PATH3 D:\test\
不符合语法规范。
二、宏定义表达式
#define 表达式的使用类似函数调用
#define 表达式可以比函数更强大
#define 表达式比函数更容易出错
强大之处其中之一就是可以求数组的大小,这是不能编写函数办到的。
下面看一段宏表达式的代码:
#include<stdio.h>#define_SUM_(a,b)(a)+(b)#define_MIN_(a,b)((a)<(b)?(a):(b))#define_DIM_(a)sizeof(a)/sizeof(*a)intmain(){inta=1;intb=2;intc[4]={0};ints1=_SUM_(a,b);ints2=_SUM_(a,b)*_SUM_(a,b);intm=_MIN_(a++,b);intd=_DIM_(c);printf("s1=%d\n",s1);printf("s2=%d\n",s2);printf("m=%d\n",m);printf("d=%d\n",d);return0;}
下面为输出结果,但是 s2 我们预期的结果应该是 9,m 的值我们预期的结果应该是 1,这是怎么回事呢?
下面进行预编译看看代码到底是怎么运行的,输入 gcc -E Test.c -o Test.i
intmain(){inta=1;intb=2;intc[4]={0};ints1=(a)+(b);ints2=(a)+(b)*(a)+(b);intm=((a++)<(b)?(a++):(b));intd=sizeof(c)/sizeof(*c);printf("s1=%d\n",s1);printf("s2=%d\n",s2);printf("m=%d\n",m);printf("d=%d\n",d);return0;}
通过上面宏定义的替换,我们很容易知道为什么结果跟我们想的不一样。
三、宏表达式与函数的对比
宏表达式被预处理器处理,编译器不知道宏表达式的存在
宏表达式用“实参”完全替代形参,不进行任何运算
宏表达式没有任何的“调用”开销
宏表达式中不能出现递归定义
所以,下面递归定义就是错误的:
四、有趣的问题
宏定义的常量或表达式是否有作用域限制?(没有)
下面看一个宏作用域分析的代码:
#include<stdio.h>voiddef(){#definePI3.1415926#defineAREA(r)r*r*PI}doublearea(doubler){returnAREA(r);}intmain(){doubler=area(5);printf("PI=%f\n",PI);printf("d=5;a=%f\n",r);return0;}
下面为输出结果:
作用域的概念是针对 C 语言中的变量和函数,不针对宏。宏表达式被预处理器处理,编译器不知道宏表达式的存在。
五、强大的内置宏
宏含义示例_FILE_被编译的文件名file1.c_LINE_当前行号25_DATE_编译时的日期Jan 31 2021_TIME_编译时的时间17:01:01_STDC_编译器是否遵循标准C规范1下面看一个宏使用的综合示例:
#include<stdio.h>#include<malloc.h>#defineMALLOC(type,x)(type*)malloc(sizeof(type)*x)#defineFREE(p)(free(p),p=NULL)#defineLOG(s)printf("[%s]{%s:%d}%s\n",__DATE__,__FILE__,__LINE__,s)#defineFOREACH(i,m)for(i=0;i<m;i++)#defineBEGIN{#defineEND}intmain(){intx=0;int*p=MALLOC(int,5);LOG("Begintorunmaincode...");FOREACH(x,5)BEGINp[x]=x;ENDFOREACH(x,5)BEGINprintf("%d\n",p[x]);ENDFREE(p);LOG("End");return0;}
下面为输出结果:
可以看到宏定义是很强大的,可以打印出日期,文件名,行号,不使用宏定义很难实现。
</div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
C语言宏的定义与使用方法是什么的详细内容,希望对您有所帮助,信息来源于网络。