有符号数与无符号数运算坑点

作者 Lei da 日期 2019-09-17
有符号数与无符号数运算坑点

本篇博客来源于我在leetcode上遇到过的一个bug,当我按照如下所示循环条件时

1
2
//vector<int> nums;
for(k=0;k<nums.size()-2;k++)

输入的nums为空数组的情况下,按照常理nums.size()-2相当于0-2=-2,但是事违人愿,出现了如下报错

1
Line 923: Char 34: runtime error: reference binding to null pointer of type 'value_type' (stl_vector.h)

原因是:vector::size返回unsigned integral类型,即无符号整形,又由于无符号数与有符号数运算时,会默认将有符号数当做无符号数来处理,下面举例说明

  • -2在16位机内存中存储形式是1111111111111110,即有符号数-2的补码形式,若该补码当成无符号数来处理,则表示十进制的65534,一个很大的数,32位或64位也以此类推,总之0-2的结果也就不等于-2了。如下代码可以输出这个很大的数
    1
    2
    3
    4
    5
    6
    7
    8
    #include<iostream>
    #include<vector>
    using namespace std;
    int main(){
    vector<int> nums;
    cout<<nums.size()-1<<endl;
    return 0;
    }

输出结果为18446744073709551615,该数值取决于电脑无符号整数的位数。

当然,把-2去掉之后,便不会报错,因为直接将nums.size()当成0来处理

无符号数与有符号数的区别

  • 无符号类型能保存2倍于有符号类型的数据,因为腾出来一个符号位

感觉这是c++编程中一大坑点,需要多多注意