"C变量型号与机器有关." 这是真的吗?已签名和未签名的号码;

cla*_*aws 4 c assembly types

我被告知C类型取决于机器.今天我想验证它.

void legacyTypes()
{
    /* character types */
    char k_char = 'a';

        //Signedness --> signed & unsigned
        signed char k_char_s = 'a';
        unsigned char k_char_u = 'a';

    /* integer types */
    int k_int = 1; /* Same as "signed int" */

        //Signedness --> signed & unsigned
        signed int k_int_s = -2;
        unsigned int k_int_u = 3;

        //Size --> short, _____,  long, long long
        short int k_s_int = 4;
        long int k_l_int = 5;
        long long int k_ll_int = 6;

    /* real number types */
        float k_float = 7;
        double k_double = 8;
}
Run Code Online (Sandbox Code Playgroud)

我使用minGW C编译器在32位机器上编译它

_legacyTypes:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $48, %esp
    movb    $97, -1(%ebp)  # char
    movb    $97, -2(%ebp)  # signed char
    movb    $97, -3(%ebp)  # unsigned char
    movl    $1, -8(%ebp)    # int
    movl    $-2, -12(%ebp)# signed int 
    movl    $3, -16(%ebp) # unsigned int
    movw    $4, -18(%ebp) # short int
    movl    $5, -24(%ebp) # long int
    movl    $6, -32(%ebp) # long long int
    movl    $0, -28(%ebp) 
    movl    $0x40e00000, %eax
    movl    %eax, -36(%ebp)
    fldl    LC2
    fstpl   -48(%ebp)
    leave
    ret
Run Code Online (Sandbox Code Playgroud)

我在GCC(linux)上的64位处理器(Intel Core 2 Duo)上编译了相同的代码

legacyTypes:
.LFB2:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
    movb    $97, -1(%rbp) # char
    movb    $97, -2(%rbp) # signed char
    movb    $97, -3(%rbp) # unsigned char
    movl    $1, -12(%rbp) # int
    movl    $-2, -16(%rbp)# signed int 
    movl    $3, -20(%rbp) # unsigned int
    movw    $4, -6(%rbp)   # short int
    movq    $5, -32(%rbp) # long int
    movq    $6, -40(%rbp) # long long int
    movl    $0x40e00000, %eax
    movl    %eax, -24(%rbp)
    movabsq $4620693217682128896, %rax
    movq    %rax, -48(%rbp)
    leave
    ret
Run Code Online (Sandbox Code Playgroud)

意见

  • char,signed char,unsigned char,int,unsigned int,signed int,short int,unsigned short int,signed short int all占用相同的no.32位和64位处理器上的字节数.

  • 唯一的变化是在long intlong long int这两个占据64位机器上的32位机器和64位上的32位.

  • 还有指针,它们在32位CPU上采用32位,在64位CPU上采用64位.

问题:

  • 我不能说,书中所说的是错的.但我在这里遗漏了一些东西.究竟什么"变量类型与机器有关?"
  • 如您所见,未签名和签名号码的说明没有区别.那么为什么两者可以解决的数字范围不同呢?
  • 我正在阅读如何在不同的机器上保持C变量类型的固定大小?我没有得到问题的目的或他们的答案.什么保持固定大小?它们都是一样的.我不明白这些答案将如何确保相同的大小.

编辑:

是不是不可能在不同的机器上提供相同的尺寸?我的意思是,如何在64位和32位机器上保持相同的指针大小?

Pét*_*rök 8

那里有更多的平台,其中一些是16位甚至8位!在这些方面,您会发现所有上述类型的尺寸差异更大.

相同基本类型的有符号和无符号版本在任何平台上占用相同的字节数,但是它们的数字范围是不同的,因为对于带符号的数字,在有符号和无符号域之间共享相同范围的可能值.

例如,16位带符号的int可以具有从-32767(或许多平台上的-32768)到32767的值.相同大小的无符号int在0到65535的范围内.

在此之后,希望您更好地理解所提问题的重点.基本上如果你编写一个程序,假设例如你的signed int变量将能够保持2*10 ^ 9(20亿)的值,那么你的程序是不可移植的,因为在某些平台上(16位及以下)这个值会导致溢出,导致沉默,很难找到错误.因此,例如一个16位的平台,你需要在#define你的整数是long为了避免溢出.这是一个简单的例子,可能无法在所有平台上运行,但我希望它能为您提供一个基本的想法.

平台之间所有这些差异的原因是,在C标准化的时候,已经有许多C编译器在过多的不同平台上使用,因此为了向后兼容,所有这些变量都必须被认为是有效的.


oef*_*efe 7

机器相关不太准确.实际上,它是实现定义的.它可能取决于编译器,机器,编译器选项等.

例如,使用Visual C++,long即使在64位计算机上也是32位.