c++中define用法
c++中define用法
define在c++语言中用法比较多,这里对其进行整理。
1.无参宏定义
无参宏的宏名后不带参数。
其定义的一般形式为:
#define 标识符 字符串
1
其中的“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。
例如:
#define MAXNUM 99999
这样MAXNUM就被简单的定义为99999。
2.有参宏定义
C++语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。
对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。
带参宏定义的一般形式为:
#define 宏名(形参表) 字符串
1
在字符串中含有各个形参。在使用时调用带参宏调用的一般形式为:宏名(实参表);
例如:
#define add(x, y) (x + y)
int main()
{
cout << "1 plus 1 is " << add(1, 1.5) << ".\n";
//输出“1 plus 1 is 2.5.”
system("pause");
return(0);
}
这个“函数”定义了加法,但是该“函数”没有类型检查,有点类似模板,但没有模板安全,可以看做一个简单的模板。
注意:该“函数”定义为(a + b),在这里加括号的原因是,宏定义只是在预处理阶段做了简单的替换,如果单纯的替换为a + b时,当你使用5 * add(2, 3)时,被替换为5 * 2 + 3,值为13,而非5 * (2 + 3),值为25。
3.宏定义中的特殊操作符
define 中的特殊操作符有#,##和… and __VA_ARGS__
(1)#
假如希望在字符串中包含宏参数,ANSI C允许这样作,在类函数宏的替换部分,#符号用作一个预处理运算符,它可以把语言符号转化程字符串。例如,如果x是一个宏参量,那么#x可以把参数名转化成相应的字符串。该过程称为字符串化。
例如:
#incldue <stdio.h>
#define PSQR(x) printf("the square of" #x "is %d.\n",(x)*(x))
int main(void)
{
int y =4;
PSQR(y);
//输出:the square of y is 16.
PSQR(2+4);
//输出:the square of 2+4 is 36.
return 0;
}
(2)##
##运算符可以用于类函数宏的替换部分。另外,##还可以用于类对象宏的替换部分。这个运算符把两个语言符号组合成单个语言符号。
例如:
#include <stdio.h>
#define XNAME(n) x##n
#define PXN(n) printf("x"#n" = %d\n",x##n)
int main(void)
{
int XNAME(1)=12;//int x1=12;
PXN(1);//printf("x1 = %d\n", x1);
//输出:x1=12
return 0;
}
(3)可变参数宏 …和__VA_ARGS__
__VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。
实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点)。这样预定义宏__VA_ARGS__就可以被用在替换部分中,替换省略号所代表的字符串。
例如:
#define PR(...) printf(__VA_ARGS__)
int main()
{
int wt=1,sp=2;
PR("hello\n");
//输出:hello
PR("weight = %d, shipping = %d",wt,sp);
//输出:weight = 1, shipping = 2
return 0;
}
省略号只能代替最后面的宏参数。
#define W(x,…,y)错误!
但是支持#define W(x, …),此时传入的参数个数必须能够匹配。
这里再介绍几个系统的宏:
1) __VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。宏前面加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的”,”去掉的作用,否则会编译出错, 你可以试试。
2) __FILE__ 宏在预编译时会替换成当前的源文件名
3) __LINE__宏在预编译时会替换成当前的行号
4) __FUNCTION__宏在预编译时会替换成当前的函数名称
4.宏定义中的多行定义
非常经典。
#define MACRO(arg1, arg2) do { /
/* declarations */ /
stmt1; /
stmt2; /
/* ... */ /
} while(0) /* (no trailing ; ) */
记得要在每一个换行的时候加上一个”/”
5.宏定义中的条件编译
在大规模的开发过程中,特别是跨平台和系统的软件里,define最重要的功能是条件编译。
#ifdef WINDOWS
......
(#else)
......
#endif
#ifdef LINUX
......
(#else)
......
#endif
可以在编译的时候通过#define设置编译环境。
6.如何取消宏
//定义宏
#define [MacroName] [MacroValue]
//取消宏
#undef [MacroName]
7.防止重复包含头文件
由于头文件包含可以嵌套,那么C文件就有可能包含多次同一个头文件,就可能出现重复定义的问题的。
通过条件编译开关来避免重复包含(重复定义)
例如:
#ifndef __headerfileXXX__
#define __headerfileXXX__
…
文件内容
…
#endif
小结及说明
1) 宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现。
2) 宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起置换。
3) 宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#undef命令。只要函数定义在#undefine之后,则函数无法使用#define的内容。
4) 宏名在源程序中若用引号括起来,则预处理程序不对其作宏代换。
5) 宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名。在宏展开时由预处理程序层层代换。
例如:
#define PI 3.1415926
#define S PI*y*y /* PI是已定义的宏名*/
6) 习惯上宏名用大写字母表示,以便于与变量区别。但也允许用小写字母。
7) 可用宏定义表示数据类型,使书写方便。
应注意用宏定义表示数据类型和用typedef定义数据说明符的区别。
宏定义只是简单的字符串代换,是在预处理完成的,而typedef是在编译时处理的,它不是作简单的代换,而是对类型说明符重新命名。被命名的标识符具有类型定义说明的功能。
请看下面的例子:
#define PIN1 int *
typedef (int *) PIN2;
1
2
从形式上看这两者相似, 但在实际使用中却不相同。
下面用PIN1,PIN2说明变量时就可以看出它们的区别:
PIN1 a,b;在宏代换后变成:
int *a,b;
表示a是指向整型的指针变量,而b是整型变量。
然而:
PIN2 a,b;
表示a,b都是指向整型的指针变量。因为PIN2是一个类型说明符。由这个例子可见,宏定义虽然也可表示数据类型, 但毕竟是作字符代换。在使用时要分外小心,以避出错。
8) 对“输出格式”作宏定义,可以减少书写麻烦。
例如:
#define P printf
#define D "%d\n"
#define F "%f\n"
main(){
int a=5, c=8, e=11;
float b=3.8, d=9.7, f=21.08;
P(D F,a,b);
P(D F,c,d);
P(D F,e,f);
}
9)带参宏定义中,宏名和形参表之间不能有空格出现。
10)在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。而宏调用中的实参有具体的值。要用它们去代换形参,因此必须作类型说明。这是与函数中的情况不同的。在函数中,形参和实参是两个不同的量,各有自己的作用域,调用时要把实参值赋予形参,进行“值传递”。而在带参宏中,只是符号代换,不存在值传递的问题。
11)在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。
c++中define用法相关推荐
- C++中#define用法
http://blog.sina.com.cn/s/blog_686188ef0100klku.html #define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一 ...
- php中define的参数_php中define的用法有哪些
php中define的用法:1.[define()]函数定义一个常量:2.定义常量名称及值,代码为[define(name,value,case_insensitive)]:3.定义一个大小写敏感的常 ...
- C++中 #define的用法
C++中 #define的用法 转自:http://blog.csdn.net/lyl_98/article/details/900158 今天整理了一些#define的用法,与大家共享! 1.简单的 ...
- #define 用法
#define用法 收藏 1.简单的define定义 #define MAXTIME 1000 一个简单的MAXTIME就定义好了,它代表1000,如果在程序里面写 if(i<MAXTIME){ ...
- [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法
一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...
- C:#define用法
#define用法 C语言中,可以用 #define 定义一个标识符来表示一个常量. 其特点是:定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了. 预编译又叫预处理.预编译不是编译 ...
- c++ 预处理命令 #define用法
预处理命令 #define用法 #define命令 #define命令 #define命令用于把指定的字符串替换文件中的宏名称 . 也就是说, #define使编译器把文件中每一个macro-name ...
- const在c中的用法
常量和变量的样子完全一样,只是常量的值不允许被修改.我们用const这个关键字来声明一个常量. 例: const int a=10; int cons ...
- sql中变量用法_SQL变量:基础和用法
sql中变量用法 In this article, we will learn the notions and usage details of the SQL variable. In SQL Se ...
最新文章
- linux中的for命令
- 爱立信华为MWC展前叫阵:5G成重头戏
- 洛阳综合保税区正式获国务院批复同意设立
- laravel 5.5 顶部带条件分页查询
- STM32开发 -- 串口详解
- java服务端项目开发规范
- hbuilderx写Ajax,Hbuilder怎么使用ajax?求指教啊
- 就地链表反转_链表常见问题总结(一)
- 2017.9.23 循环格 思考记录
- [设计模式-行为型]责任链模式(Chain of Responsibility)
- redis key命名规范_公司内部 Redis 使用规范
- 一本关于网上支付解决方案的迷你百科全书
- zwPython,字王集成式python开发平台,比pythonXY更强大、更方便。
- Ubuntu 16.04 安装monaco字体
- 无聊之时用css3自制了好看的button样式和input样式
- CentOS7安装oh-my-zsh(github start Top 10)
- 利用python下载视频
- 大学计算机网课怎么上,大学计算机课程学习路线应该是怎么样的呢?
- V4L2采集视频数据
- 机器学习SVM——实验报告
热门文章
- Apache配置域名转发
- charm-bracelet
- 手把手教你逆向分析android程序
- [APIO2010]特别行动队——[斜率优化DP]
- 提高总账和日记账导入的性能
- JavaScript中Textarea滚动条不能拖动的问题
- ChatGPT 的情感智能:机器人是否能够感受到情绪?
- C#:EF与ORM的详解。
- 微信公众号读芯术中的python_你好,程序员;再见,交易者!Jupyter即是新的Excel...
- Java用蚁群算法求最短路径_蚁群算法最短路径java