<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://www.mywiki.cn/Hovercool/index.php?action=history&amp;feed=atom&amp;title=%E5%AE%8F%E4%B8%AD_%E4%BA%95_%E7%9A%84%E7%94%A8%E6%B3%95</id>
	<title>宏中 井 的用法 - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://www.mywiki.cn/Hovercool/index.php?action=history&amp;feed=atom&amp;title=%E5%AE%8F%E4%B8%AD_%E4%BA%95_%E7%9A%84%E7%94%A8%E6%B3%95"/>
	<link rel="alternate" type="text/html" href="https://www.mywiki.cn/Hovercool/index.php?title=%E5%AE%8F%E4%B8%AD_%E4%BA%95_%E7%9A%84%E7%94%A8%E6%B3%95&amp;action=history"/>
	<updated>2026-09-01T06:14:24Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://www.mywiki.cn/Hovercool/index.php?title=%E5%AE%8F%E4%B8%AD_%E4%BA%95_%E7%9A%84%E7%94%A8%E6%B3%95&amp;diff=887&amp;oldid=prev</id>
		<title>2015年5月6日 (三) 12:31 Hovercool</title>
		<link rel="alternate" type="text/html" href="https://www.mywiki.cn/Hovercool/index.php?title=%E5%AE%8F%E4%B8%AD_%E4%BA%95_%E7%9A%84%E7%94%A8%E6%B3%95&amp;diff=887&amp;oldid=prev"/>
		<updated>2015-05-06T12:31:39Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;div style=&amp;quot;font-size:200%&amp;quot;&amp;gt;宏中&amp;quot;#&amp;quot;和&amp;quot;##&amp;quot;的用法&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 一、一般用法 ==&lt;br /&gt;
