c语言int型和char型的自动类型转换
char a = -; //机器码为0xff
unsigned char b = ; //机器码0xfe
if (a <= b){
printf("a <= b\n");
}
else{
printf("a > b\n");
}
上述代码输出结果: a > b
赋值用机器码写入内存
虽然我们以十进制为两个变量赋值,但是变量值在内存中是以二进制机器码的形式存在。如果十进制数是负数,它就以补码的形式存放在内存中。比如"a = -1",a的真值以二进制表示为"1000 0001",高位是符号位,其余位表示绝对值;它的反码是"1111 1110",补码是"1111 1111",所以内存中某个存放变量a的字节的数是0xff。而正数的补码就是原码,不需要转换,所以内存中某个存放变量b的字节的数是0xfe。(有关机器码和补码知识请戳https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html)
运行时不同类型变量的比较存在类型转换
当正在比较的两个变量类型不同时,会发生类型转换。有符号char型和无符号char型比较时,有符号临时转换成无符号(机器码不变,只是编译器处理这个变量的方法改变)。a临时转成无符号后机器码仍然时0xff,但是编译器把它作为无符号处理——即没有符号位,取值范围时[0, 255],所以临时变量值是255,自然比b大。
那么字符型和整型变量发生类型转换时需要注意哪些呢?
一字节“字符型” -> (转换为)四字节“整型”,字节数较少的字符型变量会向高位扩展,具体补‘0‘还是补’1‘,根据字符型变量自身类型和高位符号两者决定。下面看四个例子。
例一:
char a = 0xff;
unsigned b = 0xffffffff;
if (a == b){
printf("equal.\n");
}
else{
printf("not equal\n");
}
上述代码输出结果:equal.即补‘1’.
例二:
char a = 0xff;
int b = 0xffffffff;
if (a == b){
printf("equal.\n");
}
else{
printf("not equal\n");
}
上述代码输出结果:equal.即补‘1’.
例二和例一只有变量b的类型不同,由此看出向高地址补位的动作不受要转向的那个类型所影响。
例三:
unsigned char a = 0xff;
unsigned b = 0xffffffff;
if (a == b){
printf("equal.\n");
}
else{
printf("not equal.\n");
}
上述代码输出结果:not equal.。即补‘0’。
例三和例一只有变量a的类型不同,由此看出向高地址补位的动作受变量本身类型所影响。
例四:
char a = 0x7f;
unsigned b = 0xffffffff;
if (a == b){
printf("equal.\n");
}
else{
printf("not equal.\n");
}
上述代码输出结果:not equal.。即补‘0’。
例四和例一只有变量a的值不一样,例四中变量a的高位是0,因此向高位补‘0’,由此有符号型向高地址补位的动作受变量符号位的值所影响。
而四字节“整型” -> (转换为) 一字节“字符型” ,就是单纯地把低位一字节的内容赋值给字符型变量。
char型数据溢出情况
char a = ;
a *= ;
if (a >= ){
printf("a >= 0");
}
else{
prinf("a < 0");
}
上述代码输出结果:a < 0。
虽然以十进制数‘128’赋值给变量,但实际存入内存中的机器码是0x80,编译时以有符号字符型处理这个字节。这个值符号位是‘1’,表示负数,对其余位求补码——结果换算成十进制,并加负号,就是这个机器码的真值,即‘-128’。所以小于‘0’。例子中虽然0x80在一个字节所能表示的数值范围内,但是超过char型所能表示的正数范围,这是char型数据溢出的一个例子。
unsigned char型数据溢出情况
unsigned char a = ;
do {
a *= 2;
printf("%x", a);
} while (a <= 256)
上述代码会不停循环。
当变量a从0x80乘2后,机器码是0x100。由于‘a’只能存储一个字节的数据,所以取结果的低位一字节,即0x00,这样从0 -> 255 -> 0循环下去。这是unsigned char型数据溢出的一个例子。
另外举一个误把unsigned char型当作负数处理地例子,虽然不可能发生,但有必要了解一下其中原因:
unsigned char a = 0x0a;
do {
--a;
printf("%x", a);
} while (a >= )
上述代码会不停循环。
当变量a从0x0自减后,机器码是0xff。因为计算机运算中把减法当作两数的补码相加来做,(0 - 1)表达式在计算机运算中解释为(0x0 + 0xff),所以结果是0xff。
最后举一个char型最小负数取相反数溢出的例子:
char a = -;
char b = -a;
if (b > ){
printf("b > 0\n");
}
else{
printf("b <= 0\n");
}
上述代码输出结果:b <= 0。
|a|的真值用二进制表示"1000 0000",用补码表示同样是"1000 0000",最后由于是负数,高位置为‘1’,结果是"1000 0000",这个0x80的char型机器码的特殊之处在于符号位同时表示数值。‘b’被编译器处理为-128,所以输出"b <= 0"。
c语言int型和char型的自动类型转换的更多相关文章
- 所学新知——int、char型转string 类型等
1. 利用stringstream类 定义头文件#include<sstream> 通过 int a; char b; sstream ss,ss1; ss<<a; ss1&l ...
- c语言的自动类型转换
转自c语言的自动类型转换 自动转换遵循以下规则: 1) 若参与运算量的类型不同,则先转换成同一类型,然后进行运算. 2) 转换按数据长度增加的方向进行,以保证精度不降低.如 ...
- C语言自动类型转换
自动转换遵循以下规则: 1) 若参与运算量的类型不同,则先转换成同一类型,然后进行运算. 2) 转换按数据长度增加的方向进行,以保证精度不降低.(eg:int型和long型运算时,先把int量转成lo ...
- c语言的自动类型转换(转)
一.自动转换遵循以下规则: 若参与运算量的类型不同,则先转换成同一类型,然后进行运算. 转换按数据长度增加的方向进行,以保证精度不降低.如int型和long型运算时,先把int量转成long型后再进行 ...
- 「C语言」数据类型及混合运算与类型转换
深入学习C语言时,有必要先了解一下数据类型的概念,以及它们之间的混合运算与类型转换. 本篇文章便是根据<C语言程序设计教程>和在线翻阅资料后整理而出.(练习题将逐步更新) 目录: ...
- C++程序设计方法3:禁止自动类型转换
禁止自动类型转换 explicit #include <iostream> using namespace std; class Src;//前置类型声明,因为在Dst中要用到Src的类 ...
- C语言中字符型和字符串型的区别?
C语言中只有字符型类型,没有字符串型类型.字符类型用一个带符号的8位二进制编码表示,其性质与int相同,只是只有一个字节.表示字符的ASCII编码使用其中的0~127,所以要明白字符类型(char)其 ...
- java如何把char型数据转换成int型数据(转)
一字符串,String=“2324234535”:把第i个数取出来时是char型的:char temp=String.charAt(i)如何把char型转换成int型?我需要求个尾数之和,如:123的 ...
- Java中byte、short、char、int、long运算时自动类型转化问题
-------------------------------------------------------------------------------------------------- ★ ...
随机推荐
- 关掉那些windows上因权限无法关闭的服务
ProcessExplorer 下载地址 :https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer 以管理员身 ...
- JWT是什么鬼
什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点 ...
- 如何在本地编译Fabric Code
之前的博客都是拿官方现成的Docker镜像来用,但是并没有自己动手做镜像,也没有说到如何去开发和测试Fabric的代码.这一篇博客就从入门的角度讲解如何编译.测试和开发Fabric. 一.环境准备 要 ...
- 在混合开发框架模式中,简化客户端对Web API的频繁调用
在混合开发框架模式中,有时候我们在处理树形节点的时候,需要很多关联的处理,可能需要结合用户配置信息,属性字典,以及表的字段分类等信息来展示一个结构树,那么在处理的时候就可能会频繁的对这些接口API进行 ...
- Windows下切分文件(GnuWin32)
windows下碰到查看大日志文件还真麻烦,今天找了个工具来做这个:安装GnuWin32,然后用里面的split命令分割日志文件 ps:发现intellij idea还挺好,超过2g的日志文件也能进行 ...
- 面试7家,收到5个offer,我的Python就业经验总结 !
*---------------------------------------人生处处有惊喜,背后却是无尽的辛酸苦辣. Python找工作并不容易,老表面试了很多企业,总结了些宝贵经验! 一周转 ...
- HSSFWorkbook 导出excel java
public String exportExcelList(){ //创建webbook,对应一个excel文件 HSSFWorkbook wb = new HSSFWorkbook(); //在we ...
- 偶发异常BUG,如何高效精准分析排查定位?
偶发异常BUG,如何高效精准分析排查定位? 作为测试,经常会收到领导.同事.用户反馈过来各种各样BUG,令人措手不及 首选需要判断确认是不是BUG,不要急于给予回复,需有充分的条件给予说明回复 很多测 ...
- yolov3和darknet opencv版编译安装及基本测试
版权声明:本文为博主原创文章,欢迎转载,并请注明出处.联系方式:460356155@qq.com 一.准备工作: 安装pkg-config:sudo apt-get install pkg-confi ...
- PHP 高级工程面试题汇总
PHP高级工程面试题汇总(2018.05) 1.给你四个坐标点,判断它们能不能组成一个矩形,如判断([0,0],[0,1],[1,1],[1,0])能组成一个矩形. 勾股定理,矩形是对角线相等的四边形 ...