zoukankan      html  css  js  c++  java
  • C语言 string::size_type类型

    string::size_type类型

    从逻辑上来讲,size()成员函数似乎应该返回整型数值,或如2.2节“建议”中所述的无符号整数。但事实上,size操作返回的是string::size_type类型的值。我们需要对这种类型做一些解释。

    string类类型和许多其他库类型都定义了一些伙伴类型(companion types)。这些伙伴类型使得库类型的使用是机器无关的(machine-independent)。size_type就是这些伙伴类型中的一种。它定义为与unsigned型(unsigned int或unsigned long)具有相同的含义,而且可以保证足够大可存储任意string对象的长度。为了使用由string类型定义的size_type类型,程序员必须加上作用域操作符来说明所使用的size_type类型是由string类定义的。

    任何存储string的size操作结果的变量必须为string::size_type类型。特别重要的是,不要把size的返回值赋给一个int变量。

    虽然我们不知道string::size_type的确切类型,但可以知道它是unsigned型(2.1.1节)。对于任意一种给定的数据类型,它的unsigned型所能表示的最大正数值比对应的signed要大一倍。这个事实表明size_type存储的string长度是int所能存储的两倍。

    使用int变量的另一个问题是,有些机器上int变量的表示范围太小,甚至无法存储实际并不长的string对象。如在有16位int型的机器上,int类型变量最大只能表示32767个字符的string对象。而能容纳一个文件内容的string对象轻易就会超过这个数字。因此,为了避免溢出,保存一个string对象size的最安全的方法就是使用标准库类型string:: size_type。

    --------------------------------------------------------------------------------------------------------

    所有的查找函数都返回一个size_type类型,这个返回值一般都是所找到字符串的位置,如果没有找到,则返回string::npos 。有一点需要特 别注意,所有和string::npos的比较一定要用string::size_type来使用,不要直接使用int 或者unsigned int等类型。

    --------------------------------------------------------------------------------------------------------

    问题起源于这样一段代码:

    01 #include <algorithm> 
    02 #include <stdio.h> 
    03 
    04 int main()
    05 {
    06     size_t indexs = -1;
    07     size_t ps = 100;
    08     int index = -1;
    09     int p = 100;
    10     printf("%d ",std::min(p,index));
    11     printf("%d ",std::min(ps,indexs));
    12     return 0;
    13 }

    其实是很简单的题目,不过要对size_t类型有一个了解才行。

    关于size_t的来源 :

    数据类型"socklen_t"和int应该具有相同的长度。否则就会破坏 BSD套接字层的填充.POSIX开始的时候用的是size_t, Linus Torvalds(他希望有更多的人,但显然不是很多) 努力向他们解释使用size_t是完全错误的,因为在64位结构中 size_t和int的长度是不一样的,而这个参数(也就是accept函数的第三参数)的长度必须和int一致,因为这是BSD套接字接口标准.最终 POSIX的那帮家伙找到了解决的办法,那就是创造了一个新的类型"socklen_t".LinuxTorvalds说这是由于他们发现了自己的错误但又不好意思向大家伙儿承认,所以另外创造了一个新的数据类型 。

    size_t在C语言中就有了,size_t和ssize_t是ANSI C提供的标准头文件里定义的一个"数据类型",其实并不是新的数据类型,不是关键字,是通过typedef从已有数据类型定义而来。

    ANSI C总共提供了24个头文件。

    <cstddef>里这么定义了

    #include <stddef.h>

    using ::size_t

    using::ptrdiff_t

    在/usr/lib/gcc/i486-linux -gnu/4.4/include下面

    <stddef.h>里面我找到了这么几句:

    #ifndef __SIZE_TYPE__

    #define __SIZE__TYPE__ long unsigned int

    #endif

    #if !(defined(__GUNU__) && defined (size_t))

    typedef __SIZE_TYPE__ size_t;

    #ifdef __BEOS

    typedef long ssize_t

    没太看明白,不过从网上找到了不错的一个解释 :

    size_t是为了方便系统之间的移植而定义的。

    在32位系统上定义为 unsigned int

    在64位系统上定义为 unsigned long

    更准确的说法是在32位系统上是32位无符号整型

    在64位系统上是64位无符号整型

    size_t一般用来表示一种计数,比如有多少东西被拷贝等。

    sizeof操作符的结果类型是size_t,

    该类型保证能容纳实现所建立的最大对象的字节大小。

    它的意义大致是"适于计量内存中可容纳的数据项目的个数的无符号整数类型"。

    所以,它在数组下标和内存管理函数之类的地方广泛使用

    ssize_t:

    这个数据类型用来表示可以被执行读写操作的数据块的大小。它和size_t类似,但必须是signed。

    再来看下size_t与size_type的区别 :

    我觉得有一句话总结的很好:

    size_t是全局的,而size_type是跟容器相关的。

    找了下相关的文件:

    /c++ /4.3/bits/stl_tree.h,stl_list.h,stl_deque.h等直接这么定义了

    typedef size_t size_type

    stl_mutiset.h则这么定义的:

    typedef typename _Rep_type::size_type size_type;

    那么size_type到底是一种什么样的类型呢?

    string类类型和许多其他库类型都定义了一些配套类型(companion type)。通过这些配套类型,库类型的使用就能与机器无关。size_type就是这些配套类型中的一种。

    size_type被定义为与unsigned型(unsigned int, unsigned long)具有相同的含义,而且可以保证足够大能够存储任意string对象的长度。为而来使用由string类型定义的size_type类型。程序员 必须加上作用于操作符来说明所使用的size_type类型是由string类定义的。

    我们为什么不适用int变量来保存string的size呢?

    使用int变量的问题是:有些机器上的int变量的表示范围太小,甚至无法存储实际并不长的string对象。如在有16位int型的机器 上,int类型变量最大只能表示32767个字符的string对象。而能容纳一个文件内容的string对象轻易就能超过这个数字,因此,为了避免溢 出,保存一个string对象的size的最安全的方法就是使用标准库类型string::size_type ().

    一点注意 :虽然是在学习标准库string的时候巧遇了size_type类型,但是,其实vector库也可以定义size_type类型,在vector库中还有一个difference_type类型,该类型用来存储任何两个迭代器对象间的距离,所以是signed类型的。

    啰啰嗦嗦说了这么多,其实关于这个问题文章里红字标注的部分就足够了。其他的看下加深印象即可,最开始的程序结果输出为:

    -1 100。

  • 相关阅读:
    idea设置全局ignore
    win 2012 安装mysql 5.7.20 及报错 This application requires Visual Studio 2013 Redistributable. Please ins
    win 2012 安装mysql 5.7.20 及报错 This application requires Visual Studio 2013 Redistr
    kafka 删除 topic
    java编译中出现了Exception in thread “main" java.lang.UnsupportedClassVersionError
    Centos中使用yum安装java时,没有jps的问题的解决
    Spring 整合Junit
    Spring纯注解配置
    Spring 基于注解的 IOC 配置
    打印java系统的信息
  • 原文地址:https://www.cnblogs.com/guohaoyu110/p/6336898.html
Copyright © 2011-2022 走看看