我有一个简单的代码
char t =(char)(3000);
然后t的值是-72。十六进制值3000是0xBB8。我无法理解为什么t的值是-72。
感谢您的回答。
我不知道Mac。所以我的结果是-72。据我所知,MAC正在使用Big Endian,它会影响结果吗?我没有任何MAC计算机可以测试,所以我想知道MAC人员。
答案 0 :(得分:12)
十六进制值3000是0xBB8。
所以char的十六进制值(顺便说一句,似乎在编译器上签名)是0xB8。
如果它是无符号的,则0xB8将为184.但由于它已经签名,其实际值减少了256,即-72。
如果您想知道原因,请阅读two's complement表示法。
答案 1 :(得分:4)
char
是8位(只能表示0-255范围)。试图将 3000 投射到char
是...... 不可能是不可能的,至少对于你想要的是什么。
答案 2 :(得分:3)
这种情况正在发生,因为3000的值太大而导致溢出。 Char 通常从-128到127签名,或0到255无符号,但它可以根据实现而改变。
答案 3 :(得分:2)
char
是具有一定范围的可表示值的整数类型。 int
也是具有一定范围的可表示值的整数类型。通常情况下,int
的范围比[{1}}的范围宽得多。当您尝试挤入不属于char
范围的char
int
值时,值当然不会“适合”。实际结果是实现定义的。
在您的情况下,char
的{{1}}值不符合您实施的3000
范围。因此,您不会得到int
作为结果。如果您真的想知道为什么它具体出现在char
- 请参阅实施附带的文档。
答案 4 :(得分:1)
char(通常)只有8位,因此您无法存储大小为3000的值(这至少需要 11 12位)。因此,如果您想在一个字节中存储3000,它将只包装。
由于3000是0xBBA,它需要两个字节,一个0x0B,一个是0xBA。如果您尝试将其存储在单个字节中,您将只获得其中一个(0xBA)。由于一个字节(通常)是签名的,即-72。
答案 5 :(得分:1)
根据规定,16位十六进制值3000为0x0BB8
。虽然实现特定,但是从您发布的结果中,这可能会以B8 0B
的形式存储在8位内存中(某些体系结构会将其存储为0B B8
。这称为{ {3}}。)
char 可能不是16位类型。同样,这是特定于实现的,但是根据您发布的结果,它似乎是8位,这并不罕见。
因此,当您的程序为您的值分配了8位内存时,您将在该内存中存储两倍的信息。当程序稍后检索此值时,它将仅拉出第一个存储的八位字节,在本例中为B8
。 0B
将被忽略,如果它最终覆盖了重要的内容,可能会在以后出现问题。这被称为endianness,非常糟糕。
假设buffer overflow(技术上实现特定,但是合理的假设),B8
的十六进制值转换为-72
或184
十进制,取决于您是否处理签名或无符号类型。由于您未指定任何一个,因此您的编译器将使用它的默认值。再一次,这是特定于实现的,并且您的编译器似乎与 signed char 一起使用。
因此,您得到-72
。但是不要指望在任何其他系统上得到相同的结果。
答案 6 :(得分:-2)
char
用于存放单个字符,您尝试将4位数int
存储在一个字符中。也许您打算使用字符数组或字符串(在这种情况下为char t[4]
)。
将int转换为字符串(未经测试):
#include <stdlib.h>
int main() {
int num = 3000;
char numString[4];
itoa(num, buf, 10);
}
答案 7 :(得分:-6)
哦,我明白了,它是溢出,它就像char只是从-256到256或类似的东西我不确定,就像你有一个var类型的最大限制是256,你加1,比它变成-256等等