课程咨询 : 020-87532245 24小时热线:15622781509 咨询QQ:3061057839

广州C++培训 > 达内新闻 > 数值极限和标准模板库
  • 数值极限和标准模板库

    发布:广州C++培训      来源:达内新闻      时间:2017-02-14

  • 广州达内C++培训的小编这一期给大家讲数值极限和标准模板库简介。

    4.3数值极限

    一般来说,数值型别的极值是一个与平台相关的特性。C++标准程序通过template numeric_limits提供这些极值,取代传统C语言所采用的预处理参数。新的极值概念有两个优点,第一是提供了更好的型别安全性,第二是程序员可借此写出一些templates以evaluate这些极值。

    C++Standard规定了各种型别必须保证的最小精度,如果你能够注意并运用这些极值,就比较容易写出与平台无关的程序。

    1. Class umeric_limits<>

    使用template通常是为了对所有型别一次性地撰写出一个通用解决方案。除此之外,你还可以在必要时候以template为每个型别提供共同接口。方法是:不但提供通用性的template,还提供特发版本。

    通用性的template,为所有型别提供缺省极值:

    namespace std {

    template<class T>

    class umeric_limits {

    public:

    //对型别T而言,无所谓极值存在

    static const bool is_specialized = false;

    ...

    }

    }

    各具体型别的极值,由特化版本提供:

    namespace std {

    template<> class numric_limits<int> {

    public:

    //所有其他成员都根据特定型别的具体极值加以设定

    static const bool is_specialized = true;

    //所有成员不是static就是const,以便在编译期确定

    static T min() throw() {

    return -2147483648;

    }

    ...

    }

    }

    下面展示某型别极值的可能运用,例如用来了解某个型别的最大值或确定char是否带正负号:

    #include<iostream>

    #include<limits>

    using namespace std;

    int main() {

    cout<<numeric_limits<int>::max()<<endl;

    }

    5.1 STL组件

    最关键的组件是容器、迭代器和算法。STL的基本观念就是将数据和操作分离。数据由容器类别加以管理,操作则由可定制的算法定义。迭代器在两者之间充当粘合剂,使任何算法都可以和任何容器交互运作。

    STL甚至提供更泛型化的组件。通过特定的adapter和function object。

    1. Containers

    总的来说,容器可分为两类:

    序列式容器,每个元素均有固定位置——取决于插入时机和地点,和元素值无关。STL提供三个定义好的序列容器:vector,deque,list。

    关联式容器,元素位置取决于特定的排序准则。STL提供四个关联式容器:set,multiset,map,multimap。

    序列式容器

    Vectors

    将元素置于一个dynamic array中加以管理。它允许随机存取,在array尾部附加元素或移除元素均非常快速。

    include<vector>

    ...

    vector<int> col1;

    Deque

    向两端发展的queue。

    include<deque>

    ...

    deque<int> col1;

    List

    由双向链表组成,意味着不能随机存取。

    include<list>

    ...

    list<int> col1;

    注意,front()会返回第一个元素,而pop_front()并不会返回被删除元素。

    string

    也可以将string当作STL容器来使用。这里的string是指C++ string类族系的对象。

    Array

    Vectors已经具有了dynamic array全部性质并提供更安全更便捷的接口。

    关联式容器

    缺省下以operator<进行比较,通常有二叉树组成。

    set

    内部元素依据其值自动排序,每个元素值只能出现一次。

    multiset

    和set相同,允许出现重复元素。

    map

    键值对,每个键只能出现一次。

    multimap

    和map相同,允许重复。

    容器配接器Container Adapters

    statck

    queue

    priority queue

    2. iterator

    迭代器是一个“可遍历STL容器内全部或部分元素”的对象。一个迭代器用来指出容器中的一个特定位置。基本操作如下:

    operator *

    operator ++

    operator ==和operator !=

    operator =

    迭代器的分类:

    双向迭代器。以递增运算前进或递减运算后退。list、set、multiset、map和multimap这些容器所提供的迭代器都属此类。

    随机存取迭代器。不但具有双向迭代器的所有属性,还具备随机访问能力。可以增加或减少一个偏移量、处理迭代器之间的距离、或是使用相对关系比较。但是为了撰写尽可能与容器型别无关的泛型程序代码,最好不要使用随机存取迭代器的特有操作。

    3. Algorithm

    为了处理容器内的元素,STL提供了一些标准算法,包括搜索、排序、拷贝、重新排序、修改、数字运算等算法。算法并非容器类别的成员函数,而是一种搭配迭代器使用的全局函数。这么做的好处就是只需做出一份,就可以对所有容器使用。

    使用需要包含头文件<algorithm>。

    4.迭代器之配接器Iterator Adapter

    迭代器是一个纯粹抽象概念:任何东西,只要其行为类似迭代器,它就是一个迭代器。因此,你可以撰写一些类,具备迭代器接口,但是有着各不相同的行为。

    以下简介三种迭代器配接器:

    Insert Iterator

    Inserter可以使算法以insert方式而非overwrite方式运作。使用它,可以解决算法的目标空间不足问题。有三种预先定义的Insert:Back inserters、Front inserters和general inserters。例子:

    copy(col1.begin(), col1.end(),

    inserter(col4, col4.begin()));

    Stream Iterator

    另一种是流迭代器,这是一种用来读写stream的迭代器。

    copy(istream_iterator<string>(cin), // start of source

    istream_iterator<string>(),     // end of source

    back_inserter(col1));          // destination

    Reverse Iterator

    使用operator++前进被转化为使用operator--后退至前一元素。

    copy(col1.rbegin(), col1.rend(),

    ostream_iterator<int>(cout, " "));

    5. Manipulating Algorithms

    某些算法会改变区间的内容,甚至会删除元素。这体现了STL为了将容器和算法分离,以获取灵活性的代价。

    调用remove函数的时候,并不会删除元素,而是进行覆盖,因为迭代器对容器的类型一无所知。一般remove会返回一个end迭代器,配合使用可以满足一般的需求,如果真的想删除就配合erase函数使用。

    变易型算法用于关联式容器上会出问题。因为容器内的元素总是根据某个排序准则自动排序。因此为了保证这个原则,关联式容器的所有迭代器均被声明为指向常量。那么问题来了,如何删除关联容器中的元素,调用成员函数。

    6.自定义泛型函数

    下面定义一个打印函数:

    template<class T>

    inline void print(const T& col1) {

    typename T::const_iterator pos; // typename表示是型别不是值

    for(pos = col1.begin(); pos != col1.end(); ++pos)

    cout<<*pos<<" ";

    }

    7. Functor, Function Object

    传递给算法的“函数型参数”,并不一定是函数,可以是行为类似函数的对象。这种对象称为function object,或称functor。

    class X {

    public:

    return-value operator() (arguments) const;

    }

    现在你可以把这个类别的对象当作函数来调用。

    X fo;

    fo(arg1, arg2); //等于调用fo.operator() (arg1, arg2)

    1.仿函数是“smart functions”

    “行为类似指针”的对象,我们称为“smart pointers”。仿函数可拥有成员函数和成员变量,这意味仿函数拥有状态。另一个函数就是,你可以在执行期初始化它们——当然必须在它们被使用之前。

    2.每个仿函数都有自己的型别。

    3.仿函数通常比一般函数速度快。

    8.容器内的元素

    容器元素的条件

    1.必须可透过copy构造函数进行复制。

    2.必须可以透过assignment操作符完成赋值动作。

    3.必须可以透过析构函数完成销毁动作。

    了解详情请登陆广州达内C++培训官网(gz.c.tedu.cn)!

    推荐文章

上一篇:C字符串复制

下一篇:c++之运算符来执行函数

最新开班日期  |  更多

c++--零基础周末班

c++--零基础周末班

开班日期:2月28日

c++--零基础全日制班

c++--零基础全日制班

开班日期:2月28日

c++--免费训练营

c++--免费训练营

开班日期:2月28日

c++--高薪就业班

c++--高薪就业班

开班日期:2月28日

  • 网址:http://gz.c.tedu.cn     地址:广州市天河北五山路 141 号尚德大厦 627
  • 课程培训电话: 020-87532245 24小时热线:15622781509 咨询QQ:3061057839     全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内时代科技集团有限公司 版权所有 京ICP证8000853号-56