我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起.&lt;br /&gt;
&lt;br /&gt;
用法:&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
＃include&amp;lt;cstdio&amp;gt;&lt;br /&gt;
＃include&amp;lt;climits&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
#define STR(s)     #s&lt;br /&gt;
#define CONS(a,b)  int(a##e##b)&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    printf(STR(vck));           // 输出字符串&amp;quot;vck&amp;quot;&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, CONS(2,3));  // 2e3 输出:2000&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 二、当宏参数是另一个宏的时候 ==&lt;br /&gt;
&lt;br /&gt;
需要注意的是凡宏定义里有用&amp;#039;#&amp;#039;或&amp;#039;##&amp;#039;的地方宏参数是不会再展开.&lt;br /&gt;
&lt;br /&gt;
=== 1, 非&amp;#039;#&amp;#039;和&amp;#039;##&amp;#039;的情况 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
#define TOW      (2)&lt;br /&gt;
#define MUL(a,b) (a*b)&lt;br /&gt;
&lt;br /&gt;
printf(&amp;quot;%d*%d=%d\n&amp;quot;, TOW, TOW, MUL(TOW,TOW));&lt;br /&gt;
&lt;br /&gt;
//这行的宏会被展开为：&lt;br /&gt;
//printf(&amp;quot;%d*%d=%d\n&amp;quot;, (2), (2), ((2)*(2)));&lt;br /&gt;
//MUL里的参数TOW会被展开为(2).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2, 当有&amp;#039;#&amp;#039;或&amp;#039;##&amp;#039;的时候 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
#define A          (2)&lt;br /&gt;
#define STR(s)     #s&lt;br /&gt;
#define CONS(a,b)  int(a##e##b)&lt;br /&gt;
&lt;br /&gt;
printf(&amp;quot;int max: %s\n&amp;quot;,  STR(INT_MAX));    // INT_MAX ＃i nclude&amp;lt;climits&amp;gt;&lt;br /&gt;
//这行会被展开为：&lt;br /&gt;
//printf(&amp;quot;int max: %s\n&amp;quot;, &amp;quot;INT_MAX&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
printf(&amp;quot;%s\n&amp;quot;, CONS(A, A));               // compile error&lt;br /&gt;
//这一行则是：&lt;br /&gt;
//printf(&amp;quot;%s\n&amp;quot;, int(AeA));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
INT_MAX和A都不会再被展开, 然而解决这个问题的方法很简单. 加多一层中间转换宏.&lt;br /&gt;
加这层宏的用意是把所有宏的参数在这层里全部展开, 那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
#define A           (2)&lt;br /&gt;
#define _STR(s)     #s&lt;br /&gt;
#define STR(s)      _STR(s)          // 转换宏&lt;br /&gt;
#define _CONS(a,b)  int(a##e##b)&lt;br /&gt;
#define CONS(a,b)   _CONS(a,b)       // 转换宏&lt;br /&gt;
&lt;br /&gt;
printf(&amp;quot;int max: %s\n&amp;quot;, STR(INT_MAX));          // INT_MAX,int型的最大值，为一个变量 ＃i nclude&amp;lt;climits&amp;gt;&lt;br /&gt;
//输出为: int max: 0x7fffffff&lt;br /&gt;
//STR(INT_MAX) --&amp;gt;  _STR(0x7fffffff) 然后再转换成字符串；&lt;br /&gt;
&lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, CONS(A, A));&lt;br /&gt;
//输出为：200&lt;br /&gt;
//CONS(A, A)  --&amp;gt;  _CONS((2), (2))  --&amp;gt; int((2)e(2))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 三、&amp;#039;#&amp;#039;和&amp;#039;##&amp;#039;的一些应用 ==&lt;br /&gt;
&lt;br /&gt;
=== 1、合并匿名变量名 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
#define  ___ANONYMOUS1(type, var, line)  type  var##line&lt;br /&gt;
#define  __ANONYMOUS0(type, line)  ___ANONYMOUS1(type, _anonymous, line)&lt;br /&gt;
#define  ANONYMOUS(type)  __ANONYMOUS0(type, __LINE__)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
例：ANONYMOUS(static int);  即: static int _anonymous70;  70表示该行行号；&lt;br /&gt;
&lt;br /&gt;
第一层：ANONYMOUS(static int);  --&amp;gt;  __ANONYMOUS0(static int, __LINE__);&lt;br /&gt;
&lt;br /&gt;
第二层：                        --&amp;gt;  ___ANONYMOUS1(static int, _anonymous, 70);&lt;br /&gt;
&lt;br /&gt;
第三层：                        --&amp;gt;  static int  _anonymous70;&lt;br /&gt;
&lt;br /&gt;
即每次只能解开当前层的宏，所以__LINE__在第二层才能被解开；&lt;br /&gt;
&lt;br /&gt;
=== 2、填充结构 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
#define  FILL(a)   {a, #a}&lt;br /&gt;
&lt;br /&gt;
enum IDD{OPEN, CLOSE};&lt;br /&gt;
typedef struct MSG{&lt;br /&gt;
  IDD id;&lt;br /&gt;
  const char * msg;&lt;br /&gt;
}MSG;&lt;br /&gt;
&lt;br /&gt;
MSG _msg[] = {FILL(OPEN), FILL(CLOSE)};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
相当于：&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
MSG _msg[] = {{OPEN, &amp;quot;OPEN&amp;quot;},&lt;br /&gt;
              {CLOSE, &amp;quot;CLOSE&amp;quot;}};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3、记录文件名 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
#define  _GET_FILE_NAME(f)   #f&lt;br /&gt;
#define  GET_FILE_NAME(f)    _GET_FILE_NAME(f)&lt;br /&gt;
static char  FILE_NAME[] = GET_FILE_NAME(__FILE__);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 4、得到一个数值类型所对应的字符串缓冲大小 ===&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
#define  _TYPE_BUF_SIZE(type)  sizeof #type&lt;br /&gt;
#define  TYPE_BUF_SIZE(type)   _TYPE_BUF_SIZE(type)&lt;br /&gt;
char  buf[TYPE_BUF_SIZE(INT_MAX)];&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--&amp;gt;  char  buf[_TYPE_BUF_SIZE(0x7fffffff)];&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;  char  buf[sizeof &amp;quot;0x7fffffff&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
这里相当于：&lt;br /&gt;
&lt;br /&gt;
char  buf[11];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 四、一些其他有用的示例 ==&lt;br /&gt;
&lt;br /&gt;
=== 1、连接字串 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
#define TAG &amp;quot;logyfish&amp;quot;&lt;br /&gt;
#define MAIN_TAG &amp;quot;hi:&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CONCT(a, b) a b&lt;br /&gt;
#define LOG_TAG CONCT(MAIN_TAG, TAG)&lt;br /&gt;
&lt;br /&gt;
    cout &amp;lt;&amp;lt;LOG_TAG&amp;lt;&amp;lt;endl;&lt;br /&gt;
//结果: hi:logyfish&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
参考资料：http://www.52rd.com/Blog/Detail_RD.Blog_imjacob_6090.html&lt;/div&gt;</summary>
		<author><name>Hovercool</name></author>
	</entry>
</feed>