你何时会使用“signed char”而非“unsigned char”?

时间:2017-03-07 20:17:30

标签: c++

据我所知,unsigned charsigned char除了-127到128之间的签名字符和0到255之间的无符号字符之外没有太大区别。我我试图学习C ++,我一直想知道这一点。另外,我很长一段时间都是一名lua程序员,所以我习惯了无符号字符,所以我只是想知道区别,当你更喜欢使用带符号字符而不是无符号字符时。

感谢。

1 个答案:

答案 0 :(得分:2)

正如@SomeProgrammerDude解释并且您已经知道,当您希望使用小的整数值时,请明确指定signedunsigned。在AMD-64架构(这是64位通用CPU的最广泛使用的架构,它可能是您的笔记本电脑上的架构),signed char占用1个字节,范围从 - 128到127,而unsigned char也占用1个字节,但范围从0到255。

我想通过展示如何使用signedunsigned整数类型(例如charshortint来进一步推动这一点, ......)影响最终的计划并实际实施。我将使用char的示例,但其原理与其他整数类型相同。

假设我们有这个小程序:

// main.cpp

#include <iostream>

int main() {
    signed char   sc = (signed char)255; // equivalent to sc = -1
    unsigned char uc = 255;

    bool signedComp   = (sc <= 5);
    bool unsignedComp = (uc <= 5);

    return 0;
}

如果我们看看汇编程序(代码与你的CPU实际上非常接近),我们可以观察到差异。这是汇编程序代码中最相关的部分:

movb    $-1, -4(%rbp) # sc = -1
movb    $-1, -3(%rbp) # uc = -1 (equivalent to uc = 255)

cmpb    $5, -4(%rbp)  # compare sc and 5, ...
setle   %al           # ... see whether sc was lower or equal (signed comparison), ...
movb    %al, -2(%rbp) # ... and set the boolean result into signedComp.

cmpb    $5, -3(%rbp)  # compare uc and 5, ...
setbe   %al           # ... see whether uc was below or equal (unsigned comparison), ...
movb    %al, -1(%rbp) # ... and set the boolean result into unsignedComp.

(如果您很好奇并希望自己生成汇编程序,请运行g++ -S main.cpp -o main.s -O0并查看main.s文件中您看到main:标记的部分内容。)

在您的内存上(特别是在堆栈上),scuc都会占用1个字节。实际上,scuc实际上包含255相同值。但是,方式进行了比较,使scuc不同。

因此,这个:

  

unsigned charsigned char

之间没有多大区别

......具有讽刺意味的是100%真实。

从中学到的教训是,程序员使用的数字只是概念性的。最后,关于 你如何使用1和0的所有内容。