C++Primer快速浏览笔记-类型转换
bool b = 42; // _b is true_
int i = b; // _i has value 1_
i = 3.14; // _i has value 3_
double pi = i; // _pi has value 3.0_
unsigned char c = -1; // _assuming 8-bit chars_, _c has value 255_
signed char c2 = 256; // _assuming 8-bit chars_, _the value of c2 is__undefined_
类型所能表示的值的范围决定了转换的过程:
- 当我们把一个非布尔类型的算术值赋给布尔类型时,初始值为0则结果为false,
否则结果为true. - 当我们把一个布尔值赋给非布尔类型时,初始值为false则结果为O,初始值为
true则结果为1. - 当我们把一个浮点数赋给整数类型时,进行了近似处理。结果值将仅保留浮点数中
小数点之前的部分。 - 当我们把一个整数值赋给浮点类型时,小数部分记为0。如果该整数所占的空间超
过了浮点类型的容量,精度可能有损失。 - 当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表
示数值总数取模后的余数。例如,8比特大小的unsigned char可以表示0至255区间内的值,如果我们赋了一个区间以外的值,则实际的结果是该值对256取模后所得的余数(负数加上无符号数的模,这里模=x2)。因此,把-1赋给8比特大小的unsigned char所得的结果是255.
在计算机系统中,数值一律用补码来表示和存储,正整数的补码是其二进制表示,与原码相同;负整数的补码,将其对应正数二进制表示所有位取反(包括符号位,0变1,1变0)后加1。-1的原码10000001 转换成补码:11111111,因此将其看做无符号的正整数,其值为255.
- 当我们赋给带符号类型一个超出它表示范围的值时,结果是未定义的(undefined)。
此时工程程序可能继续工作、可能崩溃,也可能生成垃圾数据。
资料补充:
算数运算中自动类型转换
基本原则:值域较窄的类型向值域较宽的类型转换
同时要注意以下3点:
- 表达式中的有符号和无符号字符(针对字符)以及短整型一律被转换为整型, 如果int类型能表示原来类型的值,则转换成int类型;否则转换成unsigned类型。
- 当一个运算量为long类型, 另一个为unsigned类型时,如果long能表示unsigned的全部值, 则将unsigned转换成long; 否则将两个运算量都转换为unsigned long。
- 当两个运算量中值域较宽的类型是float类型时, 不再将float和另一运算量转换成double类型
这里需要注意有符号数与无符号数之间运算问题
当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此,从这个意义上讲,无符号数的运算优先级要高于有符号数。
下面的实验来自网友,本人在VS2013平台进行了验证:
首先进行一个实验,分别定义一个signed int型数据和unsigned int型数据,然后进行大小比较:
unsigned int a=20;
signed int b=-130;
a>b?还是b>a?实验证明b>a,也就是说-130>20,为什么会出现这样的结果呢?
这是因为在C语言操作中,如果遇到无符号数与有符号数之间的操作,编译器会自动转化为无符号数来进行处理,因此a=20,b=4294967166,这样比较下去当然b>a了。
再举一个例子:
unsigned int a=20;
signed int b=-130;
std::cout<<a+b<<std::endl;
结果输出为4294967186,同样的道理,在运算之前,a=20,b被转化为4294967166,所以a+b=4294967186
减法和乘法的运算结果类似。
如果作为signed int型数据的b=-130,b与立即数之间操作时不影响b的类型,运算结果仍然为signed int型:signed int b=-130;
std::cout<<b+30<<std::endl;
输出为-100。
而对于浮点数来说,浮点数(float,double)实际上都是有符号数,unsigned 和signed前缀不能加在float和double之上,当然就不存在有符号数根无符号数之间转化的问题了。这样一个题,据说是微软面试题:
unsigned int i=3;
cout<<i -1;
问结果是多少。
第一反应:-3。不过结果似乎不是这样的,写了个程序,运行了一下,发现是:4294967293。
在32位机上,int型和unsigned int型都是32位的(4个字节),在表达式i-1中,i是unsigned int型,-1是int型(常量整数的类型同enum),按第5条可以知道-1必须转换为unsigned int型,即0xffffffff,十进制的4294967295,然后再与i相乘,即4294967295*3,如果不考虑溢出的话,结果是12884901885,十六进制0x2FFFFFFFD,由于unsigned int只能表示32位,忽略高四位,因此结果是0xfffffffd,即4294967293。
再比如《C++Primer中文版·第五版》中有个说明:
当从无符号数中减去一个值时,不管这个值是不是无符号数,我们必须确保结果不能是一个负值。书中给出的例子是:
unsigned u1 = 42, u2 = 10;
std::cout << u1 - u2 << std::endl; //正确,输出32
std::cout << u2 - u1 << std::endl; //正确;不过,结果是取模后的值
结果是:
232−32=4294967264
C++Primer快速浏览笔记-类型转换的更多相关文章
- C++Primer快速浏览笔记-复合类型
C++Primer2.3节介绍了两种复合类型:引用和指针 1.引用 引用并非对象,它只是为一个已经存在的对象所起的别名. 一旦初始化完成,引用将和它的初始值对象一直绑定在一起,不能重新绑定到另一个对象 ...
- Angular快速学习笔记(2) -- 架构
0. angular 与angular js angular 1.0 google改名为Angular js 新版本的,2.0以上的,继续叫angular,但是除了名字还叫angular,已经是一个全 ...
- Knockout.js快速学习笔记
原创纯手写快速学习笔记(对官方文档的二手理解),更推荐有时间的话读官方文档 框架简介(Knockout版本:3.4.1 ) Knockout(以下简称KO)是一个MVVM(Model-View-Vie ...
- Git 命令快速浏览
Git 命令快速浏览 创建 Git 可管理的仓库 git init 查看当前仓库的状态 git status 添加到仓库,实际上是添加到暂存区 git add [-A | --all] git add ...
- Angular 快速学习笔记(1) -- 官方示例要点
创建组件 ng generate component heroes {{ hero.name }} {{}}语法绑定数据 管道pipe 格式化数据 <h2>{{ hero.name | u ...
- C#快速入门笔记(1)——基础语法
C#快速入门笔记(1)——基础语法 总体框架:
- git Octotree:提供项目目录,方便用户在线快速浏览项目结构【转载】
很好奇的是,GitHub 作为代码托管平台,竟然没有提供项目目录,方便用户在线快速浏览项目结构.所以,在线分析项目源码就会变得很繁琐,必须一层一层点击,然后再一次一次地向上返回.要知道,本来 GitH ...
- keras搭建神经网络快速入门笔记
之前学习了tensorflow2.0的小伙伴可能会遇到一些问题,就是在读论文中的代码和一些实战项目往往使用keras+tensorflow1.0搭建, 所以本次和大家一起分享keras如何搭建神经网络 ...
- Spring Boot 快速入门笔记
Spirng boot笔记 简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发 ...
随机推荐
- saltstack/salt的state.sls的使用
SLS(代表SaLt State文件)是Salt State系统的核心.SLS描述了系统的目标状态,由格式简单的数据构成.这经常被称作配置管理 首先,在master上面定义salt的主目录,默认是在/ ...
- php 使用redis锁限制并发访问类
1.并发访问限制问题 对于一些需要限制同一个用户并发访问的场景,如果用户并发请求多次,而服务器处理没有加锁限制,用户则可以多次请求成功. 例如换领优惠券,如果用户同一时间并发提交换领码,在没有加锁限制 ...
- SQL Server 2012 自动增长列,值跳跃问题
介绍 从 SQL Server 2012 版本开始, 当SQL Server 实例重启之后,表格的自动增长列的值会发生跳跃,而具体的跳跃值的大小是根据增长列的数据类型而定的.如果数据类型是 整型(in ...
- C#的is和as操作符来进行强制类型转换&&值类型的拆箱、装箱
if(o is Employee) { Employee e=(Employee)o; //在if语句剩余的部分中使用e; } Employee e=o as Employee; if(e!=null ...
- HDFS原理介绍
HDFS(Hadoop Distributed File System )Hadoop分布式文件系统.是根据google发表的论文翻版的.论文为GFS(Google File System)Googl ...
- Linux-PAM认证模块
Linux-PAM认证模块 用户访问服务器的时候,服务器的某一个服务程序把用户的谁请求发送到PAM模块进行认证.对于不同的服务器应用程序所对应的PAM模块也是不同的.如果想查看某个程序是否支持 ...
- Mac下DIY文件浏览器
2015-07-14 15:07:53 Mac下的finder不能浏览Linux文件目录, 一些优秀的资源管理器是收费的..... 于是想到了既然Mac的本质是类Unix, 而在windows下查看L ...
- Mybatis中的in查询和foreach标签
Mybatis中的foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合. foreach元素的属性主要有 item,index,collection,open,separato ...
- FFmpeg-20160415-snapshot-bin
ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 S 下一帧 [ -2秒 ] +2秒 ; -1秒 ' +1秒 下一个帧 -> -5秒 F ...
- vector在C++中的基本用法
在写BlackJackGame的时候,考虑到要用到容器,所以就对容器的相关知识强化了一下: 因为我想的是有card类,最后要实现发牌,洗牌等等一系列的操作的时候,使用指向card类的对象的指针,将ca ...