用C的数据类型宽度扩展来解释char c=128;printf("%d",c);问题
来源:互联网 发布:服务器地址和端口号 编辑:程序博客网 时间:2024/05/22 00:15
代码编译运行环境:VC++ 2012+Debug+Win32
1.问题描述
在编程或者面试过程中,会遇到如下问题:
char c=128;printf("%d",c); //输出-128
为什么一个正整数128以整型int输出却变成了一个负数?
2.问题分析
在理解上面的问题时,我们需要先了解如下问题。
(1)char型所能表示的数据范围是-128~127。当把128赋值给char型变量时,那么内存中实际存储的是什么呢?
将以上面的代码在Debug模式下转到反汇编,汇编代码如下:
char c=128;00B16AB0 mov byte ptr [c],80h printf("%d",c);00B16AB4 movsx eax,byte ptr [c] 00B16AB8 mov esi,esp 00B16ABA push eax 00B16ABB push 0B1EC90h 00B16AC0 call dword ptr ds:[0B2240Ch] 00B16AC6 add esp,8 00B16AC9 cmp esi,esp 00B16ACB call __RTC_CheckEsp (0B113CFh)
从汇编代码可以看出,char型变量c中存储的是128的补码:10000000。注意对于计算机来说,存储的都是数据的补码。反码、源码都对于编程人员理解数据的变换过程提出来的。
(2)当char转换为int时,内存中的数据如何从1个字节扩展到4个字节?
这个是本文的核心问题,理解了这个问题,就可以很好地解释为什么char c=128;printf(“%d”,c); 输出的是-128。
当char型扩展到int型时,C标准中有有如下规则:
一、短数据类型扩展为长数据类型
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;
二、长数据类型缩减为短数据类型
如果长数据类型的高字节全为1或全为0,则会直接截取低字节赋给短数据类型;如果长数据类型的高字节不全为1或不全为0,则转换就会发生错误。
三、同一长度的数据类型中有符号数与无符号数的相互转化
直接将内存中的数据赋给要转化的类型,数值大小则会发生变化,因为以不同类型解释同一段内存数据会得到不同的数值。比如一个字节中存放的数据是11111111,以unsigned char来解释就是255,以char来解释就是-128.
根据以上规则,可以得出当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来解释的话,就是
3.代码验证
根据以上分析,我们可以清楚准确的推断出下面的输出。
unsigned char uc=128; char c=128; printf("%d\n",uc); //128 printf("%d\n",c); //-128 printf("%u\n",uc); //128 printf("%u\n",c); //4294967168 printf("%08x\n",uc); //0x00000080 printf("%x\n",c); //0xffffff80
应该不会为这些输出结果而感到惊讶和困惑了吧!有问题欢迎讨论。
参考文献
[1]类型扩展.http://blog.sina.com.cn/s/blog_6adcb3530101cmsd.html
[2]char c=128;.http://blog.csdn.net/jinbi/article/details/6779713
- 用C的数据类型宽度扩展来解释char c=128;printf("%d",c);问题
- char c=128;printf("%d",c);问题
- (转) char c=128;printf("%d",c);问题
- char c=128; printf("c=%d\n",c); 结果为什么是-128
- C和指针,char扩展int 以及EOF的问题!
- 用C来扩展我们的PHP
- c语言数据类型及printf
- C/C++ 数据类型扩展
- c/c++变量的数据类型之char
- C语言基础之:32位机中用printf输出signed char的问题
- c语言的数据类型 范围 解释
- char c=128;
- C语言:数据类型,char,int
- C中Char类型 ----%d %c
- C语言函数printf("%*.*s",2,4,"abcdefg");的解释
- 关于c语言的printf()问题
- c语言的printf一个小问题
- c中printf的输出问题
- 单链表的头结点和头指针
- iOS 有关界面设计规范的一些总结
- struts2常用result类型详解
- java、synchronized、wait()、notify()、notifyAll()
- 关于Python脚本开头两行的:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用 – 指定文件编码类型
- 用C的数据类型宽度扩展来解释char c=128;printf("%d",c);问题
- zend studio 打开在同目录下的项目文件
- 告警exc_bad_access copy assign 重写setter方法时
- Android 事件分发机制
- numpy 常用api(一)
- 查看并释放内存
- Eclipse配置Tomcat服务器
- WEB网站防御XSS攻击思路和XSS实践
- 《图像局部不变性特征与描述》阅读笔记(2)-- 图像尺度空间