这些奇怪的问号是什么意思?

6

我遇到了一些看起来奇怪的代码。它甚至不像是C语言,但出乎意料的是,它可以在我的C编译器上编译和运行。这是C语言的某种非标准扩展吗?如果是,它存在的原因是什么?

??=include <stdio.h>

int main()
??<
  const char arr[] = 
  ??<
    0xF0 ??! 0x0F,
    ??-0x00,
    0xAA ??' 0x55
  ??>;

  for(int i=0; i<sizeof(arr)/sizeof(*arr); i++)
  ??<
    printf("%X??/n", (unsigned char)arr??(i??));
  ??>

  return 0;
??>

输出:

FF
FF
FF

这是我朝向混淆的第一步。我认为许多 C 语言程序员都不知道这一点。 - Abhineet
2
可能是C++代码中“???”的含义的重复问题。 - Jongware
1
你应该重构看起来像这样的代码。一个快速的方法是用"? ?="替换"??=",在其上运行gcc-trigraph-E,然后在生成的输出中用"#"替换"? ?=",同时删除gcc的前几行输出。 - Joel Dentici
@Jongware,这并不是重复的问题,因为这是针对C语言的。C++有额外的三字符组合,你提到的重复问题中没有提到其中任何一个,所以它并不是一个完整的答案。也没有提到三字符组合的含义。 - Lundin
1个回答

14
该代码完全符合C标准的任何版本。"?? "机制称为"三字符序列",是为了允许以另一种方式打印某些符号而引入C语言的。看起来,程序是为了演示各种三字符序列而编写的。
早些时候,许多计算机及其键盘都基于一个名为ISO 646的旧符号表,其中不包含C语言中使用的所有符号,如"\ { } [ ]"。这使得一些国家的程序员甚至无法编写C代码,因为他们的国家键盘布局缺少必要的符号。为了避免重新制作键盘和符号表,C语言进行了改变。
因此,引入了三字符序列。今天它们被认为是完全过时的功能,不建议使用它们。例如,GCC会在使用它们时给出警告。尽管如此,它们仍然保留在C标准中以实现向后兼容性,并且所有C编译器都必须支持它们。
现有的三字符序列包括(C11 5.2.1.1三字符序列):
??=  #
??(  [
??/  \
??)  ]
??'  ^
??<  {
??!  |
??>  }
??-  ~

左侧列是三字母序列,右侧列是其含义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接