计算机如何区分类型?

How does the computer make the difference between types?

我想知道我的计算机如何区分完全相同的一组 0 和 1。我真的不知道应该问什么问题,但我想知道例如当我在 C 中时:

int main(){
   __uint8_t a = 97;
   printf(" Here is a char : %c\n Here is a number : %d\n", a, a);
   return 0;
}

它怎么知道他什么时候应该打印 'a' 或 97。我知道这是由于 %c 和 %d,但到底发生了什么?

谢谢大家!

你说的那个%c或者%d叫做转换说明符,每一个都有具体的意思。他们预先决定了如何处理、格式化和打印相应的参数。

引用自C11,章节§7.21.6.1,一些例子:

  1. The conversion specifiers and their meanings are:

d,i The int argument is converted to signed decimal in the style [−]dddd.

c If no l length modifier is present, the int argument is converted to an unsigned char, and the resulting character is written.

像那样,每个转换说明符都有关于它们如何解释和打印提供的参数或忽略它们的相关规则(例如:%%)。

电脑不知道。你在printf格式字符串中通过%c%d告诉他。

在这个特定的体系结构中使用 ASCII 码是一种习惯,其中 97 是 a

您可以使用您喜欢的任何编码编写您自己的输出函数。

当您要求使用 %c 打印时,计算机将查看 ASCII table。计算机只能理解数字(二进制​​),此 table 是如何将数字更改为字符的参考(见下文),因为您可以看到十进制的 a = 97 等于二进制的 0110 0001。在代码中,你可以要求以不同的格式显示一个值(%d 表示十进制,%f 表示浮点数,%c 表示字符......)但它在计算机中始终是二进制字

问我是否需要有关低硬件层的更多信息

I am wondering how my computer can make the difference between the exact same set of 0s and 1s.

在一般情况下,不同的指令会以不同的方式解释相同的位序列。例如,x86 ADDL 指令将其操作数解释为 32 位整数值,而 ADDSD 将其操作数解释为标量双精度浮点值。

您在源代码中指定的类型信息(intdoublechar 等)决定了编译器生成的机器指令。例如,如果您有代码

double a = 1.0, b = 2.0;
double c = a + b;

编译器会将其翻译成

movsd   -8(%rbp), %xmm0     // move value of a (1.0) to xmm0 register
addsd   -16(%rbp), %xmm0    // add value of b (2.0) to value in xmm0, store result in xmm0
movsd   %xmm0, -24(%rbp)    // copy value in xmm0 (3.0) to c

如果将 double 更改为 int

int a = 1, b = 2;
int c = a + b;

然后编译器生成代码:

movl    -4(%rbp), %edx   // move value of a (1) to edx register
movl    -8(%rbp), %eax   // move value of b (2) to eax register
addl    %edx, %eax       // add value in edx to eax, store result in eax
movl    %eax, -12(%rbp)  // copy value in eax to c

不过对于你的具体问题:

I know it is due to the %c and %d, but what is going on really ?

整数 value 97 存储为位序列 - 假设为 8 位类型,该位序列为 01100001,或 0x61

%c 基本上表示 "present this value as the corresponding symbol in the basic character set" - IOW,符号 'a'。某处存在整数值和相应符号之间的映射。

%d 转换说明符基本上表示 "create a decimal string representation of this value" - 即发出字符 {'9', '7'} 序列

具体如何将值映射到字符并显示是实现和终端驱动程序的函数,并且因系统而异。