无符号字符的最大值是多少?

8
#include <stdio.h>
int main()
{
    unsigned char i=0x80;
    printf("%d",i<<1);
    return 0;
}

为什么这个程序会输出256?

据我理解,由于0x80= 0b10000000,并且无符号字符有8位,左移后的'1'应该溢出,输出应该是0而不是256。


2
不想作为答案发布,因为我不确定,但是不是因为%d是整数吗?所以,幕后的代码可能会将i<<1分配给一个整数来打印它,这意味着它适合并且不会溢出。尝试执行printf("%c", i<<1); - Stephen
@Stephen:应该发表答案了 ;) - KevenK
@Stephen:当我使用%c时,输出为空白。 - Variance
噢,好吧,我想我有点朝着正确的方向。抱歉%c没起作用——我手头没有编译器来检查它! - Stephen
在大多数编译器上,i << n 将产生一个整数,而不管原始类型是什么。 - Brian S
2个回答

14

这是由C的整数提升规则导致的结果。基本上,任何进入表达式的变量都会被“提升”,以便像这样的操作不会失去精度。然后,根据C的可变参数规则,它作为int传递给printf

如果您想要您所寻找的内容,您需要将其强制转换回unsigned char

#include <stdio.h>
int main()
{
    unsigned char i=0x80;
    printf("%d",((unsigned char)(i<<1)));
    return 0;
}

注意:根据Stephen评论中指定的使用%c是不起作用的,因为%c还需要一个整数。

编辑:或者你可以这样做:

#include <stdio.h>
int main()
{
    unsigned char i=0x80;
    unsigned char res = i<<1;
    printf("%d",res);
    return 0;
}

或者

#include <stdio.h>
int main()
{
    unsigned char i=0x80;
    printf("%d",(i<<1) & 0xFF);
    return 0;
}

1
@Nathon:这不就是我做的吗? - Billy ONeal
1
奇怪,我一定是戴上了眼罩。 - nmichaels
1
"%c""%d" 都接受一个 int"%c" 将其 int 转换为一个 unsigned char,然后打印该字符。因此,使用 Stephen 的评论中指定的 %c 不起作用,因为 %c 也期望一个整数。 - chux - Reinstate Monica
@R..:为了完整性,需要提到的是,unsigned char 会晋升(promotes)为signed int unsigned int,具体取决于是否可以用signed int来表示 unsigned char 的所有值,并且 "%c" 格式说明符(specifier)期望一个 signed int,这是几种整数类型之一。 - Nisse Engström
@Nisse:当回答初学者的问题时,我尽量避免关于平台的假设性细节,这些平台很可能实际上并不存在。 - Billy ONeal
显示剩余4条评论

0

不要忘记为打印无符号数指定格式。

printf("%u",(unsigned char)(i<<1));

由于 C 语言的提升规则,参数很可能会以“有符号整数”而不是“无符号整数”的形式传递给 printf 函数。因此,您应该将参数强制转换为与格式说明符匹配的类型。 - Nisse Engström

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接