C/C++宏的用法有很多,让我们来全面的了解#define语句
#define语句的真正用法是文本的简单替换。可以用来定义有参宏,无参宏和各种乱七八糟宏。
有参宏和无参宏的定义
|
|
很简单对吧,你可以传入任意的文本进去,宏会帮你替换,比如
|
|
会被替换成
|
|
当然呢如果要想可以运行的话需要有变量a
定义常量
宏也可以定义常量,其实我个人认为他是定义“常数”,因为它定义的常量在内存中并不占据空间。而是const定义的才占有空间。因为宏是简答替换嘛,所以也没什么可说的
|
|
宏里面的特殊符号
宏里面是可以使用特殊符号的,比如#,##,#@,\四个符号。
#符号
#符号是用来将有参宏里的参数变成字符串的。比如#define macro(varname) #varname
这个宏,如果你调用macro(hello)
会返回字符串"hello"。
##符号
##符号是将有参宏里面的变量和其他变量或者字符绑在一起的。比如宏#define macro(str1,str2) str1##str2
调用macro(a,b)
会产生ab。但是不会加上双引号,因为只是绑在一起,不是变成字符串。也可以和字符绑在一起:
#define macro(a) x##a
调用macro(2)
产生x2。
#@符号
这个符号将后面的变量加上单引号,其实和#符号差不多,只不过加上的是单引号
\符号
换行符号,如果宏太多一行写不下可以在行末使用这个换行。但是\后面除了换行符之外不可以有别的字符,连空格都不可以。
有了这些特殊符号,我们可以写出很多很方便的宏,比如:
|
|
这个用来调试变量,输出变量名和变量的值
|
|
这个用于在类里面声明一个public变量并给出初值。
连接字符串的方式
你只需要将两个字符串放在一起(或者代表字符串的宏),就可以连接这两个字符串:
|
|
需要注意的是两个字符串之间必须有空格
编译器预定义的宏
编译器自己也定义过一些宏:
- 通用宏
__FUNC__
:当前行存在哪一个函数里面__DATE__
:最后一次编译的日趋__TIME__
:最后一次编译的时间__FILE__
:这个文件的文件名称__LINE__
:这个宏所在的行号_TIMESTAMP_
:最后一次修改当前文件的时间戳
这些一般都是通用的,但是如果是不同的编译器的话,还会给出一些有关操作系统和语言的宏:
- 关于操作系统
__APPLE__
:苹果系统会给出这个宏表示编译代码的编译器在苹果公司的系统上,但是没有说明是在MacOS还是IOS上,所以你还需要包含苹果系统的头文件"TargetConditionals.h",这个头文件里面有一些宏供你使用:TARGET_OS_X
:MacOS系统TARGET_OS_IPHONE
:IOS系统 还有很多的其他的宏就不一一列举了,具体见这里
__linux
,linux
,__linux__
:表示是linux系统,不同的编译器给出的宏不一样,基本上在这三个之内WIN32
,__WIN32
,__WIN32__
:表示windos系统__ANDROID__
:安卓系统__MINGW32__
:MINGW编译器__ORBITS__
:PS4平台__CYGWIN__
:cygwin编译器_MSC_VER
:vc++__BORLANDC__
:BorlandC编译器__JETBRAINS_IDE__
:jetbrains公司的IDE(一般都是CLION啦),这个宏本身的值表示是哪一版的IDE。
接下来就是关于语言的宏
- 关于语言的宏
__cplusplus:表示使用C++编译,其中__cplusplus这个宏本身的值就代表了使用的C++标准: c++98: 199711 c++03: 199711 c++11: 201103 c++14: 201402 c++17: 201703 对于微软,你需要判断这个宏
_MSVC_LANG
- 其他有意思的宏
__COUNTER__
:这个宏会随着它的每次出现而自增1,初始值为0. 比如你这么写:
|
|
那么会输出
|
|
__has_include()
这个宏里面放入头文件,他会检查你的头文件搜索路径中有没有这个文件。系统路径使用<>,自定义路径使用””,比如:
|
|