C语言宏的使用
使用条件宏进行条件编译
譬如,对于同一份代码,我想编译出两个不同的版本,在其中一个版本中去掉某一部分功能,
这时可以通过条件宏判断是否编译,例:
如果不使用条件宏进行控制,想编译两个不同版本的程序,就需要保存两份源代码。
条件编译的语法和if else语法类似,必须以#endif结尾例如:
#if 常量表达式
//代码1
#elif 常量表达式
//代码2
#elif 常量表达式
//代码3
#else
//代码4
#endif
条件编译时将会根据常量表达式来求值,如果常量表达式的值为假,那么对应的代码将不会被 编译,还可以判断某个宏是否定义,例如:
#ifdef(NameOfMacro)
//代码1
#else
//代码2
#endif
如果NameOfMacro被定义,那么代码1将会参与编译,否则代码2参与编译,如下写法也是等价的:
#if defined(NameOfMacro)
//代码1
#else
//代码2
#endif
#if !defined(NameOfMacro)
//代码2
#else
//代码1
#endif
宏一般都定义在头文件中,要想使用改宏则使用#include包含该头文件即可,也可以定义在源文件中,但是这种情况比较少,一定要确保条件判断中的宏的定义位置位于条件判断之前,否则不会生效;宏的作用范围从定义它的位置开始到源文件结束,在其他源文件中该宏不可见,如果想使用某个宏,则必须使用#include指令包含对应的头文件。
除了在头文件和源文件中定义宏,还可以在定义预处理宏,
例如:在VS项目属性中
预处理宏只能是空的宏,但预处理宏作用于整个工程,对该工程中任意源文件可见,优先于任何定义在源码中的宏.
使用空宏进行说明
可以使用空宏对函数参数进行说明,微软的API中就使用了空宏,例如:
WINBASEAPI
BOOL
WINAPI
WriteFileEx(
_In_ HANDLE hFile,
_In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer,
_In_ DWORD nNumberOfBytesToWrite,
_Inout_ LPOVERLAPPED lpOverlapped,
_In_ LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
In,_Inout_定义如下:
_In_表示该参数为传入参数,Inout_表改参数为传入传出参数,为了防止_In,_Inout_被
别人定了,所以先使用#ifdef判断该宏是否被定义,如果被定义则使用#undef取消定义,然后
在重新定义该宏。
#和##运算符
除了#define 标识符 记号序列 这种形式定义宏,还可以定义带有参数的宏,形式如下:
#define 标识符(标识符列表(可选)) 记号序列,
在定义带有形参的宏定义中,#和##将会影响宏替换的过程,如果记号序列中某一个参数前
面有一个#,那么替换时将会在这个参数前后插入",将其变成一个字符串,即使该参数是
另一个带参宏,也不会在进行宏展开替换;如果该参数为一个字符串常量,那么预处理器会
分别为字符串前后的"号进行转义,将"变成字符,然后在前后各插入一个";
例:
#define TEST0(p1) #p1"333"
#define TEST(p1,p2,p3) #p1#p2 #p3
int main()
{
int nTest1;
int nTest2;
int nTest3;
printf("%s", TEST(TEST0(0),"333",nTest3));
return 0;
}
运行结果:
从上面的例子可以看出#运算符主要作用就是将宏定义中的参数变成字符串,而##运算符的
作用就是将宏定义中相邻的两个的参数连接在一起组成一个标识符,如果该标识符不符合C
语言表示符的组成规则,那么编译时会报错;
例如:
对于使用了##和#的宏定义,预处理器需要进行反复扫描分析记号序列,以此来查找已定义的
标识符进行替换,如果一个表示符在某次扫描中被替换后,再次扫描遇到此标识符时,则不在
进行替换。
例:
#define TEST(p1,p2) p1##p2
int main()
{
int nTest1;
int nTest2;
int nTest3;
int TEST(TEST(nTest1, nTest2), nTest3) = 3;
printf("%d", TEST(TEST(nTest1, nTest2), nTest3));
return 0;
}
使用/P命令查看编译预处理后的结果:
int main()
{
int nTest1;
int nTest2;
int nTest3;
int TEST(nTest1, nTest2)nTest3 = 3;
printf("%d", TEST(nTest1, nTest2)nTest3);
return 0;
}
可以看出TEST(TEST(nTest1, nTest2), nTest3)第一次展开后为TEST(nTest1, nTest2)nTest3,
然后又遇到了TEST宏定义,则不在进行展开,直接将TEST(nTest1, nTest2)nTest3作为最终结果,但是
TEST(nTest1, nTest2)nTest3显然不符合C语言表示符的定义,所以编译时会报错。
注意:/P命令使用完成后,必须从命令行中删除它,否则编译的时候会报找不到xxxxx.obj错误
#和##运算符是C语言宏定义中两个比较有创造力的运算符,可以创造出许多"黑魔法"宏定义
预定义的宏
C语言中有些预定义的宏,这些宏不能取消定义和重定义:
code[class*="language-"], pre[class*="language-"] { color: rgba(51, 51, 51, 1); font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; text-align: left; white-space: pre; word-spacing: normal; word-break: normal; word-wrap: normal; line-height: 1.4; -moz-tab-size: 8; -o-tab-size: 8; tab-size: 8; -webkit-hyphens: none; -moz-hyphens: none; -ms-hyphens: none; hyphens: none }
pre[class*="language-"] { padding: 0.8em; overflow: auto; border-radius: 3px; background: rgba(245, 245, 245, 1) }
:not(pre)>code[class*="language-"] { padding: 0.1em; border-radius: 0.3em; white-space: normal; background: rgba(245, 245, 245, 1) }
.token.comment, .token.blockquote { color: rgba(150, 152, 150, 1) }
.token.cdata { color: rgba(24, 54, 145, 1) }
.token.doctype, .token.punctuation, .token.variable, .token.macro.property { color: rgba(51, 51, 51, 1) }
.token.operator, .token.important, .token.keyword, .token.rule, .token.builtin { color: rgba(167, 29, 93, 1) }
.token.string, .token.url, .token.regex, .token.attr-value { color: rgba(24, 54, 145, 1) }
.token.property, .token.number, .token.boolean, .token.entity, .token.atrule, .token.constant, .token.symbol, .token.command, .token.code { color: rgba(0, 134, 179, 1) }
.token.tag, .token.selector, .token.prolog { color: rgba(99, 163, 92, 1) }
.token.function, .token.namespace, .token.pseudo-element, .token.class, .token.class-name, .token.pseudo-class, .token.id, .token.url-reference .token.variable, .token.attr-name { color: rgba(121, 93, 163, 1) }
.token.entity { cursor: help }
.token.title, .token.title .token.punctuation { font-weight: bold; color: rgba(29, 62, 129, 1) }
.token.list { color: rgba(237, 106, 67, 1) }
.token.inserted { background-color: rgba(234, 255, 234, 1); color: rgba(85, 165, 50, 1) }
.token.deleted { background-color: rgba(255, 236, 236, 1); color: rgba(189, 44, 0, 1) }
.token.bold { font-weight: bold }
.token.italic { font-style: italic }
.language-json .token.property { color: rgba(24, 54, 145, 1) }
.language-markup .token.tag .token.punctuation { color: rgba(51, 51, 51, 1) }
code.language-css, .language-css .token.function { color: rgba(0, 134, 179, 1) }
.language-yaml .token.atrule { color: rgba(99, 163, 92, 1) }
code.language-yaml { color: rgba(24, 54, 145, 1) }
.language-ruby .token.function { color: rgba(51, 51, 51, 1) }
.language-markdown .token.url { color: rgba(121, 93, 163, 1) }
.language-makefile .token.symbol { color: rgba(121, 93, 163, 1) }
.language-makefile .token.variable { color: rgba(24, 54, 145, 1) }
.language-makefile .token.builtin { color: rgba(0, 134, 179, 1) }
.language-bash .token.keyword { color: rgba(0, 134, 179, 1) }
pre[data-line] { position: relative; padding: 1em 0 1em 3em }
pre[data-line] .line-highlight-wrapper { position: absolute; top: 0; left: 0; background-color: rgba(0, 0, 0, 0); display: block; width: 100% }
pre[data-line] .line-highlight { position: absolute; left: 0; right: 0; margin-top: 1em; background: linear-gradient(90deg, rgba(153, 122, 102, 0.1) 70%, rgba(153, 122, 102, 0)); pointer-events: none; line-height: inherit; white-space: pre }
pre[data-line] .line-highlight:before, pre[data-line] .line-highlight[data-end]:after { content: attr(data-start); position: absolute; top: 0.4em; left: 0.6em; min-width: 1em; padding: 0 0.5em; background-color: rgba(153, 122, 102, 0.4); color: rgba(245, 242, 240, 1); font: bold 65% / 1.5 sans-serif; text-align: center; vertical-align: 0.3em; border-radius: 999px; text-shadow: none; box-shadow: 0 1px rgba(255, 255, 255, 1) }
pre[data-line] .line-highlight[data-end]:after { content: attr(data-end); top: auto; bottom: 0.4em }
html body { font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; color: rgba(51, 51, 51, 1); background-color: rgba(255, 255, 255, 1); overflow: initial; box-sizing: border-box; word-wrap: break-word }
html body>:first-child { margin-top: 0 }
html body h1, html body h2, html body h3, html body h4, html body h5, html body h6 { line-height: 1.2; margin-top: 1em; margin-bottom: 16px; color: rgba(0, 0, 0, 1) }
html body h1 { font-size: 2.25em; font-weight: 300; padding-bottom: 0.3em }
html body h2 { font-size: 1.75em; font-weight: 400; padding-bottom: 0.3em }
html body h3 { font-size: 1.5em; font-weight: 500 }
html body h4 { font-size: 1.25em; font-weight: 600 }
html body h5 { font-size: 1.1em; font-weight: 600 }
html body h6 { font-size: 1em; font-weight: 600 }
html body h1, html body h2, html body h3, html body h4, html body h5 { font-weight: 600 }
html body h5 { font-size: 1em }
html body h6 { color: rgba(92, 92, 92, 1) }
html body strong { color: rgba(0, 0, 0, 1) }
html body del { color: rgba(92, 92, 92, 1) }
html body a:not([href]) { color: inherit; text-decoration: none }
html body a { color: rgba(0, 136, 204, 1); text-decoration: none }
html body a:hover { color: rgba(0, 163, 245, 1); text-decoration: none }
html body img { max-width: 100% }
html body>p { margin-top: 0; margin-bottom: 16px; word-wrap: break-word }
html body>ul, html body>ol { margin-bottom: 16px }
html body ul, html body ol { padding-left: 2em }
html body ul.no-list, html body ol.no-list { padding: 0; list-style-type: none }
html body ul ul, html body ul ol, html body ol ol, html body ol ul { margin-top: 0; margin-bottom: 0 }
html body li { margin-bottom: 0 }
html body li.task-list-item { list-style: none }
html body li>p { margin-top: 0; margin-bottom: 0 }
html body .task-list-item-checkbox { margin: 0 0.2em 0.25em -1.8em; vertical-align: middle }
html body .task-list-item-checkbox:hover { cursor: pointer }
html body blockquote { margin: 16px 0; font-size: inherit; padding: 0 15px; color: rgba(92, 92, 92, 1); border-left: 4px solid rgba(214, 214, 214, 1) }
html body blockquote>:first-child { margin-top: 0 }
html body blockquote>:last-child { margin-bottom: 0 }
html body hr { height: 4px; margin: 32px 0; background-color: rgba(214, 214, 214, 1); border: 0 none }
html body table { margin: 10px 0 15px; border-collapse: collapse; border-spacing: 0; display: block; width: 100%; overflow: auto; word-break: keep-all }
html body table th { font-weight: bold; color: rgba(0, 0, 0, 1) }
html body table td, html body table th { border: 1px solid rgba(214, 214, 214, 1); padding: 6px 13px }
html body dl { padding: 0 }
html body dl dt { padding: 0; margin-top: 16px; font-size: 1em; font-style: italic; font-weight: bold }
html body dl dd { padding: 0 16px; margin-bottom: 16px }
html body code { font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.85em !important; color: rgba(0, 0, 0, 1); background-color: rgba(240, 240, 240, 1); border-radius: 3px; padding: 0.2em 0 }
html body code::before, html body code::after { letter-spacing: -0.2em; content: " " }
html body pre>code { padding: 0; margin: 0; font-size: 0.85em !important; word-break: normal; white-space: pre; background: rgba(0, 0, 0, 0); border: 0 }
html body .highlight { margin-bottom: 16px }
html body .highlight pre, html body pre { padding: 1em; overflow: auto; font-size: 0.85em !important; line-height: 1.45; border: rgba(214, 214, 214, 1); border-radius: 3px }
html body .highlight pre { margin-bottom: 0; word-break: normal }
html body pre code, html body pre tt { display: inline; max-width: initial; padding: 0; margin: 0; overflow: initial; line-height: inherit; word-wrap: normal; background-color: rgba(0, 0, 0, 0); border: 0 }
html body pre code:before, html body pre tt:before, html body pre code:after, html body pre tt:after { content: normal }
html body p, html body blockquote, html body ul, html body ol, html body dl, html body pre { margin-top: 0; margin-bottom: 16px }
html body kbd { color: rgba(0, 0, 0, 1); border-top: 1px solid rgba(214, 214, 214, 1); border-right: 1px solid rgba(214, 214, 214, 1); border-bottom: 2px solid rgba(199, 199, 199, 1); border-left: 1px solid rgba(214, 214, 214, 1); padding: 2px 4px; background-color: rgba(240, 240, 240, 1); border-radius: 3px }
@media print { html body { background-color: rgba(255, 255, 255, 1) } html body h1, html body h2, html body h3, html body h4, html body h5, html body h6 { color: rgba(0, 0, 0, 1); page-break-after: avoid } html body blockquote { color: rgba(92, 92, 92, 1) } html body pre { page-break-inside: avoid } html body table { display: table } html body img { display: block; max-width: 100%; max-height: 100% } html body pre, html body code { word-wrap: break-word; white-space: pre } }
.markdown-preview { width: 100%; height: 100%; box-sizing: border-box }
.markdown-preview .pagebreak, .markdown-preview .newpage { page-break-before: always }
.markdown-preview pre.line-numbers { position: relative; padding-left: 3.8em; counter-reset: linenumber 0 }
.markdown-preview pre.line-numbers>code { position: relative }
.markdown-preview pre.line-numbers .line-numbers-rows { position: absolute; pointer-events: none; top: 1em; font-size: 100%; left: 0; width: 3em; letter-spacing: -1px; border-right: 1px solid rgba(153, 153, 153, 1); -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none }
.markdown-preview pre.line-numbers .line-numbers-rows>span { pointer-events: none; display: block; counter-increment: linenumber 1 }
.markdown-preview pre.line-numbers .line-numbers-rows>span:before { content: counter(linenumber); color: rgba(153, 153, 153, 1); display: block; padding-right: 0.8em; text-align: right }
.markdown-preview .mathjax-exps .MathJax_Display { text-align: center !important }
.markdown-preview:not([for="preview"]) .code-chunk .btn-group { display: none }
.markdown-preview:not([for="preview"]) .code-chunk .status { display: none }
.markdown-preview:not([for="preview"]) .code-chunk .output-div { margin-bottom: 16px }
{ width: 8px }
{ border-radius: 10px; background-color: rgba(0, 0, 0, 0) }
{ border-radius: 5px; background-color: rgba(150, 150, 150, 0.66); border: 4px solid rgba(150, 150, 150, 0.66); background-clip: content-box }
html body[for="html-export"]:not([data-presentation-mode]) { position: relative; width: 100%; height: 100%; top: 0; left: 0; margin: 0; padding: 0; overflow: auto }
html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview { position: relative; top: 0 }
@media screen and (min-width: 914px) { html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview { padding: 2em calc(50% - 457px + 2em) } }
@media screen and (max-width: 914px) { html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview { padding: 2em } }
@media screen and (max-width: 450px) { html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview { font-size: 14px !important; padding: 1em } }
@media print { html body[for="html-export"]:not([data-presentation-mode]) #sidebar-toc-btn { display: none } }
html body[for="html-export"]:not([data-presentation-mode]) #sidebar-toc-btn { position: fixed; bottom: 8px; left: 8px; font-size: 28px; cursor: pointer; color: inherit; z-index: 99; width: 32px; text-align: center; opacity: 0.4 }
html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] #sidebar-toc-btn { opacity: 1 }
html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc { position: fixed; top: 0; left: 0; width: 300px; height: 100%; padding: 32px 0 48px; font-size: 14px; box-shadow: 0 0 4px rgba(150, 150, 150, 0.33); box-sizing: border-box; overflow: auto; background-color: inherit }
{ width: 8px }
{ border-radius: 10px; background-color: rgba(0, 0, 0, 0) }
{ border-radius: 5px; background-color: rgba(150, 150, 150, 0.66); border: 4px solid rgba(150, 150, 150, 0.66); background-clip: content-box }
html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc a { text-decoration: none }
html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc ul { padding: 0 1.6em; margin-top: 0.8em }
html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc li { margin-bottom: 0.8em }
html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc ul { list-style-type: none }
html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview { left: 300px; width: calc(100% - 300px); padding: 2em calc(50% - 457px - 150px); margin: 0; box-sizing: border-box }
@media screen and (max-width: 1274px) { html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview { padding: 2em } }
@media screen and (max-width: 450px) { html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview { width: 100% } }
html body[for="html-export"]:not([data-presentation-mode]):not([html-show-sidebar-toc]) .markdown-preview { left: 50%; transform: translateX(-50%) }
html body[for="html-export"]:not([data-presentation-mode]):not([html-show-sidebar-toc]) .md-sidebar-toc { display: none }
C语言宏的使用的更多相关文章
- C语言 宏/macor/#define/
C语言 宏/macor/#define 高级技巧 1.在进行调试的时候,需要进行打印/PRINT,可以通过define进行自定义.例如,自己最常用的DEBUG_PRINT() #define DEBU ...
- C语言宏的高级应用
原文:C语言宏的高级应用 关于#和##在C语言的宏中,#的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个双引号.比如 ...
- C 语言宏定义
C 语言宏定义1.例子如下: #define PRINT_STR(s) printf("%s",s.c_str()) string str = "abcd"; ...
- 将C语言宏定义数值转换成字符串!
将C语言宏定义转换成字符串! 摘自:https://blog.csdn.net/happen23/article/details/50602667 2016年01月28日 19:15:47 六个九十度 ...
- C语言宏应用-------#define STR(X) #X
C语言宏应用-------#define STR(X) #X #:会把参数转换为字符串 #define STR(x) #x #define MAX 100 STR(MAX) 会被扩展成" ...
- C语言 宏定义之可变参数
可变参数宏定义 C99编译器标准允许你可以定义可变参数宏(variadic macros),这样你就可以使用拥有可以变化的参数表的宏.可变参数宏就像下面这个样子: #define dbgprint(. ...
- C语言宏定义时#(井号)和##(双井号)的用法1
#在英语里面叫做 pound 在C语言的宏定义中,一个#表示字符串化:两个#代表concatenate 举例如下: #include <iostream> void quit_comman ...
- C语言宏定义时#(井号)和##(双井号)的用法
C语言中如何使用宏C(和C++)中的宏(Macro)属于编译器预处理的范畴,属于编译期概念(而非运行期概念).下面对常遇到的宏的使用问题做了简单总结. 关于#和## 在C语言的宏中,#的功能是将其后面 ...
- c语言宏定义
一. #define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往往不能理解该命令的本质,总是在此处产生一些困惑,在编程时 ...
随机推荐
- SwiftUI render WKWebView
SwiftUI render WKWebView // // ContentView.swift // webview-app // // Created by 夏凌晨 on 2020/10/27. ...
- js data type checker
js data type checker js 数据类型检测 "use strict"; /** * * @author xgqfrms * @license MIT * @cop ...
- convert number or string to ASCII in js
convert number or string to ASCII in js ASCII dictionary generator // const dict = `abcdefghijklmnop ...
- website url spam
website url spam xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
- front-end & web & best code editor
front-end & web & best code editor 2019 VS Code https://designrevision.com/best-code-editor/ ...
- Nestjs mongodb
nestjs 文档 mongoose 文档 使用"@meanie/mongoose-to-json"转换查询后返回的json数据 将"_id"转为"i ...
- 大胆预计SPC算力空投收益,月收益22.8%
此前,NGK官方公告表示,NGK算力持有者获得SPC的数量是根据200万枚SPC除以全网算力总量决定的. 举个例子,假设全网算力总量为500万,那么每个算力持有者如果持有一个算力,则可获得200万÷5 ...
- NGK流动性挖矿为何会备受瞩目?
随着越来越多资金的涌入,参与DeFi项目或挖矿的用户不难发现,使用体验不尽人意,在以太坊网络的DeFi时常需要漫长的等待确认和高昂的GAS费用,加上DeFi流动性挖矿需要相对较高的资金门槛和技术门槛, ...
- Echarts制作一张全球疫情图
一.获取全球疫情数据 1)获取API 使用用友提供的新冠肺炎实时数据,登录注册之后可以免费使用. 2)点击用户信息 这里的AIPCODE,复制并保存,用于后续的使用. 3)API的使用 用友有提供一个 ...
- 运用Spock编写高质量单元测试
单元测试作为提升代码质量的有效方法,目前在国内各大互联网公司的开发团队中,尤其是业务团队中却鲜少被使用.这主要由于大家对于单元测试有一些认知错误,或者没有正确的打开方式.至今我们团队在小剧场.零代码运 ...