有符号数与无符号数的程序设计原则:

  • 当需要表示数值时,使用有符号数(如 int)。
  • 当需要表示位集合时,使用无符号数(如unsigned int)。

有符号数和无符号数混合运算有可能会带来灾难性的后果。例如:

vector<int> v;
for(int i=0;i<v.size();++i)cout<<v[i]<<'\n';

易实现版本:

unsigned char max=160;    //非常大
for(signed char i=0;i<max;i++)cout<<int(i)<<'\n';

循环变量i可能会溢出,即,v.size()有可能比最大的有符号数int值还要大。当i的值增大到有符号数int所能代表的最大正数(如,int为16位宽度,此值为215-1)时,下一次增1运算不会得到更大的整型值,而会得到一个负数。因此循环永远也不会停止!每当我们到达最大整数时,接着就会从最小负int值重新开始。因此如果v.size()的值为32*1024或者更大,循环变量为16位int型的话,这个循环就是一个(可能非常严重的)bug。如果循环变量是32位int型的话,当v.size()的值大于等于2*1024*1024*1024时就会出现同样的问题。

为了避免这个问题,我们可以使用vector提供的size_tupe或者是迭代器:

for(vector<int>::size_type i=0;i<v.size();++i)cout<<v[i]<<'\n';
for(vector<int>::iterator p=v.begin();p!=v.end();++p)cout<<*p<<'\n';
for(int x:v)cout<<x<<'\n';

  size_tupe确保是无符号的,因此,第一种形式(使用无符号数)与int型循环变量的版本相比,多出一个二进制位来表示循环变量的数值(而不是符号)。这个改进很重要,但终究只是多出一位来表示循环的范围(循环次数多出一倍)。而使用迭代器的版本就不存在这个限制。

大致来说,我们有两个原因将无符号数当作整数来使用,而不是简单作为一组二进制位(即,不使用+、-、*和/);

  • 有更多的二进制位来表示数值,从而获得更高的精度。
  • 用来表示逻辑属性,其值不能是负数。

前者就是我们刚刚看到的,使用无符号循环变量带来的效果。

混合使用有符号数和无符号数的问题在于,在c++中,两者转换的方式很奇怪,而且难以记忆。例如:

unsigned int ui=-1;
int si=ui;
int si2=ui+2;
unsigned ui2=ui+2;

  输出结果:

4294967295
-1
1
1

不推荐为获得一个额外的二进制位的精度而是要无符号数。

标准库容器的下标都是无符号数。

c++程序设计原理与实践(进阶篇)

有符号数和无符号数------c++程序设计原理与实践(进阶篇)的更多相关文章

  1. C语言基础(5)-有符号数、无符号数、printf、大小端对齐

    1.有符号数和无符号数 有符号数就是最高位为符号位,0代表正数,1代表负数 无符号数最高位不是符号位,而就是数的一部分而已. 1011 1111 0000 1111 1111 0000 1011 10 ...

  2. 深入理解计算机系统(2.5)------C语言中的有符号数和无符号数以及扩展和截断数字

    上一篇博客我们讲解了计算机中整数的表示,包括无符号编码和补码编码,以及它们之间的互相转换,个人觉得那是非常重要的知识要点.这篇博客我们将介绍C语言中的有符号数和无符号数以及扩展和截断数字. 1.C语言 ...

  3. C语言中 有符号数、无符号数、整数溢出 (转)

    #include<stdio.h> void main() { int l=-1; unsigned int c=135; printf("%u\n",l+c); } ...

  4. java 理解有符号数和无符号数

    转至:http://jinguo.iteye.com/blog/212049 理解有符号数和无符号数负数在计算机中如何表示呢? 这一点,你可能听过两种不同的回答. 一种是教科书,它会告诉你:计算机用“ ...

  5. c++ 常量/有符号数和无符号数

    一.宏定义 #define 和常量 const 1. const关键字 const是constant的简写,只要一个变量前面用const来修饰,就意味着该变量里的数据可以被访问,不能被修改.也就是说c ...

  6. 关于有符号数和无符号数的转换 - C/C++

    转载自:http://www.94cto.com/index/Article/content/id/59973.html 1.引例: 今天在做了一道关于有符号数和无符号数相互转换及其左移/右移的问题, ...

  7. Mysql中有符号数和无符号数的区别

    1原文地址:https://blog.csdn.net/s78365126/article/details/85048882 2可以手写sql验证一下 3mysql无符号和有符号的区别无符号unsig ...

  8. Qt之C语言有符号数与无符号数运算

    以32位的stm32f4为例: 1.  uint32_t t_int_k = 239773, t_int_km1 = 4294859707; 则t_int_k - t_int_km1 > 0; ...

  9. C语言迷题:有符号数与无符号数的问题(转)

    https://my.oschina.net/kelvinfang/blog/134725

随机推荐

  1. ARM-Linux内核移植之(一)——内核启动流程分析

    内核版本:2.6.22  为什么要采用这样一个较低的版本进行移植了,因为韦东山大牛说了,低版本的才能学到东西,越是高版本需要移植时做的工作量越少,学的东西越少. 内核启动分为三个阶段,第一是运行hea ...

  2. TIMEQUEST学习之黑金动力(三)

    不知不觉,学到的第四章.但是对于TQ的内部模型和外部模型的完整分析还是没有很好的理解.接着学习......... 我们也了解静态时序分析的第一步骤,亦即时钟方面的约束.此外,也稍微对 Report T ...

  3. 生成signature

    签名规则说明 1. 将参数先按键值排序(只做一级排序),进行key和value的拼接 2. 拼接完后,在最后面再拼接上分配的 appSecret 然后用sha1对拼接串加密 签名示例 假如传入参数: ...

  4. DRF之权限认证频率组件

    概要 retrieve方法源码剖析 认证组件的使用方式及源码剖析 权限组件的使用方式及源码剖析 频率组件的使用方式及源码剖析 知识点复习回顾 Python逻辑运算 知识点复习回顾一:Python逻辑运 ...

  5. 17-EasyNetQ:非泛型的发布&订阅扩展方法

    自从EasyNetQ第一个版本开始,它就可以发布/订阅特定类型的消息. bus.Subscribe<MyMessage>("subscriptionId", x =&g ...

  6. GDB常用命令简介

    1.启动调试程序 gdb 调试对象,例如gdb app 2.运行程序 run 或这简写为r 3.设置断点 有几种不同的方式 1)break line 2) break file:line 3) bre ...

  7. 201671010140. 2016-2017-2 《Java程序设计》java学习第三周

    java学习第三周       不知不觉,学习java已经是第三周了,不同于初见时的无措,慌张,在接触一段时日后,渐渐熟悉了一些,了解到了它的便利之处,也体会到了它的一些难点,本周主攻第四章,< ...

  8. 查看window下默认ORACLE_SID

    Configuration and Migration Tools-----Configuration and Migration Tools-----Administration Assistant ...

  9. SPQuery DateTime 类型查询

    使用SPQuery查询时间,默认查询会忽略 时分秒,只检查日期,如果要检查时间,则必须添加 IncludeTimeValue='TRUE' 格式如下: <Where>    <Gt& ...

  10. SpringMVC总结四:拦截器简单介绍

    首先要说一下HandlerExecutionChain: HandlerExecutionChain是一个执行链,当用户的请求到达DispatcherServlet的时候,DispatcherServ ...