如何标记 printf("result is %d\n",a) ;词法分析器的语句
How to tokenize printf("result is %d\n",a) ; statement by lexical analyser
如果词法分析器将"result is %d\n"作为一个记号在:
printf("result is %d\n",a);
那么 %d 和 \n 如何以及在什么阶段分别被识别为格式说明符和下一行。
libc
"manually"中printf
的代码是自己解析格式串,一个字符一个字符的。同样,编译器也会对以下参数进行类型检查。
调用 printf
中的文字字符串是普通字符串文字,与程序中的任何其他字符串文字没有区别。 printf
是一个普通函数,它的第一个参数应该是一个字符串。不需要 printf
的第一个参数是字符串 literal;它可以是任何表达式,其值是一个指向字符串的指针。 (虽然许多风格指南警告你不要实际这样做。)所以以下是完全合法的:
const char* fmt = "The result is %d\n";
/* ... */
printf(fmt, a);
在字符串文字中,像 \n
这样的转义序列被转换为它们所代表的特殊字符(在本例中为换行符)。所以 "\n"
是一个包含单个字符的字符串文字。
每次调用 printf
时,它都会扫描提供的格式字符串以识别格式转换。显然,这发生在 运行 时间,而不是程序编译时。
话虽如此,由于 printf
是一个具有明确行为的标准库函数,如果格式参数在编译时已知,编译器优化对 printf
的调用是合法的-时间。一些编译器利用了这一点。
如果词法分析器将"result is %d\n"作为一个记号在: printf("result is %d\n",a); 那么 %d 和 \n 如何以及在什么阶段分别被识别为格式说明符和下一行。
libc
"manually"中printf
的代码是自己解析格式串,一个字符一个字符的。同样,编译器也会对以下参数进行类型检查。
调用 printf
中的文字字符串是普通字符串文字,与程序中的任何其他字符串文字没有区别。 printf
是一个普通函数,它的第一个参数应该是一个字符串。不需要 printf
的第一个参数是字符串 literal;它可以是任何表达式,其值是一个指向字符串的指针。 (虽然许多风格指南警告你不要实际这样做。)所以以下是完全合法的:
const char* fmt = "The result is %d\n";
/* ... */
printf(fmt, a);
在字符串文字中,像 \n
这样的转义序列被转换为它们所代表的特殊字符(在本例中为换行符)。所以 "\n"
是一个包含单个字符的字符串文字。
每次调用 printf
时,它都会扫描提供的格式字符串以识别格式转换。显然,这发生在 运行 时间,而不是程序编译时。
话虽如此,由于 printf
是一个具有明确行为的标准库函数,如果格式参数在编译时已知,编译器优化对 printf
的调用是合法的-时间。一些编译器利用了这一点。