C语言的数据类型及用%u输出char的问题

今天学弟问了我两个很好的问题:
1、各种基本数据类型的本质区别是什么?网上说是分配的字节数不同,但是也有两种不同的数据类型分配的字节数一样的情况啊。
2、我输入
char a=-1;
printf(”%u”,a);
我的理解是 char是一个字节的,用char数据类型保存-1应该是11111111(补码),然后用%u输出应该是2的八次方减一,但是为啥结果是2的32次方-1

下面是我查阅资料后对这两个问题的看法:


数据类型的区别

首先要明确每种基本数据类型的位数分别为多少,直到现在我还有同学觉得int最大值一定是65535.获得位数可以用sizeof(),想得到最小值最大值可以用INT_MAX,INT_MIN之类的常数,头文件是<limit.h>
这里写图片描述
然后,各个基本数据类型的本质区别,是对他们存储各位的处理不同.
举例来说,int和float都是4字节32位.
但是int是由1个符号位,31个存储位组成
float由1个符号位,8个指数位,23个尾数位组成.
所以尽管它们的位数一样,但是相同位置的位在不同的类型中代表的意义不同.


用%u输出char的问题

char的定义

c语言标准里,有三种char:char,signed char,unsigned char.
signed char由1个符号位和7个数字位组成,可表示的范围是-128到127
unsigned char由8个数字位组成,可表示范围是0到255
而char,在C标准里属于未定义,由编译器实现决定到底是signed还是unsigned.
在自己的电脑上可以这样测试
这里写图片描述
我的电脑char的默认实现是signed char

int转char

char(8位)是低类型,int(32位)是高类型.

由int转到char只需要截断前24位,得到后8位即可.

int i=-1;
signed char sc=a;
unsigned char uc=a;

i在内存中的表示为0xFFFFFFFF
sc和uc在内存中均为0xFF
虽然它们在内存中是一样的,但是表示的意义不一样(参考第一题)
sc为-1,uc为255.

char转int

由char转换到int需要提升24位.
如果是unsigned char,前面24位全部补0.
如果是signed char,前面24位全部补符号位(即本来char的最高位).
举个栗子

signed char sc=-1; //0xFF -1
unsigned char uc=-1; //0xFF 255
int i1=sc; //0xFFFFFFFF -1
int i2=sc; //0x000000FF 255

这里写图片描述

char转unsigned int

同样是低类型转高类型,与char转int完全相同.

signed char sc=-1; //0xFF -1
unsigned char uc=-1; //0xFF 255
unsigned int i1=sc; //0xFFFFFFFF 4294967295
unsigned int i2=sc; //0x000000FF 255

但是unsigned int与int相比没有符号位,导致表示的数字不同”4294967295”

printf与char

有一个神奇的规定是,用printf输出char类型的参数时,会将它提升到”对应”的int类型.
“对应”的意思是:signed char提升到signed int,unsigned char 提升到unsigned int
这个转换在使用%c输出符号的时候不会影响到任何东西,一截断就好了.

但是如果是%d或者%u,就会将按对应的int类型进行输出

    char a=-1printf"%u",a);

所以以上代码实际上:
1.将int类型的-1赋给signed char类型的a,从0xFFFFFFFF截断得到0xFF,即-1
2.把signed char -1提升到到int类型 0xFFFFFFFF ,即 -1
3.按无符号整形输出,结果是 4294967295

可以思考一下如果这里的char是unsigned char会怎么样
以及思考一下

    signed char a=-1,b=-257,c=4294967295,d=255;
    unsigned char e=-1,f=-257,g=4294967295,h=255;
    printf("%u %d\n%u %d\n%u %d\n%u %d\n",a,a,b,b,c,c,d,d );
    printf("%u %d\n%u %d\n%u %d\n%u %d\n",e,e,f,f,g,g,h,h );
    printf("%u %d\n%u %d\n%u %d\n%u %d\n",-1,-1,-257,-257,(int)4294967295,(int)4294967295,255,255 );

多用程序验证.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值