免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 11607 | 回复: 7
打印 上一主题 下一主题

一个关于unsigned char的极限值可以等于256的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-03-20 11:10 |只看该作者 |倒序浏览
本帖最后由 中山八富力 于 2010-03-20 11:24 编辑

在rhel 5.0 下,好奇想验证一下unsigned char、unsigned short的长度和极值,发现如下:

测试代码  test.c:
#include <stdio.h>

int main(void)
{
        unsigned char uc=-1;
        unsigned short us=-1;

        printf("sizeof(uc)=%d, max value=%d\n",sizeof(uc),uc);
        printf("sizeof(us)=%d, max value=%d\n",sizeof(us),us);

        printf("uc+1 = %d\n",uc+1);
        printf("us+1 = %d\n",us+1);

        return 0;
}


使用gcc test.c 进行编译

运行结果:
sizeof(uc)=1, max value=255
sizeof(us)=2, max value=65535
uc+1 = 256
us+1 = 65536


请问这里 uc+1、us+1  不是应该等于 0 吗?? 我的问题出在哪里了??望各位牛人解答一下

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
2 [报告]
发表于 2010-03-20 11:31 |只看该作者
在用 printf("...%d", uc+1) 打印 uc + 1 的时候,uc 会先被提升为整形(即 int),然后加一,然后打印。另外一个类似。

论坛徽章:
0
3 [报告]
发表于 2010-03-20 12:20 |只看该作者
谢谢2楼的解答,按照你的提示,我把代码修改如下:

#include <stdio.h>

int main(void)
{
        unsigned char uc=-1;
        unsigned short us=-1;
        unsigned int ui=-1;

        printf("sizeof(uc)=%x, max value=%x\n",sizeof(uc),uc);
        printf("sizeof(us)=%x, max value=%x\n",sizeof(us),us);
        printf("sizeof(ui)=%x, max value=%x\n",sizeof(ui),ui);


        printf("1:uc+1 = %x\n",uc+1);
        uc += 1;
        printf("2:uc+1 = %x\n",uc);

        printf("1:us+1 = %x\n",us+1);
        us += 1;
        printf("2:us+1 = %x\n",us);

        printf("1:ui+1 = %x\n",ui+1);
        ui += 1;
        printf("2:ui+1 = %x\n",ui);

        return 0;
}


运行结果:
sizeof(uc)=1, max value=ff
sizeof(us)=2, max value=ffff
sizeof(ui)=4, max value=ffffffff
1:uc+1 = 100
2:uc+1 = 0
1:us+1 = 10000
2:us+1 = 0
1:ui+1 = 0
2:ui+1 = 0


这说明:
1、%d换为%x,能在一定程度上解决问题
2、若printf函数里,设计计算,貌似会先将其提升为整型。(这里无法考证是提升为有符号还是无符号,因为unsigned char、unsigned short对比int太短了)
3、若计算不在printf里进行,则一切都是正确的。

还有一个问题:
unsigned int好像不受上述影响。why??

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
4 [报告]
发表于 2010-03-20 13:54 |只看该作者
本帖最后由 MMMIX 于 2010-03-20 13:56 编辑
谢谢2楼的解答,按照你的提示,我把代码修改如下:
1、%d换为%x,能在一定程度上解决问题

不存在解决问题一说,因为一开始就没有问题。你之所以有疑惑,不是因为代码有问题,而是因为你不理解它的行为。

2、若printf函数里,设计计算,貌似会先将其提升为整型。(这里无法考证是提升为有符号还是无符号,因为unsigned char、unsigned short对比int太短了)

不是貌似,而是肯定,这是 C 标准里面规定了的。即使不存在计算,那些 char, short 型也会被提升为 int 型(因为你用了 %d or %x),而且是 signed int(singed int 足够表示被提升类型的值),这些在 ISO C99 的 section 6.3.1.1 有描述,被称为 integer promotions.

3、若计算不在printf里进行,则一切都是正确的。

前面也不存在错误,这里之所以和前面结果不同,是因为在前面 (printf 中) 是整形提升,而在这里是截断。例如 unsigned char uc = 0xff, 则 uc + 1 = 0x100,截断为 8 位后结果就是 0。

还有一个问题:
unsigned int好像不受上述影响。why??

对,unsigned int 在这里不存在提升问题,都是截断。

