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上一篇: 如何轻松将无符号字符串转换为字符串?