(转) char c=128;printf("%d",c);问题
来源:互联网 发布:农村淘宝怎么解绑 编辑:程序博客网 时间:2024/06/05 14:37
char c=128;printf("%d",c);问题
同属计算机储存,补码问题的延生~~
二、解密
答案输出是-128,为什么呢?
char型变量c中存储的是128的补码:10000000。上一篇文章已经说到,对于计算机来说,存储的都是数据的补码。
赋值给char型,debug模式下反汇编如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
使eax寄存器扩展成为 0xFFFFFF80,扩展在这一步~~
而且
- 1
- 2
- 3
- 4
进一步将寄存器存到内存中
对于计算机来说
char c = -128;
signed char c = 0x80;
以上两句是一回事。
如下几种情况:
char c=128;
printf(“%u\n”, c); //按%u输出,结果为 4294967168
printf(“%d\n”, c); //按%d输出,结果为 -128
printf(“%c\n”, c);//按%c输出,结果为空
原因:
c 是一个字符的长度,但当它被传送到printf函数的参数时,是将c按照int来扩张传给printf的。
128 即为二进制的 1000 0000,16进制的0x80, 当它扩展为 int时,由于int可能是4个字节,所以会进行符号扩展。由于 128最高为是1,为负数,扩展为int的-128为11111111 111111 111111 1000000,即0xffffff80
而0xffffff80按照有符号的int来说,就是-128。
而按照无符号的int来说,就是十进制的 4294967168。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
三、数据扩展
1、短数据类型扩展为长数据类型
(1)要扩展的短数据类型为有符号数
进行符号扩展,即短数据类型的符号位填充到长数据类型的高字节位(即比短数据类型多出的那一部分),保证扩展后的数值大小不变
例1:char x=10001001b; short y=x; 则y的值应为11111111 10001001b;
例2:char x=00001001b; short y=x; 则y的值应为00000000 00001001b;
(2)要扩展的短数据类型为无符号数*
进行零扩展,即用零来填充长数据类型的高字节位
例1:unsigned char x=10001001b; short y=x; 则y的值应为00000000 10001001b;
例2:unsigned char x=00001001b; short y=x; 则y的值应为00000000 00001001b;
2、长数据类型缩减为短数据类型
如果长数据类型的高字节全为1或全为0,则会直接截取低字节赋给短数据类型;如果长数据类型的高字节不全为1或不全为0,则转换就会发生错误。(这个还不确定)
事实上下面代码会输出 ‘0’
- 1
- 2
- 3
3、同一长度的数据类型中有符号数与无符号数的相互转化
直接将内存中的数据赋给要转化的类型,数值大小则会发生变化,因为以不同类型解释同一段内存数据会得到不同的数值。比如一个字节中存放的数据是11111111,以unsigned char来解释就是255,以char来解释就是-1.
根据以上规则,可以得出当char c 是一个有符号的字符变量,其内存中存储的是1000 0000,但当它被传送到printf函数的参数时,是将c按照int来进行宽度扩展后再传给printf的。
128的补码是 1000 0000,16进制是0x80, 当它扩展为 int时,由于int是4个字节,需要进行短数据类型扩展到长数据类型。由于内存中存放的是10000000,以char型来解释的话第一位为符号位,表示负数,进行符号扩展为int后,int型变量中存储的数据是:11111111 11111111 11111111 1000000,即0xffffff80。以int来解释的这四个字节的数据,其值就是-128,以unsigned int来解释的话,就是232−1−127=4294967168。
四、为什么会在前面补1?
开始的char c 是 1000 0000b,后来变成 11111111 11111111 11111111 1000000b,为什么要在前面补1呢?
或者举例,char c 是 1000 0001b,后来变成 11111111 11111111 11111111 1000001b
因为要使 -2^31+2^30+…+2^7+0+1 = -2^7+0+1
也就是 -2^31+2^30+…+2^8 = -2*2^7
也就是 -2^31+2^30+…+2^8+2*2^7 = 0
-2^31+2^30+…+2^8+2*2^7
= -2^31+(2^31-1)-(2^6+2^5+…+1)+2^7 = 0
—END—
- (转) char c=128;printf("%d",c);问题
- char c=128;printf("%d",c);问题
- 用C的数据类型宽度扩展来解释char c=128;printf("%d",c);问题
- char c=128; printf("c=%d\n",c); 结果为什么是-128
- char c=128;
- printf("%d%d%d%d\n", a,b,c);
- C printf() 详解——printf('%08x',number); 程序员面试宝典中的一个错误 char * b=(char *)&a
- C printf() 详解——printf('%08x',number); 程序员面试宝典中的一个错误 char * b=(char *)&a
- C printf() 详解——printf('%08x',number); 程序员面试宝典中的一个错误 char * b=(char *)&a
- C printf() 详解——printf('%08x',number); 程序员面试宝典中的一个错误 char * b=(char *)&a
- C printf() 详解——printf('%08x',number); 程序员面试宝典中的一个错误 char * b=(char *)&a
- C中Char类型 ----%d %c
- C语言中的可变参数函数 三个点“…”printf( const char* format, ...) 博客分类: C语言 ANSI C CC++C#D语言编程 第一篇
- printf("a=%d\nb=%d\nc=%d\n",a,b,c);
- C语言基础之:32位机中用printf输出signed char的问题
- C语言初探 之 printf压栈顺序(printf("%d %d %d %d %d %d\n",a++, ++a, a++, ++a, a++, ++a ))
- C printf无法输出问题
- string 转 char* (C#)
- 关于ubuntu16.04的几个免密操作
- hdu 1010 Tempter of the Bone(dfs+枝剪)
- 实验4 无向图的深度优先搜索
- C++ 指针数组 & 指向数组的指针
- Linux下安装Zookeeper
- (转) char c=128;printf("%d",c);问题
- Freso的图片缓存
- Android动画解析(一)-----逐帧动画和补间动画
- 文本批量处理方法大全
- Hibernate Validation使用示例及讲解
- vs2015配置Opencv3.3.1
- 快讯丨北京出台中国首个自动驾驶法规,北京第一批测试道路将推出
- Spring Boot
- Ubuntu14.04下的ORB_SLAM2安装