C语言宏定义#define的使用
目录
- 无参宏定义
- 定义形式
- 带参宏定义
- 定义形式
- #和##运算
- #运算 用法:
- ##运算 用法:
- 变参宏
- #ifndef 条件编译
宏定义命令:define
优点:方便程序的修改,同时也能提高程序的运行效率。
宏定义一般有两种形式:无参宏定义和带参宏定义。
无参宏定义
定义形式
#define 标识符 字符串
注意:
1.宏定义是用宏名来表示一个字符串,在宏展开时以该字符串取代宏名,只是简单的替换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理不作任何检查。只在编译时检查。
2.宏定义行末不必加分号(除非你的宏内容中需要有分号)。
3.宏定义必须写在函数之外,作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#undef命令
例1:输入圆的半径输出圆的周长和面积
#include #define PI 3.14 int main(){int r; printf("输入半径:"); scanf("%d",&r); printf("圆的周长为:%.2f,面积为:%.2f",2*PI*r,PI*r*r); return 0; }
预处理阶段进行宏替换↓:
#include int main(){int r; printf("输入半径:"); scanf("%d",&r); printf("圆的周长为:%.2f,面积为:%.2f",2*3.14*r,3.14*r*r); return 0; }
代码输出:
文章图片
例2:通过宏定义输出字符串
#include #define HELLO "Hello,"#define WORLD "World!"int main(){printf(HELLO WORLD); return 0; }
预处理阶段进行宏替换↓:
#include int main(){printf("Hello," "World!"); return 0; }
代码输出:
文章图片
例3:请问如下代码S1和S2的输出是否相等
#include #define S1 3+4#define S2 (3+4)int main(){printf("S1:%d\n",S1*5); printf("S2:%d\n",S2*5); return 0; }
预处理进行宏替换↓(这里就体现出了直接替换并不会因为你的宏先定义就先计算,而是替换后再做后续处理):
#include #define S1 3+4#define S2 (3+4)int main(){printf("S1:%d\n",3+4*5); printf("S2:%d\n",(3+4)*5); return 0; }
代码输出:
文章图片
带参宏定义 定义形式
#define 宏名(形参表) 字符串
例1:M(3)==N(3)?M(3+2)==N(3+2)?
#include#defineM(y)((y)*(y)+3*(y))#defineN(y)(y*y+3*y)int main(){ printf("M(3):%d\n",M(3)); printf("N(3):%d\n",N(3)); printf("M(3+2):%d\n",M(3+2)); printf("N(3+2):%d\n",N(3+2)); }
预处理阶段进行宏替换↓(这个例题主要是为了提醒大家如果要用宏定义进行一些计算,最好将参与计算的所有变量都加上括号以防本题中的情况出现):
#include#defineM(y)((y)*(y)+3*(y))#defineN(y)(y*y+3*y)int main(){ printf("M(3):%d\n",((3)*(3)+3*(3))); printf("N(3):%d\n",(3*3+3*3)); printf("M(3+2):%d\n",((3+2)*(3+2)+3*(3+2))); printf("N(3+2):%d\n",(3+2*3+2+3*3+2)); }
代码输出:
文章图片
例2:通过宏来计算数组中元素个数
#include#include#include#define Size_Array(b) sizeof(b)/sizeof(b[0])int main(){ int i; srand((unsigned)time(NULL)); int b[i=rand()%100]; printf("随机数为:%d 数组元素个数为:%d",i,Size_Array(b)); }
预处理阶段进行宏替换↓(很经典的面试小题):
#include#include#includeint main(){ int i; srand((unsigned)time(NULL)); int b[i=rand()%100]; printf("随机数为:%d 数组元素个数为:%d",i,sizeof(b)/sizeof(b[0])); }
代码输出:
文章图片
#和##运算
#运算 用法:
# 运算符的用处就是把符号转化为字符串。例如,如果 a 是一个宏的形参,则替换文本中的 #a 则被系统转化为 “a”。
#include #define TO_STR(s) #sint main(){printf(TO_STR(HelloWorld!)); return 0; }
代码输出:
【C语言宏定义#define的使用】
文章图片
##运算 用法:
## 运算符可以用在替换文本中,而它的作用是起到粘合的作用,即将两个符号组合成一个符号。
#include #define CONCAT(x,y) x##yint main(){printf("%d", CONCAT(1,000)); return 0; }
代码输出:
文章图片
变参宏 用法:
当要调用printf类似不确定参数格式时可以使用__VA_ARGS__,在宏定义中,形参列表的最后一个参数为省略号“…”,“__VA_ARGS__”就可以被用在替换文本中,来表示“…”代表了什么。
#define PR(...) printf(__VA_ARGS__)//宏定义PR("hello\n"); //宏调用
例:
#include #define P(X, ...) printf("get:"#X":"__VA_ARGS__)int main(){int j=20,i=10; P(10, "j = %d\n", j); P(10, "j = %d i=%d\n", j,i); return 0; }
代码输出:
文章图片
#ifndef 条件编译 #ifndef 的最主要目的是防止头文件的重复包含和编译。
c语言中,对同一个变量或者函数进行多次声明不会报错。所以如果.h文件里进行了声明工作,不使用# ifndef宏定义,多个c文件包含同一个.h文件也不会报错。
然而c++中,#ifdef的作用域只是在单个文件中。所以如果.h文件里定义了全局变量,即使采用#ifdef宏定义,多个.c文件包含同一个.h文件就会出现全局变量重定义的错误。
使用#ifndef可以避免这种错误:
#ifndef x//先测试x是否被宏定义过#define xcode1//如果x没有被宏定义过,定义x,并编译code1#endifcode2//如果x已经定义过了则编译code2,跳过code1
适当的使用条件编译和宏定义可以让代码的运行效率更高,特别是在进行大项目的时候当某个数值使用次数较多且修改比较频繁的情况下,宏定义也是比较高效的(当然函数也可以,等有时间写完函数再来比较一下函数和宏的优缺点吧)
到此这篇关于C语言宏定义#define的使用的文章就介绍到这了,更多相关C语言宏定义#define内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- java|JAVA语言的产生与发展史
- java是编译语言么_Java是编译语言还是解释编程语言()
- 【C/C++】C语言基础知识【第二版】
- c语言|《数据结构初阶》实现顺序循环队列和链式队列
- c语言|《伏C录》凝丹篇-函数栈帧理解手册
- c语言|《伏C录》凝气篇-初战动态内存管理四兄弟
- c语言|《伏C录》破劫篇-零基础无境界限制极速领悟指针与数组
- c语言|C语言实现扫雷(含展开,附源码)
- c语言|《伏C录》神兵百解篇-重铸struct关键字之心
- C语言基于EasyX库实现有图形界面钟表