When would you use "signed char" over "unsigned char"?

To my knowledge, there isn't much of a difference between an unsigned char and a signed char besides a signed char ranging from -127 to 128 and an unsigned char ranging from 0 to 255. I'm trying to learn C++ and I've been wondering this for a while. Also, I was a lua programmer for a long time so I'm used to unsigned chars, so I'm just wondering the difference and when you'd rather use a signed char over an unsigned char.

Thanks.


As @SomeProgrammerDude explained and you already knew, you specify signed or unsigned explicitly when you wish to use small integral values. On an AMD-64 architecture (which is the most widely-used architecture for 64-bit general-purpose CPUs, and it probably the one you have on your laptop), a signed char takes up 1 byte and ranges from -128 to 127, while an unsigned char also takes up 1 byte but ranges from 0 to 255.

I would like to push this a little further by showing how using signed or unsigned integral types (such as char , short , int , ...) impact the final program and are actually implemented. I'll use the example of char , but the principle is identical with other integral types.

Assume we have this small program:

// 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;
}

If we have a look at the assembler (the code that is very close to what your CPU actually does), we can observe the difference. Here is the most relevant part of the assembler code:

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.

(If you are curious and want to generate the assembler yourself, run g++ -S main.cpp -o main.s -O0 and have a look at part of the main.s file where you see the main: tag.)

On your memory (specifically, on the stack), both sc and uc will take up 1 byte. In fact, sc and uc actually contain the same value of 255 . However, it's the way the comparison is done that makes sc and uc different.

Thus, this :

there isn't much of a difference between an unsigned char and a signed char

... is ironically 100% true.

The lesson to learn from this is that the numbers programmers work with are just conceptual. In the end, it's all about how you work with the 1s and 0s.

链接地址: http://www.djcxy.com/p/96706.html

上一篇: 如何轻松将无符号字符串转换为字符串?

下一篇: 你什么时候使用“signed char”而不是“unsigned char”?