首页 > 解决方案 > 根据 C 标准,哪些字符在 C 中的预处理指令之前和之后有效

问题描述

根据C 标准,哪些字符在C中的预处理指令之前和之后有效。

/*what are all the valid characters that can occur here*/ #include <stdio.h> /*and here according to the C standard*/
main()
{

    printf("Hello World");      

}

现在C标准没有提到预处理指令之前和之后哪些字符是有效的,如果有人可以指导我了解C标准的确切定义,将不胜感激

标签: ccharactertokendirectivepreprocessor-directive

解决方案


让我们剖析您在评论中链接的 C 标准的第 2 段

预处理指令由满足以下约束的一系列预处理标记组成:

构成源代码的字符被划分为标记。此类标记例如是特殊字符(如“#”)、以字母或下划线开头的标识符或以十进制字符开头的数字。

序列中的第一个标记是 # 预处理标记,它(在翻译阶段 4 开始时)是源文件中的第一个字符(可选地在不包含换行符的空格之后)或者紧随其后的空格至少包含一个换行符。

“空白”是没有任何其他字符的任何空白字符序列。常用的空白字符有空格(或空白)、水平制表符、换行符或回车符。

“[...] 包含至少一个换行符的空格”表示在 '#' 之前的空白字符序列中存在一个换行符。它在序列中的哪个位置并不重要。

所以这些都是有效的序列,显示为 C 字符串:

"\n\t\t\t#..."
"\n      #..."
"\n#..."
"\n\t#..."
"\n\t #..."
"\n \t#..."

序列中的最后一个标记是序列中第一个标记之后的第一个换行符。

从标记“#”开始,所有下一个标记组成预处理器指令,直到找到下一个换行符。脚注 165 提到了这种序列的术语“线”。

换行符结束预处理指令,即使它出现在调用类似函数的宏中。

类函数宏的调用看起来像 C 中的函数调用,一个带有一对括号的标识符。如果右括号前有换行符,则指令 ands 在那个地方。


编辑:

空白字符在您链接的标准的第7.4.1.10 章“isspace 函数”中具体列出:

标准的空白字符如下:空格('')、换页符('\f')、换行符('\n')、回车符('\r')、水平制表符('\t ') 和垂直制表符 ('\v')。

可以假设预处理器使用了这个函数。

您的困惑可能来自将“[...] 不含换行符的空白 [...]”解释为“空白通常不包括换行”或“换行是特殊的空白字符” 。” 两者都不是真的。

换行符是一个有效的空白字符。它只是在标记预处理器指令的开始和结束的特定情况下具有特殊的含义。这就是为什么他们要求没有任何换行符的空白。

如果空格包含换行符,它将在预处理器的上下文中标记新标记序列的开始。

请注意,预处理器和语言 C 是完全不同的概念。您可以使用预处理器来预处理任何其他源文件,将其用于汇编是很常见的。并且您可以编写 C 源文件而无需任何预处理器指令。

预处理器对 C 一无所知,而 C 编译器对预处理指令一无所知。


推荐阅读