关于字符(char)的问题:难道字符不是8位(8 bits)?

vcf_reader 2008-02-28 01:07:28
关于字符(char)的问题:难道字符不是8位(8 bits)?

最近正好针对字符得编程做得多一些。发现了一个问题,在Visual C++和C++ Builder 平台都存在的问题。
编译环境:缺省设置。
根据MSDN的解释,在C++中,char 是一个字节(8bits),unsigned char 也是一个字节(8bits)。两者具有共同的数据范围:0x00到0xFF,如果用它们表示整数的话,范围分别就是-128到127,0到255;但用16进制表示都是一样的:即00到FF。

但是在输出时,发生了奇怪的现象:

代码:
......
char x = 0x80;
CString str;//CString 是MFC定义的字符串类。
str.Format("%X",x);
......
结果:
str显示为32bit的数:FFFFFF80,显然,与MSDN的描述矛盾了。MSDN说是8bits,结果却是32bits!!!
如果,给x赋的值小于等于0x7F,那么str的内容只有8bits,与MSDN的描述一致。
又如果把上面的变量x声明为unsigned char ,则不论给x赋何值,str的内容永远都是8bits,与MSDN的描述一致。

上面的问题在C++ Builder平台也是如此。
...全文
539 16 打赏 收藏 举报
写回复
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
iambic 2008-03-01
  • 打赏
  • 举报
回复
不一定是8位。
wfwsm 2008-03-01
  • 打赏
  • 举报
回复
%x 是以十六进制输出无符号整型的;
所以 str.Format( "%x", x ) 会自动把x 转换成无符号整形的

例如测试如下:
__int64 a = 0x0000ffffffffffff;
str.Format( "%x", a );
str = "ffffffff";

转换的规则是 不足32位的 高位是1 扩展位补1
高位是0 扩展位补0;
JYeung 2008-03-01
  • 打赏
  • 举报
回复
str.Format("%X",x);
format是不会检查type的。所以 %X就直接拿了在&x的32bit
正确写法是 str.Format("%02hhX",x);
vcf_reader 2008-02-28
  • 打赏
  • 举报
回复
估计,linux_328 说的“32位系统上%x默认是按照32位数来处理的”才是正解。谢谢。
sjh_lucky 2008-02-28
  • 打赏
  • 举报
回复
个人观点:CString 实际上封装的是一个字符串的类,它给出的字符串首字符的指针的值,而我们应该知道指针的大小是4个字节,也就是32BIT了。应该是这样的。
linux_328 2008-02-28
  • 打赏
  • 举报
回复
32位系统上%x默认是按照32位数来处理的,也就是一般的int32,在计算机内部,负数是用补码表示的,char是有符号的数,但char的最高位为1时,是负数,转换为int32是也是负数,所以但char是0x80是,最高位为负数,转换为int32后为FFFFFF80,但unsigned char为非负数,不存在补码的表示,也转换为 unsigned int32,值为00000080,但%x默认不打起面的0的,所以为显示为0x80, 但char为0x7F是,最高位为0,是非负数,转换为int32后为0x0000007F,所以打印出也为0x7F
lucian2007 2008-02-28
  • 打赏
  • 举报
回复
有符号数从8位扩展到32位就是这样,有符号数是补码形式存储!
dubiousway 2008-02-28
  • 打赏
  • 举报
回复
回lz, 8bit char, 如果是有符号数,其范围是 -128~127, 所以,0x80 表示的是 最小负数 -128,因此那个最高位的1 是数值,不是符号。所以必须在内存扩展符号位。否则无法区分 有符号数的 0x80和无符号数的 0x80
vcf_reader 2008-02-28
  • 打赏
  • 举报
回复
没有高人吗?
vcf_reader 2008-02-28
  • 打赏
  • 举报
回复
符号位应该是最高位
对8bit而言,第7位就是符号位。>=0x80时,第7位就是1,就是负数!

难道这个问题平时没有人注意到吗?
dubiousway 2008-02-28
  • 打赏
  • 举报
回复
char x= 0x80;
当 x 参与运算的时候,只能进行符号扩展,否则符号位不久没了?
所以你Format的时候可能需要加长度限制吧,没试过,你试试
vcf_reader 2008-02-28
  • 打赏
  • 举报
回复
很高兴终于又回复开始沾边了。
只是,既然是8bits,为什么输出却是32bits呢?
flyingscv 2008-02-28
  • 打赏
  • 举报
回复
正是因为char是8位,所以当char最高位是1(0x80)的时候,转换为32bit需要全补1(表示同一个负数)
否则补零

unsigned char没有符号位,所以全补零,表示同一个unsigned值
vcf_reader 2008-02-28
  • 打赏
  • 举报
回复
哎,都没有回答到点上。
lucian2007 2008-02-28
  • 打赏
  • 举报
回复
应该是补成4个字节(32位)方便处理
hastings 2008-02-28
  • 打赏
  • 举报
回复
看几位不是这么看的;
要用sizeof来看.
str.Format只是个函数,
里面怎么实现,全由微软说了算,高兴几位就几位,
前面补个100个0都没关系
发帖
C++ 语言

6.3w+

社区成员

C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
帖子事件
创建了帖子
2008-02-28 01:07
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下