Compiler construction 如何标记printf(“结果是%d\n”,a);词汇分析器的陈述
如果词法分析器将“结果为%d\n”作为以下内容中的一个标记: printf(“结果是%d\n”,a);Compiler construction 如何标记printf(“结果是%d\n”,a);词汇分析器的陈述,compiler-construction,lexical-analysis,Compiler Construction,Lexical Analysis,如果词法分析器将“结果为%d\n”作为以下内容中的一个标记: printf(“结果是%d\n”,a); 然后,如何以及在什么阶段将%d和\n分别识别为格式说明符和下一行。libc中的printf代码“手动”逐个字符地自行解析格式字符串。类似地,编译器也会对以下参数进行类型检查。对printf的调用中的文本字符串是一个普通的字符串文本,与程序中的任何其他字符串文本没有区别printf是一个普通函数,其第一个参数应为字符串。不要求printf的第一个参数是字符串文字;它可以是值为字符串指针的任何表达
然后,如何以及在什么阶段将%d和\n分别识别为格式说明符和下一行。libc中的
printf
代码“手动”逐个字符地自行解析格式字符串。类似地,编译器也会对以下参数进行类型检查。对printf
的调用中的文本字符串是一个普通的字符串文本,与程序中的任何其他字符串文本没有区别printf
是一个普通函数,其第一个参数应为字符串。不要求printf
的第一个参数是字符串文字;它可以是值为字符串指针的任何表达式。(尽管许多样式指南警告您不要这样做。)因此,以下内容完全合法:
const char* fmt = "The result is %d\n";
/* ... */
printf(fmt, a);
在字符串文本中,像\n
这样的转义序列被转换为它们所表示的特殊字符(本例中为换行符)。因此,“\n”
是一个包含单个字符的字符串文字
每次调用printf
,它都会扫描提供的格式字符串以识别格式转换。显然,这是在运行时发生的,而不是在编译程序时
话虽如此,由于
printf
是一个具有良好定义行为的标准库函数,如果在编译时已知format参数,编译器优化对printf
的调用是合法的。一些编译器利用了这一点。它是在运行时识别的,而不是在编译期间。