让你秒懂对char和unsigned char 以%d或%u形式打印的核心

左图无符号unsigned char的数值图,可知,是由0~255。

右图是有符号char(char和 signed cahr)的数值图,可知是由 -128~127。

截断:

将一个整数存储到char里面,由于char是一个字节大小,对于四个字节大小的整数,会发生截断,只保留补码的最后8位。

整形提升:

意义在于将截断后的8位补充到32位,

规则:对char和signed char(有符号char)这种有符号位的采用左补24个符号位(截断后的8个比特位的符号位)。

对unsigned char 这种无符号位的采用直接左补24个0。

整形提升后的打印;

一:%u

%u是以无符号的形式打印整数,所以,我们整形提升后得到的32位补码直接可以作为原码 ,再打印出结果。

二:%d

%d是以有符号的形式打印整数,所以,我们整形提升后得到的32位补码,要先观察32的第一位,如果是1,则是负数,需要将这32位补码转化为原码(-1,符号位不变按位取反);如果是0,则是正数,原返补码相同,直接打印即可。

重点:整形提升需要注意char是否有无符号,但是提升完毕后,不管是%d,还是%u打印,都不需要在考虑char是否有无符号,而是要站在%d和%u的角度去考虑整形提升后的32位是直接打印(%u),还是要从补码换成原码(%d)。

题目讲解:

1.
// 输出什么?
#include <stdio.h>
int main ()
{
    char a = - 1 ;
    signed char b =- 1 ;
    unsigned char c =- 1 ;
    printf ( "a=%d,b=%d,c=%d" , a , b , c );
    return 0 ;
} //a=-1,b=-1,c=255
首先abc截断后的8位都是一样的(1111 1111),其次a,b都是有符号char,所以a,b的整形提升后的32位一样(1111 1111 1111 1111 1111 1111 1111 1111 ),又都是按照%d打印,32位要转化成原码,符号位为1,所以为负数,原码为 (1000 0000 0000 0000 0000 0000 0000 0001),结果就是-1。
对于c, 截断后的8位都是一样的(1111 1111),整形提升无符号char,所以左补24个0,此时32 位为(0000 0000 0000 0000 0000 0000 1111 1111),要以%d打印,第一位为0,所以是正数,原反补相同,直接作为原码打印,255。
2.
#include <stdio.h>
int main ()
{
    char a = - 128 ;
    printf ( "%u\n" , a );
    return 0 ;
}//4294967168
a截断后为(1111 1111),整形提升,有符号char左补符号位,所以32个1,又以%u打印,所以,直接补码打印即可。

3.
unsigned int i ;
for ( i = 9 ; i >= 0 ; i -- )
{
    printf ( "%u\n" , i );
} //从9~0然后从4294967168递减。
从9~0很简单,当-1的时候,补码全为1,而%u打印,补码直接打印,所以结果为4294967168,然后再递减1。
4.
int main ()
{
    char a [ 1000 ];
    int i ;
    for ( i = 0 ; i < 1000 ; i ++ )
  {
        a [ i ] = - 1 - i ;
  }
    printf ( "%d" , strlen ( a ));
    return 0 ;
}//结果为255
char的范围在-128~127,a【i】从-1递减开始1(-1,-2,-3)到-128,然后由图可知会从,127到0,总的来说,从-1~-128,然后从127~0,而strlen的判断条件是‘\0’,‘\0’的ascll码值就是0,所以在a【i】=0的时候,会停止,总计在0之前有255个数。

 

 

  • 28
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值