论坛徽章:
0
5 [报告]
发表于 2010-03-22 22:33 |只看该作者
谢谢!~~~获益良多~~~~

论坛徽章:
5
白羊座
日期:2014-10-28 11:23:27水瓶座
日期:2015-01-20 10:19:022015亚冠之柏斯波利斯
日期:2015-07-11 18:17:2015-16赛季CBA联赛之同曦
日期:2015-12-23 12:38:582016猴年福章徽章
日期:2016-02-18 15:30:34
6 [报告]
发表于 2010-03-26 19:16 |只看该作者
长见识啦 ,你的解答太详细了,谢谢

论坛徽章:
0
7 [报告]
发表于 2010-03-27 08:31 |只看该作者
如果细心的话还可以发现,"%.2x" 在对待 char 与 unsigned char 变量时也不同

  1. #include <stdio.h>

  2. int
  3. main (void)
  4. {
  5.         char a[256];
  6.         unsigned char b[256];
  7.         int i;

  8.         for (i=0; i<256; i++) {
  9.                 a[i] = b[i] = i;
  10.         }

  11.         printf ("display array a:\n");
  12.         for (i=0; i<256; i++) {
  13.                 printf ("%.2x%s", a[i],
  14.                         (i + 1) % 16 ? " " : "\n");
  15.         }

  16.         printf ("display array b:\n");                                                                                                                                                                     
  17.         for (i=0; i<256; i++) {
  18.                 printf ("%.2x%s", b[i],
  19.                         (i + 1) % 16 ? " " : "\n");
  20.         }

  21.         return 0;
  22. }
复制代码
运行结果

  1. display array a:
  2. 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
  3. 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
  4. 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
  5. 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
  6. 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
  7. 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
  8. 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
  9. 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f
  10. ffffff80 ffffff81 ffffff82 ffffff83 ffffff84 ffffff85 ffffff86 ffffff87 ffffff88 ffffff89 ffffff8a ffffff8b ffffff8c ffffff8d ffffff8e ffffff8f
  11. ffffff90 ffffff91 ffffff92 ffffff93 ffffff94 ffffff95 ffffff96 ffffff97 ffffff98 ffffff99 ffffff9a ffffff9b ffffff9c ffffff9d ffffff9e ffffff9f
  12. ffffffa0 ffffffa1 ffffffa2 ffffffa3 ffffffa4 ffffffa5 ffffffa6 ffffffa7 ffffffa8 ffffffa9 ffffffaa ffffffab ffffffac ffffffad ffffffae ffffffaf
  13. ffffffb0 ffffffb1 ffffffb2 ffffffb3 ffffffb4 ffffffb5 ffffffb6 ffffffb7 ffffffb8 ffffffb9 ffffffba ffffffbb ffffffbc ffffffbd ffffffbe ffffffbf
  14. ffffffc0 ffffffc1 ffffffc2 ffffffc3 ffffffc4 ffffffc5 ffffffc6 ffffffc7 ffffffc8 ffffffc9 ffffffca ffffffcb ffffffcc ffffffcd ffffffce ffffffcf
  15. ffffffd0 ffffffd1 ffffffd2 ffffffd3 ffffffd4 ffffffd5 ffffffd6 ffffffd7 ffffffd8 ffffffd9 ffffffda ffffffdb ffffffdc ffffffdd ffffffde ffffffdf
  16. ffffffe0 ffffffe1 ffffffe2 ffffffe3 ffffffe4 ffffffe5 ffffffe6 ffffffe7 ffffffe8 ffffffe9 ffffffea ffffffeb ffffffec ffffffed ffffffee ffffffef
  17. fffffff0 fffffff1 fffffff2 fffffff3 fffffff4 fffffff5 fffffff6 fffffff7 fffffff8 fffffff9 fffffffa fffffffb fffffffc fffffffd fffffffe ffffffff
  18. display array b:
  19. 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
  20. 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
  21. 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
  22. 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
  23. 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
  24. 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
  25. 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
  26. 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f
  27. 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f
  28. 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f
  29. a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af
  30. b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf
  31. c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf
  32. d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df
  33. e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef
  34. f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff
复制代码
从而也证明了 MMMIX 的观点

论坛徽章:
0
8 [报告]
发表于 2010-05-25 16:26 |只看该作者
果然是精华贴,以后真的要主义细节问题了!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP