无符号整数(string::size_type,size_t,unsigned,long unsigned)

本文深入探讨了C++中string::size_type、size_t、unsigned及long unsigned等数据类型的特性和应用,尤其关注这些类型在标准库string和vector中的角色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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_tsize_type的区别和联系

在C++Primer一书中,并未指出size_type(vector::size_type,string::size_type)具体为什么类型,只是指明其为无符号类型。能够存放任意string或者vector的对象大小。但是在实际中,size_tsize_type是几乎没有什么差别的。在C++Reference string中指明成员类型size_type的定义即为size_tvector::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 = -1i的值。

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来存放一个stringfind或者类似的成员函数,来存放返回的值是非常危险的行为,应该使用相对应的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的值,因此能够执行成功。

/data/k50048780/cpp_mutator/mutators/BitStream.cpp: In member function ‘BitStream BitStream::slice(size_t, size_t) const’: /data/k50048780/cpp_mutator/mutators/BitStream.cpp:154:46: error: passing ‘const BitStream’ as ‘this’ argument discards qualifiers [-fpermissive] 154 | copy_bits(*this, start_bit, 0, bit_length); | ^ In file included from /data/k50048780/cpp_mutator/mutators/BitStream.cpp:5: /data/k50048780/cpp_mutator/mutators/BitStream.h:62:10: note: in call to ‘void BitStream::copy_bits(const BitStream&, size_t, size_t, size_t)’ 62 | void copy_bits(const BitStream& src, size_t src_start, size_t dest_start, size_t bit_count); | ^~~~~~~~~ CMakeFiles/mutator.dir/build.make:446: recipe for target 'CMakeFiles/mutator.dir/mutators/BitStream.cpp.o' failed make[3]: *** [CMakeFiles/mutator.dir/mutators/BitStream.cpp.o] Error 1 make[3]: *** Waiting for unfinished jobs.... /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp: In constructor ‘StringLengthEdgeCase::StringLengthEdgeCase(std::shared_ptr<StringBase>, std::mt19937): /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:10:37: error: no matching function for call to ‘IntegerEdgeCases::IntegerEdgeCases(std::shared_ptr<StringBase>&, std::mt19937&)’ 10 | : IntegerEdgeCases(obj, rand) { | ^ In file included from /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.h:10, from /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:5: /data/k50048780/cpp_mutator/mutators/string/../utils.h:146:5: note: candidate: ‘IntegerEdgeCases::IntegerEdgeCases(std::shared_ptr<NumberBase>, std::mt19937&)’ 146 | IntegerEdgeCases(std::shared_ptr<NumberBase> obj, std::mt19937 &rand); | ^~~~~~~~~~~~~~~~ /data/k50048780/cpp_mutator/mutators/string/../utils.h:146:50: note: no known conversion for argument 1 from ‘shared_ptr<StringBase>’ to ‘shared_ptr<NumberBase>’ 146 | IntegerEdgeCases(std::shared_ptr<NumberBase> obj, std::mt19937 &rand); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~ /data/k50048780/cpp_mutator/mutators/string/../utils.h:144:7: note: candidate: ‘IntegerEdgeCases::IntegerEdgeCases(const IntegerEdgeCases&)’ 144 | class IntegerEdgeCases : public Mutator { | ^~~~~~~~~~~~~~~~ /data/k50048780/cpp_mutator/mutators/string/../utils.h:144:7: note: candidate expects 1 argument, 2 provided /data/k50048780/cpp_mutator/mutators/string/../utils.h:144:7: note: candidate: ‘IntegerEdgeCases::IntegerEdgeCases(IntegerEdgeCases&&)’ /data/k50048780/cpp_mutator/mutators/string/../utils.h:144:7: note: candidate expects 1 argument, 2 provided /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp: In member function ‘virtual std::pair<long int, long int> StringLengthEdgeCase::get_limits(std::shared_ptr<StringBase>): /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:24:25: error: request for member ‘has_value’ in ‘((std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>*)(& obj))->std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>::operator->()->StringBase::<anonymous>.TypeBase<StringBase>::max_length’, which is of non-class type ‘int64_t’ {aka ‘long int’} 24 | if (obj->max_length.has_value()) { | ^~~~~~~~~ /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:25:47: error: request for member ‘value’ in ‘((std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>*)(& obj))->std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>::operator->()->StringBase::<anonymous>.TypeBase<StringBase>::max_length’, which is of non-class type ‘int64_t’ {aka ‘long int’} 25 | max_ = std::min(max_, obj->max_length.value()); | ^~~~~ /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:29:25: error: request for member ‘has_value’ in ‘((std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>*)(& obj))->std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>::operator->()->StringBase::<anonymous>.TypeBase<StringBase>::min_length’, which is of non-class type ‘int64_t’ {aka ‘long int’} 29 | if (obj->min_length.has_value()) { | ^~~~~~~~~ /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:30:47: error: request for member ‘value’ in ‘((std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>*)(& obj))->std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>::operator->()->StringBase::<anonymous>.TypeBase<StringBase>::min_length’, which is of non-class type ‘int64_t’ {aka ‘long int’} 30 | min_ = std::max(min_, obj->min_length.value()); | ^~~~~ /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp: At global scope: /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:42:6: error: no declaration matches ‘void StringLengthEdgeCase::perform_mutation(std::shared_ptr<StringBase>, int64_t)’ 42 | void StringLengthEdgeCase::perform_mutation(std::shared_ptr<StringBase> obj, int64_t value) { | ^~~~~~~~~~~~~~~~~~~~ In file included from /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:5: /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.h:16:10: note: candidate is: ‘void StringLengthEdgeCase::perform_mutation(std::shared_ptr<String>, size_t)’ 16 | void perform_mutation(std::shared_ptr<String> obj, size_t index); | ^~~~~~~~~~~~~~~~ /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.h:13:7: note: ‘class StringLengthEdgeCase’ defined here 13 | class StringLengthEdgeCase : public IntegerEdgeCases { | ^~~~~~~~~~~~~~~~~~~~ In file included from /data/k50048780/cpp_mutator/mutators/MutatorFactory.cpp:8: /data/k50048780/cpp_mutator/mutators/number/NumberVariance.h:13:32: error: invalid covariant return type for ‘virtual std::pair<long unsigned int, long unsigned int> NumberVariance::get_limits(std::shared_ptr<NumberBase>)’ 13 | std::pair<size_t ,size_t > get_limits(std::shared_ptr<NumberBase> obj); | ^~~~~~~~~~ In file included from /data/k50048780/cpp_mutator/mutators/string/../../utils/sample_util.h:12, from /data/k50048780/cpp_mutator/mutators/string/StringCaseLower.h:8, from /data/k50048780/cpp_mutator/mutators/MutatorFactory.cpp:6: /data/k50048780/cpp_mutator/mutators/string/../../utils/../mutators/utils.h:70:51: note: overridden function is ‘virtual std::pair<long int, long int> IntegerVariance::get_limits(std::shared_ptr<NumberBase>)’ 70 | virtual std::pair<std::int64_t, std::int64_t> get_limits(std::shared_ptr<NumberBase> obj); | ^~~~~~~~~~
最新发布
06-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值