C 计算机如何区分不同的类型?

C 计算机如何区分不同的类型?,c,binary,cpu,computer-science,C,Binary,Cpu,Computer Science,我想知道我的电脑是如何区分完全相同的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称为转换说明符,它们每个都有特定的含义。它们预先决

我想知道我的电脑是如何区分完全相同的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章,一些示例:

  • 转换说明符及其含义如下:
  • d,i
    int参数转换为样式中的带符号十进制数[−]dddd

    c
    如果不存在
    l
    长度修饰符,则
    int
    参数将转换为
    无符号字符
    ,并写入结果字符


    与此类似,每个转换说明符都有相关的规则,用于解释和打印提供的参数或忽略它们(例如:
    %%
    ).

    您提到的
    %c
    %d
    称为转换说明符,每一个都有特定的含义。它们预先决定了如何处理、格式化和打印相应的参数

    引用
    C11
    ,第§7.21.6.1章,一些示例:

  • 转换说明符及其含义如下:
  • d,i
    int参数转换为样式中的带符号十进制数[−]dddd

    c
    如果不存在
    l
    长度修饰符,则
    int
    参数将转换为
    无符号字符
    ,并写入结果字符


    与此类似,每个转换说明符都有相关的规则来解释和打印提供的参数或忽略它们(例如:
    %%
    )。

    计算机不知道。您可以通过
    %c
    %d
    printf
    格式字符串中告诉他

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


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

    计算机不知道。您可以通过
    %c
    %d
    printf
    格式字符串中告诉他

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


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

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


    询问我是否需要有关低硬件层的详细信息当您要求使用%c打印时,计算机将查看ASCII表。计算机只能理解数字(二进制),此表是如何将数字更改为字符的参考(见下文)正如您可以看到的那样,十进制中的a=97等于二进制中的0110 0001。在代码中,您可以要求以不同的格式显示一个值(%d表示十进制,f表示浮点,c表示字符…),但它在计算机中始终是一个二进制字

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

    我想知道我的电脑是如何区分完全相同的0和1的

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

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

    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
    
    但是,对于您的具体问题:

    我知道这是因为%c和%d,但到底发生了什么

    整数值
    97
    存储为位序列-假设为8位类型,则该位序列为
    0110001
    0x61

    %c
    基本上是说“将此值作为基本字符集中的对应符号呈现”-低,符号
    'a'
    。在某个地方,整数值和对应符号之间存在映射

    %d
    转换说明符基本上说是“创建此值的十进制字符串表示形式”-也就是说,发出字符序列
    {'9','7'}

    值映射到字符和显示的确切方式取决于实现和终端驱动程序,这将因系统而异

    我想知道我的电脑是如何区分完全相同的0和1的

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

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

    double a = 1.0, b = 2.0;
    double c = a + b;
    
    编译器会将其转换为