请考虑以下代码段
shouldPerformSegueWithIdentifier
编译并执行时打印HELLO。
请帮助理解#include<stdio.h>
#define AB "HELLO"
#define A "WORLD"
#define MAC1 A##B
void main(void)
{
printf(MAC1"\n");
}
和##
之间忽略A
的原因。
同样,在编译以下代码时,会出现以下错误,
B
21.c:在功能âmainâ中:
21.c:11:2:错误:在程序中流浪â#â 21.c:11:9:错误:预期â)在字符串常量之前
为什么会出现这种情况?
答案 0 :(得分:2)
##
预处理令牌用于令牌粘贴。
宏定义中A##B
的效果是生成令牌AB
。因此printf(MAC1"\n")
与printf(AB"\n")
相同。
令牌不被忽略&#34;它正在完成它的工作。
在您的第二个示例中,A#B
只是字面意思A#B
。 #
在函数式宏中只有特殊含义。所以你的代码扩展为:
printf(A#B"\n");
这是一个错误,因为#
不是预处理器之外的C语法的一部分。
答案 1 :(得分:1)
令牌#和##在宏扩展中很特殊。 '##'是令牌粘贴运算符。它在宏中需要2个符号并将它们绑定到一个符号中。这对于创建专用名称很有用。
#define LINE_COUNTER static int line## __LINE__ =0; line ## __LINE__ ++;
这会创建一个变量,当行执行时,该变量会增加。它可以在同一个函数中多次使用,因为它具有基于行号的唯一名称。 (static int line_17 = 0; line_17 ++;)
'#'符号是字符串化运算符。它将后面的内容转换为字符串。
#define assert( x ) if( ! x ) { fprintf( stderr, "Assertion failed %s\n", #x ); exit( 1 ) }
答案 2 :(得分:0)
##连接符号。换句话说,A ## B表示不存在的AB。 如果你想做两个变量名的变量名,你可以这样使用:
#define newVar(x,y) x##y
int main()
{
int newVar(my,Var); // int myVar;
newVar(f,printf)(stdout,"Hello World"); // fprintf(stdout,"Hello World");
}
#取一个名字,然后把它变成一个字符串。例如
#define VARSTR(x) #x
int main()
{
printf(VARSTR(myVar));
}
将“myVar”打印到字符串中(即使myVar不是main的变量,它也在宏替换中)
#define "HELLO" "WORLD"
要连接字符串文字,它们只需要彼此相邻放置,之间没有其他有效标记。因此导致“HELLOWORLD”注意文字之间的空格被忽略,并且是不必要的。我用它来澄清它。
这将取代AA和BB,如下所示:
#include<stdio.h>
#define AA "HELLO"
#define BB "WORLD"
#define MAC1 AA BB
void main(void)
{
printf(MAC1"\n"); // printf("HELLO" "WORLD""\n");
// same as printf("HELLOWORLD\n");
}
答案 3 :(得分:0)
正如其他人指出的那样,##
运算符用于创建新标记。
#define MAC1 A##B
将创建定义为包含字符串AB
的宏HELLO
。这就是printf(MAC1"\n")
打印&#34; HELLO&#34;的原因。如果要连接AB
和A
表示的字符串,可以按如下方式定义MAC1
:
#define MAC1 AB A
然后,您的预处理程序将首先将AB B
替换为"HELLO""WORLD
,以便MAC1
看起来像
#define MAC1 "HELLO""WORLD"
然后它会在它出现的任何地方替换MAC1
。所以你的printf语句将是
printf("HELLO""WORLD""\n"); // --> HELLOWORLD