字符串化#

C 语言中,# 号可用于将宏参数转为字符串,如下:

#define STR(x)  #x
int main()
{
    int age=18;
    printf(STR(age)); //输出字符串age,而非18
    printf(STR(18));  //输出字符串18
}

这种用法有什么使用场景呢?如下,有时候我们需要取得宏函数参数(表达式/变量)的字面内容:

#define warn(expr)  printf(#expr)
int main()
{
    int a=0;
    int b=0;
	warn(a==0);    //打印"a==0"
    return 0;
}

这在某些情况下很有用,比如 assert 宏,参见assert剖析

另外需要注意,当宏参数是另一个宏的时候,宏定义里有用 # 的地方宏参数不会再展开 ,比如:

#define warn(expr)  printf(#expr)
#define Π 3.14
int main()
{
    warn(Π==3.14); //输出"Π==3.14"而不是"3.14==3.14"
}

如果想要宏参数展开,则需要使用以下两步:

#define _warn(expr)  printf(#expr)
#define warn(expr)   _warn(expr)
#define Π 3.14
int main()
{
    warn(Π==3.14); //输出"3.14==3.14"而不是"Π==3.14"
}

原因是 warn(expr) 展开时会扩展它的参数,即替换 expr 中的宏变量。

符号粘贴##

## 用于拼接两个符号,如下:

#define ponit(x,y) x##.##y 
int main()
{
    printf("%f",point(12,32));  //输出12.32
}

注意,从以上结果可见,转换后的结果不是字符串! 而是正常的代码或数字。如果想将结果转为字符串,可以采用如下方式:

#define TOSTR(x) #x
#define CONT(a,b) TOSTR(a)##TOSTR(b)
int main()
{
	printf(CONT(12,32)); //输出"1232"
}

Window 下对 ## 的一个简单使用是指定字符编码方式:

#ifdef _UNICODE
#define  TEXT(x) L##x
#else
#define  TEXT(x) x

当定义了 _UNICODE 时,则 TEXT("hello")"hello" ,否则为 L"hellp

L"str" 是 C/C++ 对宽字节字符的原生支持,表示字符串中的每个字符都是双字节。

另外需要强调的是,### 都只能用于预处理宏扩展,不能在普通源码中使用。

文章作者: 极简
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 后端技术分享
C/C++
喜欢就支持一下吧