我希望这个问题有道理!我目前正在学习C(简单!),我对表映射的工作方式感兴趣。
我使用扩展的ASCII表作为实验。 (http://www.ascii-code.com)
例如,我可以创建一个char
并将其值设置为代码,如下所示:
char charSymbol = '~';
我也可以像这样指定完全相同的值:
char charDec = 126;
char charHex = 0x7E;
char charOct = 0176;
char charBin = 0b01111110;
无论我选择哪种上述声明(如果我正确理解事物),每个变量在内存中保存的值总是完全相同。也就是说,二进制表示(01111110)
我的问题是;编译器是否保留扩展的ASCII表并在编译期间执行二进制值查找?如果是这种情况,程序运行的机器是否也保持扩展的ASCII表,以便知道当程序被要求打印01111110以屏幕显示它打印一个" 〜" ?
答案 0 :(得分:3)
实际上,从技术上讲,您的文本编辑器是带有ASCII(或Unicode)表的文本编辑器。该文件只是作为一个字节序列保存;编译器实际上并不需要有一个ASCII表,它只需要知道哪些字节做了什么。 (是的,编译器在逻辑上将字节解释为ASCII,但是如果你查看编译器的机器代码,你所看到的是一堆字节与固定字节值的比较)。
另一方面,正在执行的计算机有一个ASCII表某处,用于将程序输出的字节映射为可读字符。该表可能在您的终端仿真器中。
答案 1 :(得分:3)
对于您问题中的大多数代码,不需要ASCII查找表。
请注意,在C中,char
是一个整数类型,就像int
一样,但更窄。像'x'
这样的字符常量(由于历史原因)的类型为int
,而基于ASCII的系统x
与120
几乎完全相同。
char charDec = 126;
char charHex = 0x7E;
char charOct = 0176;
char charBin = 0b01111110;
(标准C不支持像0b01111110
这样的二进制常量;这是gcc扩展名。)
当编译器看到像126
这样的整数常量时,它会从中计算一个整数值。为此,需要知道1
,2
和6
是十进制数字,以及它们的值。
char charSymbol = '~';
为此,编译器只需要识别~
是有效字符。
编译器从文本文件C源中读取所有这些字符。该文件中的每个字符都存储为8位序列,表示0到255之间的数字。
因此,如果您的C源代码包含:
putchar('~');
(并且~
恰好具有值126),然后编译器需要知道的是126是有效字符值。它会生成将值126
发送到putchar()
函数的代码。在运行时,putchar
将该值发送到标准输出流。如果标准输出转到文件,则值126
将存储在该文件中。如果它要去终端,终端软件会进行某种查找,将数字126
映射到显示为代字符字符的字形。
编译器必须识别特定的字符值。他们必须认识到+
是加号字符,用于表示加法运算符。但是对于输入和输出,不需要ASCII映射,因为每个ASCII字符在处理的所有阶段(从编译到执行)都表示为数字。
那么编译器如何识别'+'
字符? C编译器通常用C编写。在编译器自己的源代码中,可能有类似的东西:
switch (c) {
...
case '+':
/* code to handle + character */
...
}
因此编译器在其输入中识别+
,因为它自己的源代码中有+
- 并且+
(在编译器源代码中存储为8位数字) 43)导致数字43存储在编译器自己的可执行机器代码中。
显然第一个C编译器不是用C编写的,因为没有任何东西可以编译它。早期的C编译器可能用B,BCPL或汇编语言编写 - 每个编译器都由编译器或汇编器处理,可能识别+
,因为它自己的源代码中有+
码。每一代C编译器都将+
的“知识”传递给它编译的下一个C编译器。 +
为43的“知识”不一定写在源代码中;每次使用旧编译器编译新编译器时都会传播它。
有关此问题的讨论,请参阅Ken Thompson的文章"Reflections on Trusting Trust"。
另一方面,您也可以使用在基于ASCII的系统上运行的编译器,该系统为基于EBCDIC的系统生成代码,反之亦然。这样的编译器必须具有从一个字符集到另一个字符集的查找表映射。
答案 2 :(得分:1)
C语言的类型安全性非常弱,这就是为什么你总是可以为字符变量赋一个整数。
您使用了整数的不同表示来分配给字符变量 - 这在C编程语言中是受支持的。
当您在C程序的文本文件中键入“〜”时,文本编辑器实际上转换了键击并存储了其ASCII等效项。因此,当编译器解析C代码时,它没有感觉到写的是〜(代字号)。在解析时,当编译器遇到等价于'(即单引号)的ASCII时,它进入一种模式以读取下一个字节,作为适合char变量后跟另一个'(单引号)的内容。由于char变量可以具有0-255个不同的值,因此它涵盖整个ASCII集,包括扩展字符集。
使用汇编程序时也是如此。
在完全不同的游戏中打印到屏幕 - 这是I / O系统的一部分。 当您键入键盘上的特定字符时,映射整数的脉冲进入并在读取程序的内存中稳定。同样,当您在打印机或屏幕上打印特定的整数时,该整数将采用相应字符的形状。
因此,如果要在int变量中打印整数,则有一些例程可以转换每个数字并为每个数字发送ASCII代码,I / O系统会将它们转换为字符。
答案 3 :(得分:0)
所有这些值彼此完全相同 - 它们只是相同值的不同表示,因此编译器在将您的书写文本转换为字节值后,以完全相同的方式查看它们。