string::size_type
size_t
unsigned
long unsigned
这四种数据类型在C++语言环境下均为无符号整数,但是却又各不相同,这里介绍下它们各自之间的关系和区别。
string::size_type
标准库string
中的成员类型(member type),以实现标准库类型和机器的无关性,能够存下任意string
对象的大小,是一种无符号类型。
标准库string
的成员函数(size(),查找函数)的返回值类型均为string::size_type
。
在用下标访问元素时,string
使用string::size_type
作为下标类型。
string::size_type
它在不同的机器上,长度是可以不同的,并非固定的长度。但只要你使用了这个类型,就使得你的程序适合这个机器与实际机器匹配。与之类似的有vector::size_type
。
size_t
cstddef
头文件中定义的一种与机器实现有关的无符号整数类型,其能够表示任意数组的大小。
size_t
和size_type
的区别和联系
在C++Primer一书中,并未指出size_type
(vector::size_type
,string::size_type
)具体为什么类型,只是指明其为无符号类型。能够存放任意string
或者vector
的对象大小。但是在实际中,size_t
和size_type
是几乎没有什么差别的。在C++Reference string中指明成员类型size_type
的定义即为size_t
。vector::size_type
也一样。
string::npos
string::size_type
所能表示的最大值,其在不同的机器环境下有着不同的值,当使用标准库string
中的查找(find
,rfind
,find_first_of
,find_first_not_of
,find_last_of
,find_last_not_of
)函数时,如果无法找到指定的字符串,返回string::npos
。实际中,其值等于string::size_type i = -1
中i
的值。
unsigned
即unsigned int
,无符号整数类型,不同的机器上其能够表示的范围不同。但是最少要求两个字节存储一个unsigned
类型的整数,因此unsigned
类型最小的最大值为65535,而在实际系统中可能会更大,如采用四个字节存储unsigned
的数据类型的时候,最大值为4294967295。C语言标准库中的limits.h头文件定义了unsinged int的最大值宏——UINT_MAX。
long unsigned
即long unsigned int
,无符号长整数类型,不同的机器上其能够表示的范围不同。但是最少要求两个字节存储一个unsigned long
类型的整数,因此unsigned long
类型最小的最大值为4294967295,而在实际系统中可能会更大。与unsigned类似,C语言标准库中的limits.h头文件定义了unsinged int的最大值宏——ULONG_MAX。
代码分析
#include <vector>
#include <string>
#include <iostream>
#include <cstddef>
using std::vector;
using std::string;
using std::cout;
using std::endl;
using std::cin;
int main(int argc, char const *argv[])
{
unsigned i = -1;
long unsigned l = -1;
string::size_type j = -1;
size_t k = -1;
cout << "sizeof(unsigned): " << sizeof(unsigned) << endl;
cout << i << endl;
cout << "sizeof(long unsigned): " << sizeof(long unsigned) << endl;
cout << l << endl;
cout << "sizeof(string::size_type): " << sizeof(string::size_type) << endl;
cout << j << endl;
cout << "sizeof(size_t): " << sizeof(size_t) << endl;
cout << k << endl;
return 0;
}
在ubtun64位的机器上程序的输出结果为:
sizeof(unsigned): 4
4294967295
sizeof(long unsigned): 8
18446744073709551615
sizeof(string::size_type): 8
18446744073709551615
sizeof(size_t): 8
18446744073709551615
在vs2010下程序的执行结果为:
注意事项
在实际中,使用unsigned
或者long unsigned
来存放一个string
中find
或者类似的成员函数,来存放返回的值是非常危险的行为,应该使用相对应的string::size_type
来存放。
如下:
#include <string>
#include <iostream>
using std::string;
using std::cout;
using std::endl;
using std::cin;
int main(int argc, char const *argv[])
{
string str("ab2c3d7R4E6");
string num("0123456789");
string::size_type offset = 0;
unsigned i;
while (( i = str.find_first_of(num,offset)) != string::npos)
{
cout << str[i] << " ";
offset = i + 1;
}
cout << endl;
return 0;
}
上述代码在vs2010环境下是可以正确运行的,但是在ubtuntu64环境下,总是发生段错误,而实际原因就是用unsigned i
来存放find_first_of
的返回值,显然在此环境下i
最大值只能是4294967295,而string::npos
的值则为18446744073709551615。因此会发生错误。而在vs2010下unsigned
类型可以存放string::size_type
的所有值的,能够正确的存放 string::npos
的值,因此能够执行成功。