关于Vector的size_type的问题的探讨 C++

我们都知道C++中的String和Vector的size_type实际上定义为有编译器决定的unsigned型,但是对于unsigned型或许我们需要深入理解一下,通过下面这段程序引入本文的主题:

程序1:

#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    vector<int> vect;
    vect.push_back(1);
    vect.push_back(2);
    vect.push_back(3);
    vect.push_back(4);

 for(vector<int>::size_type i=vect.size()-1;i>=0;--i)
 {
  cout<<i<<":  "<<vect.size()<<": "<<vect[i]<<endl;
 }

 return 0;
}

运行上面程序将会出现如下vector超出索引的异常:

于是我参考程序报错的C++标准源码,

if (size() <= _Pos)
   {
   _DEBUG_ERROR("vector subscript out of range");
   _SCL_SECURE_OUT_OF_RANGE;
   }

这是报错的错误,很明显就是一个超出索引的错误,一直没想清楚原因,后来记得C++ Primer中讲过size_type实际上定义为有编译器决定的unsigned型,于是定义为有关unsigned的问题。

程序2:

于是如若将程序做如下修改,则程序正确:

#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    vector<int> vect;
    vect.push_back(1);
    vect.push_back(2);
    vect.push_back(3);
    vect.push_back(4);

 //修改循环判断条件

for(vector<int>::size_type i=vect.size()-1;i!=-1;--i)
 {
  cout<<i<<":  "<<vect.size()<<": "<<vect[i]<<endl;
 }

 return 0;
}

首先解释为什么程序1是错误的:

那为什么改变这两个判定条件会导致程序运行不同呢,原因就在于unsigned型在循环中变到0的时候,再次执行--i时,实际上它是按照0的补码减1的操作,这样实际上内存存储的这个等效于int型的-1的内存存储,为10000000    00000000     00000000   00000001(假设编译器字长为32位机),则实际上的unsigned值为4294967295。这就解释了为什么当循环判断条件为i>=0是会超出索引,这时候i不是-1,而是4294967295,循环判断条件成立,但是输出是i已经超出索引。

然后解释为什么程序2是正确的:

那为什么i!=-1作为循环判断条件是正确的呢?因为当利用关系运算符!=判断一个unsigned和int型是,它实际并不是比较两个值,而是比较两个变量在内存中的存储是否相同,因为unsigned的4294967295和int的-1都是存储为10000000    00000000     00000000   00000001(假设编译器字长为32位机),为了验证这个观点,利用程序3来证明

程序3:

#include "stdafx.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
 unsigned int i=-1;
 int j=-1;
 if(i==j) 
  cout<<"i: "<<i<<"\n"<<"j: "<<j<<endl;
 else     
  cout<<"Your opinion is error!!"<<endl;

 return 0;
}

运行:

由此可以看出i和j的值肯定是不相等的,i不可能为负值,但是由于他们在内存中存储一样,所以能判断为相等,而且i的值是4294967295。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值