size_type:

   STL容器中的一个成员变量,是一种用以保存不同容器的任意大小的类型,它与size_t一样,目的都是为了使用起来与具体机器无关。标准库类型将size_type定义为unsigned类型,比如string类的string::size_type 就是一个代表string抽象长度的无符号整型。也就是说,string::size_type从本质上来说,是一个整型数。关键是由于机器的环境,它的长度有可能不同。

size_t:

size_t是一些C/C++标准在stddef.h中定义的。这个类型足以用来表示对象的大小。size_t的真实类型与操作系统有关。

在32位机器中被普遍定义为:

typedef   unsigned int size_t;

而在64位机器中被定义为:

typedef  unsigned long size_t;

        size_t在32位架构上是4字节,在64位架构上是8字节,在不同架构上进行编译时需要注意这个问题。而int在不同架构下都是4字节,与size_t不同;且int为带符号数,size_t为无符号数。

 

为什么有时候不用int,而是用size_type或者size_t:

       与int固定四个字节不同有所不同,size_t的取值range是目标平台下最大可能的数组尺寸,一些平台下size_t的范围小于int的正数范围,又或者大于unsigned int. 使用Int既有可能浪费,又有可能范围不够大。

 

容易被坑的一些地方:

0x0001:

string str="123";
int a=2;
cout<<a-str.size()<<endl;

这段代码的输出并不是-1,在我64位win10系统中的输出是:4294967295,这是因为str.size()返回值是size_type一个无符号整数,而编译器在int与size_type做减法时,都视为了无符号整数。
 

0x0002:

我们在使用 string::find的函数的时候,它返回的类型就是 string::size_type类型。而当find找不到所要找的字符的时候,它返回的是 npos的值,这个值是与size_type相关的。假如,你是用 string s; int rc = s.find(.....); 然后判断,if ( rc == string::npos ) 这样在不同的机器平台上表现就不一样了。如果,你的平台的string::size_type的长度正好和int相匹配,那么这个判断会侥幸正确。但换成另外的平台,有可能 string::size_type的类型是64位长度的,那么判断就完全不正确了。 所以,正确的应该是: string::size_type rc = s.find(.....); 这个时候使用 if ( rc == string::npos )就回正确了。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