“#”在C语言中有多种用法,总结有5种:
以下分别详细解释。
这一作用比较常见,如包含头文件时,使用#include;
如#define, #endif, #ifndef
如#warning, #error
总所周知,宏定义是可以定义字符串的,如下:
#include <stdio.h>
#define STR "test macro to string"
int main(int argc, char** argv)
{
printf("%s\r\n",STR);
return 0;
}
打印如下:
test macro to string
但是在某些场景下,无法直接宏定义字符串,需要宏定义转成字符串。目前有两个应用场景,如有其他应用场景,欢迎大家评论区留言。
比如,将数字以字符串的形式打印,或者将任意输入以字符串形式打印:
用宏定义#define STR1(a) #a实现:
#include <stdio.h>
#define STR1(a) #a //以“#”的形式将输入转换成字符串,必须以宏定义的方式
int main(int argc, char** argv)
{
printf("print string: %s\r\n", STR1(test string));
printf("print string: %s\r\n", STR1(10086));
//printf("print string: %s\r\n", #10086);//必须用上面宏定义的方式,直接加#编译报错!!!
return 0;
}
输出:
test macro to string
print string: test string
print string: 10086
代码第3行,用宏定义的方式将输入转换成字符串,注意,必须用宏定义的方式,直接加#编译报错!
请大家思考一个问题,上节中,如果将数字10086和字符传test string 定义成宏的形式,然后再用STR(a)去打印会如何?直接上代码:
#include <stdio.h>
#define STR1(a) #a //以“#”的形式将输入转换成字符串,必须以宏定义的方式
#define TEST_NUM 10086
#define TEST_STR "test string"
int main(int argc, char** argv)
{
printf("%d to string: %s\r\n", TEST_NUM, STR1(TEST_NUM));
printf("%s to string: %s\r\n", TEST_STR, STR1(TEST_STR));
return 0;
}
打印如下:
10086 to string: TEST_NUM
test string to string: TEST_STR
由上面结果可见,如果我用宏定义了一个整数或字符串,然后用4.1小节的方式打印宏定义,只能直接将宏定义的名字打出,而不能打印出宏定义定义的内容。我们想要实现将打印“TEST_NUM”就能打印出“10086”字符串的效果,该如何实现呢?
还是看代码:(注意第6行,11、12行)
#include <stdio.h>
#define STR1(a) #a //以“#”的形式将输入转换成字符串,必须以宏定义的方式
#define TEST_NUM 10086
#define TEST_STR "test string"
#define STR2(a) STR1(a) //用二级字符串对的方式实现转换成字符串
int main(int argc, char** argv)
{
printf("%d to string: %s\r\n", TEST_NUM, STR1(TEST_NUM));
printf("%s to string: %s\r\n", TEST_STR, STR1(TEST_STR));
printf("%d to string: %s\r\n", TEST_NUM, STR2(TEST_NUM));
printf("%s to string: %s\r\n", TEST_STR, STR2(TEST_STR));
return 0;
}
运行结果打印如下:
10086 to string: TEST_NUM
test string to string: TEST_STR
10086 to string: 10086
test string to string: "test string"
上述结果实现了我们的预期结果(见11、12行打印)。我们用第6行实现了该功能。
注意:宏定义是完全替换,所以第12行的打印将引号也打印了出来。如果第4行宏定义的10086加上括号,同样第11行也会将括号打印出来。
“##”可以用于将两个标识符连接起来,上代码:
#include <stdio.h>
#define CONNECT(a,b) a##b
#define NAME_1 "zhangsan"
#define NAME_2 "lisi"
#define NAME(name) NAME_##name
int main(int argc, char** argv)
{
printf("num: %d\r\n", CONNECT(11,12));
printf("name: %s\r\n", NAME(1));
printf("name: %s\r\n", NAME(2));
return 0;
}
结果打印如下:
num: 1112
name: zhangsan
name: lisi
代码第3行宏定义将两个标识符连接,第9行打印如结果第1行所示,将11和12连接起来变成1112;
第10行和第11行,宏展开后,NAME(1)变成NAME_##1,NAME(2)变成NAME_##2,由于##的作用是连接作用,所以NAME(1)就是NAME_1,打印出来就是“zhangsan”;同样NAME(2)就是NAME_2,打印出来就是“lisi”。