精华内容
下载资源
问答
  • 向系统返回0,表示程序正常结束。 std::exit(0); 向系统返回1,表示程序非正常结束。 2、std::abort() 程序异常结束,不会调用析构函数: #define debug qDebug()<< struct ceshi { ~ceshi() { debug ...

    1、std::exit() 由系统调用,表示结束进程。对于已构造的对象会调用析构函数(在一个析构函数中调用exit()会无限递归)。

    • std::exit(0); 向系统返回0,表示程序正常结束。
    • std::exit(1); 向系统返回1,表示程序非正常结束。

    2、std::abort() 程序异常结束,不会调用析构函数:

    #define debug qDebug()<<
    struct ceshi
    {
        ~ceshi()
        {
            debug "ceshi 析构";
        }
    };
    
    int main(int argc, char *argv[])
    {
        ceshi c;
        std::abort();
        debug "hello";
    }

    3、std::atexit(void (*fun) (void)) 参数是一个函数指针,指向一个无参数无返回值的函数,终止前可以执行制定的函数。会调用析构函数,析构顺序:在std::atexit()前面定义的后析构,在std::atexit()后面定义的先析构:

    #define debug qDebug()<<
    struct ceshi
    {
        ~ceshi()
        {
            debug "ceshi 析构" << a;
        }
        int a;
    };
    
    void debugValue()
    {
        debug "hello world";
    }
    
    int main(int argc, char *argv[])
    {
        ceshi c1;
        c1.a = 88;
        std::atexit(debugValue);
        ceshi c2;
        c2.a = 66;
    
        debug "hello";
    }

    4、std::quick_exit() 和exit()相似但不调用析构函数。

    展开全文
  • C++ STL标准模板简介

    2021-05-03 13:58:38
    文章目录1. 什么是STL?...标准模板库(英文:Standard Template Library,缩写:STL),是一个C++软件库,大量影响了C++标准程序库但并非是其的一部分。其中包含4个组件,分别为算法、容器、函数、


    C++ STL标准库系列文章:

    [STL] 1.简介
    [STL] 2.序列容器 固定数组array(C++ 11)
    [STL] 3.序列容器 动态数组vector
    [STL] 4.序列容器 双端队列deque
    [STL] 5.序列容器 双向链表list
    [STL] 6.序列容器 单向链表forward_list(C++ 11)
    [STL] 7.适配器简介
    [STL] 8.容器适配器 栈stack
    [STL] 9.容器适配器 队列queue
    [STL] 10.容器适配器 优先队列priority_queue
    [STL] 11.关联容器 集合set
    [STL] 12.关联容器 映射map
    [STL] 13.关联容器 多重集合multiset
    [STL] 14.关联容器 多重映射multimap
    [STL] 15.关联容器 无序集合unordered_set(C++ 11)
    [STL] 16.关联容器 无序集合unordered_map(C++ 11)
    [STL] 17.仿函数functor与函数对象
    [STL] 18.预定义函数对象、仿函数适配器
    [STL] 19.算法algorithm
    [STL] 20.迭代器适配器
    [STL] 21.空间配置器allocator

    1. 什么是STL?

    标准模板库 - 维基百科,自由的百科全书 (wikipedia.org)

    标准模板库(英文:Standard Template Library,缩写:STL),是一个C++软件库,大量影响了C++标准程序库但并非是其的一部分。其中包含4个组件,分别为算法、容器、函数、迭代器。[1]

    模板是C++程序设计语言中的一个重要特征,而标准模板库正是基于此特征。标准模板库使得C++编程语言在有了同Java一样强大的类库的同时,保有了更大的可扩展性。

    2. STL的优势

    • 功能强大、代码精致

    STL由惠普实验室的无数大牛们开发,设计精巧,功能强大,集成了优秀的算法。

    • 高可重用性

    ST广泛使用模板泛型编程,代码具有高度的复用性。

    • 高性能、工业强度

    ST提供的算法具有工业强度,高性能,用它可开发出性能高效的应用程序。

    • 开源跨平台

    STL跨平台,而且开源,开发者可以很容易借鉴与扩展。

    3. STL版本?

    HP STL

    HP STL是Alexandar Stepanov在惠普Palo Alto实验室工作时,与Meng Lee合作完成的。HP STL是C++ STL的第一个实现版本,而且是开放源码。其它版本的C++ STL一般是以HP STL为蓝本实现出来的。

    SGI STL

    由Silicon Graphics Computer Systems公司参照HP STL实现,主要设计者仍然是STL之父Alexandar Stepanov,被Linux的C++编译器GCC所采用。SGI STL是开源软件,源码可读性甚高。

    STLport

    为了使SGI STL的基本代码都适用于VC++和C++ Builder等多种编译器,俄国人Boris Fomitchev建立了一个free项目来开发STLport,此版本STL是开放源码的。

    P.J.Plauger STL

    由P.J.Plauger参照HP STL实现出来,被Visual C++编译器所采用,但不是开源的。

    Rouge Wave STL

    由Rouge Wave公司参照HP STL实现,用于Borland C++编译器中,这个版本的STL也不是开源的。

    4. STL的六大组件

    image-20210503121253228

    1、容器(Containers):各种数据结构,如Vector,List,Deque,Set,Map,用来存放数据,STL容器是一种Class Template,就体积而言,这一部分很像冰山载海面的比率。

    2、算法(Algorithms):各种常用算法如Sort,Search,Copy,Erase,从实现的角度来看,STL算法是一种Function Templates。

    3、迭代器(Iterators):扮演容器与算法之间的胶合剂,是所谓的“泛型指针”,共有五种类型,以及其它衍生变化,从实现的角度来看,迭代器是一种将:Operators*,Operator->,Operator++,Operator–等相关操作予以重载的Class Template。所有STL容器都附带有自己专属的迭代器——是的,只有容器设计者才知道如何遍历自己的元素,原生指针(Native pointer)也是一种迭代器。

    4、仿函数(Functors): 行为类似函数,可作为算法的某种策略(Policy),从实现的角度来看,仿函数是一种重载了Operator()的Class 或 Class Template。一般函数指针可视为狭义的仿函数。

    5、配接器(适配器)(Adapters):一种用来修饰容器(Containers)或仿函数(Functors)或迭代器(Iterators)接口的东西,例如:STL提供的Queue和Stack,虽然看似容器,其实只能算是一种容器配接器,因为 它们的底部完全借助Deque,所有操作有底层的Deque供应。改变Functor接口者,称为Function Adapter;改变Container接口者,称为Container Adapter;改变Iterator接口者,称为Iterator Adapter。配接器的实现技术很难一言蔽之,必须逐一分析。

    6、分配器(Allocators):负责空间配置与管理,从实现的角度来看,配置器是一个实现了动态空间配置、空间管理、空间释放的Class Template。

    ​ ——《STL源码剖析》

    5. 学习建议

    路线:

    • C++数据结构
    • C++模板
    • STL标准库
    • Boost库

    资源:

    Containers - C++ Reference (cplusplus.com)

    cppreference.com

    image-20210503121942346

    image-20210503133131350

    6. 为什么需要迭代器?

    #include "stdafx.h"
    #include<iostream>
    using namespace  std;
    
    /* 思考题一
    现在有一个数组  int  arr[5] = { 1,2,3,4,5 };
    void   Print(int  *begin, int  *end)
    {
    //此处编写代码
    }
    让 Print(arr, arr + 5);  实现打印所有元素?
    */
    
    /*
    void   Print(int  *begin, int  *end)
    {
       //此处编写代码
       for (int *p = begin; p != end; ++p)//利用指针的++,依次访问每个元素
       {
       	cout << *p << "		";
       }
       cout << endl;
    }
    */
    
    /*  思考题二
    
    现在有一个链表,有5个Node节点:
    
    struct   Node
    {
    int  data;
    Node*  next;
    };
    
    void   Print(Node *begin, Node *end)
    {
    //此处编写代码
    }
    
    让 Print(pHead,  pTail );  实现打印所有元素?
    */
    
    struct   Node
    {
       int  data;
       Node*  next; 
    };
    
    ostream & operator <<(ostream&  o,const  Node &node)
    {
       o << node.data << endl;
       return   o;
    }
    
    /*
    void   Print(Node *begin, Node *end)
    {
       //此处编写代码
       for (Node *p    =begin;  p!= end ;  p=p->next) //指向下一个节点
       {
       	cout << (*p).data << "		"; 
       }
       cout << endl;
    }
    */
    
    //思考题三
    //写出一个通用的Print 函数模板
    template<class T>
    void   Print(T  begin, T  end)
    {
       //此处编写代码
       for (T  p = begin; p != end; ++p)
       {
       	cout << *p << "		";
       }
       cout << endl;
    }
    
    int main()
    {
       //题目一测试
       int  arr[5] = { 1,2,3,4,5 };
       Print(arr, arr + 5); //arr + 5是指向 最后一个元素下一个的位置
       
       //Print<int *>(arr, arr + 5);//调用模板函数
    
    
        //题目二测试
       Node  n1;
       n1.data = 11;
       Node  n2;
       n2.data =22;
       Node  n3;
       n3.data = 33;
       Node  n4;
       n4.data = 44;
       Node  n5;
       n5.data = 55;
    
       n1.next = &n2;
       n2.next = &n3;
       n3.next = &n4;
       n4.next = &n5;
       n5.next = NULL;
    
       Print(&n1, n5.next);
    
       return 0;
    }
    

    7. 自己实现迭代器iterator

    迭代器(iterator)是指针的抽象,它允许程序员以相同的方式处理不同的数据结构(容器)。

    迭代器支持的一些基本操作:

    • =:迭代器赋值
    • ==:比较迭代器的相等性
    • !=:比较迭代器的不等性
    • ++:迭代器向后移动
    • --:迭代器向前移动
    • *:解引用,返回迭代器指向的元素
    #include "stdafx.h"
    #include<iostream>
    using namespace  std;
    
    //思考题三
    //写出一个通用的Print 函数模板
    template<class T>
    void   Print(T  begin, T  end)
    {
       //此处编写代码
       for (T  p = begin; p != end; ++p)
       {
       	cout << *p << "		";
       }
       cout << endl;
    }
    
    //虽然数组不需要迭代器,因为指针就是一种特殊的迭代器
    //也可以设计一个数组迭代器
    class  ArrayIterator
    {
    public:
       ArrayIterator(int *p) : _p(p) {}
       ArrayIterator  &  operator++()
       { 
       	++_p;//指针就是++指向下一个
       	return  *this ;
       }
    
       bool   operator!=(const ArrayIterator & it)
       {
       	return  _p != it._p;
       }
    
       int&   operator*()
       {
       	return   *_p;
       }
       //private: 
       int * _p;
    };
    
    //考虑设计一个中间类,让它支持operator ++,实际实现是链表的p=p->next
    //链表迭代器
    class  ListIterator
    {
    public:
       ListIterator(Node *p) : _p(p) {} 
       ListIterator  &  operator++()
       {
       	//链表的真正操作
       	_p = _p->next;
       	return  *this;
       }
    
       bool   operator!=(const ListIterator & it)
       {
       	return  _p != it._p;
       }
    
       Node&   operator*( )
       {
       	return   *_p;
       }
    //private: 
       Node * _p; 
    };
     
    int main()
    {
       //使用链表迭代器
       ListIterator begin(&n1);
       ListIterator end(n5.next);
       Print(begin, end);
    
       return 0;
    }
    

    8. STL中的5种迭代器

    • 输入迭代器(Input iterator)
    • 输出迭代器(Output Iterator)
    • 前向迭代器(Forward iterator)
    • 双向迭代器(Bidirectional iterator)
    • 随机访问迭代器(Random Access iterator)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-on3WXlhN-1620021492142)(C:\Users\tangx\AppData\Roaming\Typora\typora-user-images\image-20210503133856493.png)]

    image-20210503133806278

    image-20210503133715845

    不同的数据结构(容器)支持的迭代器类型不同,比如数组结构可支持随机访问迭代器,但是链表结构就无法支持,链表往往设计为双向迭代器。

    9. STL中的iterator类

    iterator类是一个基类模板,可用于从它派生迭代器类。它不提供迭代器具有的任何功能,仅提供了些默认成员类型,这些并不是迭代器类型必须需具备的,它们可能是有用的。

    定义:

    iterator - C++ Reference (cplusplus.com)

    template <class Category, class T, class Distance = ptrdiff_t,
             class Pointer = T*, class Reference = T&>
     struct iterator {
       typedef T         value_type;
       typedef Distance  difference_type;
       typedef Pointer   pointer;
       typedef Reference reference;
       typedef Category  iterator_category;
     };
    

    Category

    迭代器所属的类别。 它必须是以下迭代器标签之一:

    迭代器标签迭代器的类别迭代器类型
    input_iterator_tagInput Iterator输入迭代器
    output_iterator_tagOutput Iterator输出迭代器
    forward_iterator_tagForward Iterator前向迭代器
    bidirectional_iterator_tagBidirectional Iterator双向迭代器
    random_access_iterator_tagRandom-access Iterator随机访问迭代器

    T

    迭代器指向的元素类型。

    Distance

    键入以表示两个迭代器之间的差异。

    Pointer

    类型,表示指向迭代器指向的元素的指针。

    Reference

    类型,表示对迭代器指向的元素的引用。

    示例代码:

    #include "stdafx.h"
    #include<iostream>
    #include<iterator>
    
    using namespace  std;
    
    class  A
    {
    public:
       typedef  int  MYINT;  //内部类型
       using   MYFLOAT = float; //内部类型
    };
    
    class MyIterator : public std::iterator<std::random_access_iterator_tag, int>
    {
       int* p;
    public:
       MyIterator(int* x) :p(x) {}
       MyIterator(const MyIterator& mit) : p(mit.p) {}
       MyIterator& operator++() { ++p; return *this; }
       MyIterator operator++(int) { MyIterator tmp(*this); operator++(); return tmp; }
       bool operator==(const MyIterator& rhs) const { return p == rhs.p; }
       bool operator!=(const MyIterator& rhs) const { return p != rhs.p; }
       int& operator*() { return *p; }
       //int &operator[](int index) { 	return   *(p + index); }
    };
    
    int main()
    {
       //A::MYINT  a = 100;
       //A::MYFLOAT b = 100;
    
       //定义一个迭代器对象
       iterator<  input_iterator_tag   , int>  it ;
    
     	//内部类型:iterator_category代表迭代器类别类型
       cout << typeid(iterator<input_iterator_tag, int>::iterator_category).name() << endl;
    
       //迭代器指向元素的类型
       cout << typeid( iterator<input_iterator_tag, int>::value_type).name() << endl;
    
       //迭代器指向元素的指针类型
       cout << typeid(iterator<input_iterator_tag, int>::pointer).name() << endl;
    
       //迭代器指向元素的引用类型 
       cout << typeid(iterator<input_iterator_tag, int>::reference).name() << endl;
    
       //迭代器指向元素的指针类型 相减得到的差值类型
       cout << typeid(iterator<input_iterator_tag, int>::difference_type).name() << endl;
    
       iterator<input_iterator_tag, int>::value_type  a = 100;
       iterator<input_iterator_tag, int>::pointer  pA = &a;
       iterator<input_iterator_tag, int>::reference  b=a;
    
       cout << a << "		" << *pA << endl;
       b = 200;
       cout << a<<"		"<< b << endl;
    
       iterator<input_iterator_tag, int>::pointer  pB = &a+2;
    
       iterator<input_iterator_tag, int>::difference_type  c = pB - pA;
       cout << c << endl;
    
       //测试自定义的迭代器
       int numbers[] = { 10,20,30,40,50 };
       MyIterator from(numbers);
       MyIterator until(numbers + 5);
       for (MyIterator it = from; it != until; it++)
       	std::cout << *it << ' ';
       std::cout << '\n';
       
       //cout << from[3] << endl;
    
       MyIterator::value_type  x = 100;
    
       return 0;
    }
    

    10. 序列容器对比

    序列容器数据结构底层实现迭代器优缺点
    array (c++11)固定数组普通数组、连续内存随机访问迭代器快速随机访问、在中间插入、删除元素效率较低、无法扩容
    vector动态数组new 堆内存、连续内存随机访问迭代器快速随机访问、在中间插入、删除元素效率较低、容量可动态增长
    deque双端队列一个中央控制器和多个缓冲区、不连续随机访问迭代器快速随机访问、两端插入、删除效率高
    list双向链表双向链表、不连续双向迭代器不支持随机访问、可双向遍历、任意位置插入、删除元素效率高
    forward_list (c++11)单向链表单向链表、不连续前向迭代器不支持随机访问、单向遍历、任意位置插入、删除元素效率高

    11. 容器适配器对比

    容器适配器数据结构底层实现迭代器特点
    stack底层默认用queue实现,也可以是vectorlist不支持先进后出 FILO
    queue队列底层默认用queue实现,也可以是list不支持先进先出 FIFO
    priority_queue优先队列底层默认用vector为容器,使用堆heap为处理规则来排序。容器也可以是deque不支持优先级最高(或最低)的元素先出

    12. 关联容器对比

    序列容器数据结构底层实现迭代器优缺点
    set集合红黑树双向迭代器key唯一、有序
    map映射红黑树双向迭代器key唯一、有序、value可重复
    multiset多重集合红黑树双向迭代器key可重复、有序
    multimap多重映射红黑树双向迭代器key可重复、有序、value可重复
    unordered_set无序集合哈希表双向迭代器key唯一、无序
    unordered_map无序映射哈希表双向迭代器key唯一、无序、value可重复
    unordered_multiset (c++11)无序多重集合哈希表双向迭代器key可重复、无序
    unordered_multimap (c++11)无序多重映射哈希表双向迭代器key可重复、无序、value可重复
    展开全文
  • C++的模板为泛型程序设计奠定了关键的基础 术语:概念 用来界定具备一定功能的数据类型。例如: 将“可以比大小的所有数据类型(有比较运算符)”这一概念记为Comparable 将“具有公有的复制构造函数并可以用...

    10.1 泛型程序设计及STL的结构

    10.1.1 泛型程序设计的基本概念

    • 编写不依赖于具体数据类型的程序
    • 将算法从特定的数据结构中抽象出来,成为通用的
    • C++的模板为泛型程序设计奠定了关键的基础

    术语:概念

    • 用来界定具备一定功能的数据类型。例如:
      • 将“可以比大小的所有数据类型(有比较运算符)”这一概念记为Comparable
      • 将“具有公有的复制构造函数并可以用‘=’赋值的数据类型”这一概念记为Assignable
      • 将“可以比大小、具有公有的复制构造函数并可以用‘=’赋值的所有数据类型”这个概念记作Sortable
    • 对于两个不同的概念A和B,如果概念A所需求的所有功能也是概念B所需求的功能,那么就说概念B是概念A的子概念。例如:
      • Sortable既是Comparable的子概念,也是Assignable的子概念

    术语:模型

    • 模型(model):符合一个概念的数据类型称为该概念的模型,例如:
      • int型是Comparable概念的模型。
      • 静态数组类型不是Assignable概念的模型(无法用“=”给整个静态数组赋值)

    用概念做模板参数名

    • 很多STL的实现代码就是使用概念来命名模板参数的。
    • 为概念赋予一个名称,并使用该名称作为模板参数名。
    • 例如

      • 表示insertionSort这样一个函数模板的原型:

    template <class Sortable>
    void insertionSort(Sortable a[], int n);

    原文链接:侵删

    https://www.cnblogs.com/alec7015/p/12465052.html

    展开全文
  • c++标准库iostream

    2021-11-14 16:19:24
    我们学习c的时候也频繁用到了一些,但是并不多,c++也有,且比c要多,通常越高级的语言越多,如java、python等封装越严重的语言就更多,在学习高级语言时学习占比变得很重,如python我们学习完他的语法...

            我们学习c的时候也频繁用到了一些库,但是库并不多,c++也有库,且比c要多,通常越高级的语言库越多,如java、python等封装越严重的语言库就更多,在学习高级语言时学习库占比变得很重,如python我们学习完他的语法才算刚刚入门,后面的提高就是库的应用。一个典型的c程序(后缀.c)可以完全被视为c++程序来编译。在c++的编译器中自动定义了一个long int型__cplusplus(双下划线)变量用来存放当前c++的版本,而c没有该变量,所以c程序可以使用宏来判断是否有定义__cplusplus符号来判断当前是c还是c++的编译环境。

            c++的源文件名的常用扩展名有.cpp .cxx .cc .c .c++,头文件有.hpp .hxx .h。由此可见c++是一个c的超集, c++完全兼收了c的语法特性和标准库,所以c++编译器完全可以正常编译一个c程序。

            虽然c++程序可以支持c形式包含头文件的方式并直接使用库中的函数,如stdio.h,他并不是源生支持,而是这是c++做了很多额外工作,来兼容的。所以c++并不建议我们以c的写法去包含原来c的头文件,而是推荐使用c++的库,如<cstdio>来代替<stdio.h>,没错没有扩展名,在c++中所有的标准库都没有后缀扩展名,如.h。

            ubuntu中gcc的工具链的头文件在/usr/include 在当前目录下还有一个c++的文件夹,存放的全是g++工具链的头文件。

    iostream引用

    iostream是c++的常用标准库之一,内部包含了很多我们常用的函数,为了防止库与我们自定义的名称冲突,所以他也使用了命名空间,封装的命名空间名称为std。std的声明在iostream头文件中,与众不同的是这个头文件的包含不需要.h,直接#include<iostream>头文件即可,既然是命名空间,那么我们要使用std命名空间的元素,如cout就需要std::cout。由于对该头文件内的东西频繁使用,所以我们一般,直接将整个命名空间进行声明如:

    using namespace std;        //声明库中的命名空间,
    cout << “hell word” << endl  //调用其内部元素cout

    标准输出cout

            cout标准输出,对应stdout,在std命名空间中。结合 <<(流操作)进行输出,可多节连接。cout涉及的头文件有<iostream> <iomanip>,iostram还生了两个儿子就是ostram(输出)和istram(标准输入),iomanip内部是一些格式化,如输入输出的对齐。

            cout本质上是ostream(iostream派生类)的一个对象,暂时我们先将类简单理解成类型,对象理解成变量。也就是说cout其实是在iostream中事先定义的一个变量。

            操作符 << 本质上是c语言中的左移,在iostream中进行了运算符重载(把符号功能进行了重新定义)。

    示例:
    int val=8;
    cout << “hello word” << val << endl

            我们可以把cout看成是一个输出设备,把<<看成箭头,大概意思就是把字符串按箭头方向送到cout设备即可实现输出。endl与cout一样都是std命名空间中的一个对象,我们可简单的把他理解成是\n\r的一个替代。实际上我们同样可以就就写<</n,但是这是c的语法,我们在c++中一般不用。val是一个我们要输出值的变量。多个<<符号可以进行级联。

    流操作格式化

    流操作格式化一般使用“流操作算子”,常用的操作符见下表,他们都是在iomanip头文件中,要使用必须包含该头文件。

    流操纵算子

    作  用

    dec(默认)

    以十进制形式输出整数

    hex

    以十六进制形式输出整数

    oct

    以八进制形式输出整数

    fixed

    以普通小数形式输出浮点数

    scientific

    以科学计数法形式输出浮点数

    left

    左对齐,即在宽度不足时将填充字符添加到右边

    right(默认)

    右对齐,即在宽度不足时将填充字符添加到左边

    标准输入cin

            cin是c++中的标准输入,也是iostream头文件中定义的std命名空间。实际上标准输入与标准输出有很多点相类似,如上表的格式也同样适用于输入,数据流符号位>>右移符号,无论是输出还是输入,cout和cin都在左边,我们的变量或要操作的内容在右边。同样输入时也具有接续效果,使用变量去接收输入参数示例如下:

    int a,b;
    cin >> hex >> a >>b;

            cin是输入的函数,hex是以十六进制接收,a和b是去接收用户输入的两个变量,第一个输入参数放在a中,第二个放在b中,用户输入时数字间使用空格隔开,输入空格时cin认为是一个结束符号。如果输入了3个数字,由于没有接收变量,cin会把第3个数字丢了。

    c++库函数查询

    在c学习过程中我们经常使用man指令进行函数查询,而c++的库ubuntu并没有自带,需要我们自己进行安装,然而我们并不推荐使用man手册查询,因为c++的库比较复杂,在man手册中查询并不是很好用,我们推荐使用网络资源进行查询,如下网站。

    cppreference.com

    fstream读写文件

            file stream简称fstream,是c++中用来读写流式文件的一个类,功能与c中的fopen、fclos类似,实际上我们对文件的操作仍然离不开c中的操作函数,只不过c++进行了重新封装。fstream本质上是一个class,这个class中提供了一系列的文件操作函数。

    open函数

    • 功能:将名为 filename 的文件打开并与文件流关联。
    • 原型:void open( const char *filename, ios_base::openmode mode = ios_base::in );
    • 参数:filename -  要打开的文件名

                    mode  -     指定打开模式。它是位掩码类型,定义下列常量:

                    app 每次写入前寻位到流结尾

                    binary     以二进制模式打开

                    in    为读打开

                    out  为写打开,如果文件不存在自动创建

                    trunc      在打开时舍弃流的内容

                    ate  打开后立即寻位到流结尾

    • 返回值:无
    • 示例:fstream fs;
    fs.open(pach);   //打开文件

    is_open函数

    • 功能:检查文件流是否有关联文件,检查是否打开成功。
    • 原型:bool is_open(void);
    • 参数:无
    • 返回值:若文件流有关联文件,则为 true ,否则为 false
    • 示例:if(fs.is_open()==true)//打开成功

    close函数

    • 功能:关闭打开的文件
    • 原型:void close();
    • 参数:无
    • 返回值:无
    • 示例:fs.close();  //关闭文件

    read函数

    • 功能:读取文件
    • 原型:basic_istream& read( char_type* s, std::streamsize count );
    • 参数:   s      -     指向要存储字符到的字符数组的指针

                    count     -     要读取的字符数

    • 返回值:*this
    • 示例:char read_buff[20]={0};

    fs.read(read_buff,sizeof(read_buff));

    write函数

    • 功能:读取文件
    • 原型:std::basic_ostream<CharT,Traits>::write
    • 参数:s  -     指向要写入的字符串的指针

                    count  -     要写入的字符数返回值

    • 返回值:*this
    • 示例:
    • fs.write(write_buff,sizeof(write_buff));
      fs << "hello word" << endl;

    skeep函数

    • 功能:移动文件指针
    • 原型:seekp (int offset, int mode)
    • 参数:offset—基于mode的偏移量,可正可负。

                    mode—参考点,beg表示文件开始,end表示文件尾,cur表示指针的当前位置。

    • 返回值:
    • 示例:fs.seekp(0,fs.beg);//移动到文件头

    C++字符串

            c++字符串关键字string,是c++库中的一个类,该类是STL中basic_string模板实例化得到的一个模板类。在string这个类中有很多的成员函数,这些函数都是用来处理字符串的,我们每定义一个字符串对象如string s1,那么就可以基于对象来调用成员函数来操作s1,如s1.swap(s2),就是将s1与s2的内容进行交换。

    c++的字符串与c的字符串对比

            c语言严格的说是没有字符串的,我们之前用的准确的说应该叫字符数组、字符指针,有无字符串主要是看是否有字符串类型,如都有int类型,而c++或java是真的有字符串这个类型,而且为此还提供了很多关于字符串操作的函数。所以在我们c++开发的时候,要使用c++的字符串类型,而不是使用c中的字符数组。

    string函数构造

    string构造函数的方法有多种,如:

    • string s1   //看起来有点像是定义一个对象
      string s1()  //和上一个类似,但初值不同,初值为1;
      string s1(“hello word”)//在构造时赋值,类似于定义变量时赋初值。
      string s1(4,’x’)   //初值为4个字符X

    需要注意的是我们给初值时不能给初值为数字,如string s1(123);也不能给单个字符,如string(‘x’),编译时报错的数量会让你怀疑人生。起码会让你从疲惫中被吓清醒。

    string赋值

    赋值很简单,和c中对字符指针赋值类似,如下:

    string s1;
    s1 = “hello word”
    s1 = ‘h’

    获取字符串长度

            获取长度也是用string的成员函数length和size,值得注意的是size是内存空间大小,虽然每个字符默认占1个字节,实际上我们是可以通过成员函数去改变,所以length与size有时候输出结果相同,但有时候是不同的。语法:

    string s1(hell word);
    i=s3.length(); 
    y=s3.size();

    字符串拼接

            字符串的拼接很简单,可以直接使用+和+=,这种方法和两个变量求和很像,这都是c++的的封装和对运算符重载的结果,这种方式在c中简直都不可想象。没办法c++就是这么强大。

    string s1(“1234”);
    string s2(“789”);
    string s3
    s3 = s1 + s2;
    s1 +=s2;

    字符串比较

    字符串的比较也非常简单,直接像变量一样使用!=、==、等符号即可实现。

    string s1(“1234”);
    string s2(“789”);
    if(s1==s2)

    混合编程

            c有很多优秀且成熟的项目和库,丢了可惜,重写没必要,所以在c++中有时候需要调用c的代码,另外就是在一个非常庞大的项目中,如操作系统,他的底层很注重运行效率,应用层很注重开发效率,所以需要使用不同的语言进行混编。

            无论是c还是c++最终都会编译成.o文件,在.o文件中我们几乎无法通过对文件本身来判断源文件是c还是c++在.o文件中仅有一些符号和二进制可执行代码,所以链接的时候完全可以对他们进行相互组合,实际上两种语言的.o文件也并不是可以无缝链接的,c++支持函数名重载而c不支持,函数名重载其实就是函数名在.o文件中的表达不一样,c的.o中的函数名就是源文件的函数名,而c++的.o中的函数名是函数名后自动添加的传参类型的首字母,如void func(int a,int b),在c++的.o中的函数名称是funcii,所以在链接的时候链接不上。

            解决这个问题的关键就是要让c++编译后的变量名与c相同,在c++中为我们提供了extern “C”的机制,来告诉编译器,函数名使用c的规则来命名。示例如下:

    #ifdef __cplusplus   //该变量是c++编译器自动添加的
    extern “C”
    {
    #endif
    void func(void);     //函数声明
    # ifdef __cplusplus
    }
    #endif

            上例中只要在extern “C”的大括号内的函数声明,在c++编译器编译的时候,函数名都会按照c的标准来进行函数名重载,即中间函数名与源文件函数名相同。extern “C”是c++的语法,如果c的编译器去编译就会报错,为了提高我们的文件可移植性,即可以使用c编译器又可以使用c++编译器,所以使用了#ifdef,如果是c编译器编译,__cpluspls这个变量根本就没有所以extern根本就不会被编译进去,自然就不会报错。所以我们用c写标准程序时一定要添加extern “C”来保证我们程序的移植性。

    c静态库与c++源文件混编

            这种情况通常出现在供应商给我的是动态库或静态库是(含.a和.h)基于c的,如果供应商给我们的.h文件中没有添加extern “C”来兼容c++的编译,我们使用g++再次混编时,会把.o文件内的函数名重载,导致.h中的函数声明是错误的,我们去调用也会失败,解决方案是,我们可以在自己的c++源文件中包含供应商的头文件时添加extern“C”,当然也可以添加到对方的.h文件中,示例如下:

    extern “C”
    {
    include “xxx.h”
    }

    c++静态库与c源码混编

            这种情况同样也有可能是别人给你的库文件已经按c++的方式编译了,我们要在c中调用,首先的问题是我们不知道.hpp文件在.o中函数重载后的函数名称,所以我们无法调用,有一个投机的方法就是把.o文件反汇编,就可以看到函数名,然后在c中调用即可。

            然而这样做不正规,如果函数较多,我们需要一个一个的核对,容易出错。

            正规的解决方案是把.o库进行再次封装,写一个c++源文件,在文件中为.h中的每一个函数建一个别名函数,来调用库中的函数,这样我们就得到了库中每个函数的别名,再在我们新建的头文件中去添加extern “C”来使其按c标准进行函数重载,编译后得到另外一个库,我们的c程序就可去调用我们新建的库来实现间接调用源库函数。

    gcc man.c  -lpack -ltest  -L./cplus  //库中库的引用的顺序错误会出现链接失败,要先上
                                         //级库后 下级库,即被库调用的库应该排在后面。

     

    反编译方法

    linux下反编译在学习c的时候已讲过,然而我们视乎已经忘了,所以在此重提,步骤如下:

    gcc 1xxx -c -o 2xxx.o       //将1xxx只编译不链接,命名为2xxx.o
    objdump -d 2xxx.o > 3xxx.i  //将2xxx.o文件反编译成.i文件。

    .o文件内部全部是二进制,本身也带有符号信息,只是我们看不懂二进制,所以要使用反编译器将其转换成我们能看懂的格式。

    制作静态库与使用

    gcc 1xxx -c -o 2xxx.o    //将1xxx只编译不链接,后文件名命名为2xxx.o
    ar -r lib1xx.a  2xxx.o  //ar是工具链,-r静态库,lib1xxx.a库名,lib开头。
    g++  main.cpp  -l1xxx -L.  //-l指定库名,-L指定当前路径

    展开全文
  • C++ 中,我们有两种类型的: 静态 动态 静态 静态是成为引用它的可执行文件的一部分的。因此,当我们开发应用程序并引用其中的静态时,静态的内容在应用程序中被替换。 Windows 上的静态通常...
  • C++标准库

    2020-12-24 15:18:32
    C++标准库的所有头文件都没有扩展名。 http://cplusplus.com/reference/ C++标准库的内容总共在50个标准头文件中定义,其中18个提供了C的功能。<cname>形式的标准头文件【<complex>例外】其内容...
  • C++标准库的所有头文件及作用

    千次阅读 2020-12-26 11:54:55
    C++标准库的所有头文件都没有扩展名。C++标准库的内容总共在50个标准头文件中定义,其中18个提供了C的功能。 <cname>形式的标准头文件【 <complex>例外】其内容与ISO标准C包含的name.h头文件相同,但...
  • C++标准库》学习笔记 — STL — 国际化一、字符集 一、字符集 常用的字符集 utf-8 是 unicode 标准的一种实现方案。utf-8 支持带 BOM 的版本。其为 byte order mark 的缩写,用以标识它所使用的是 big-endian 或 ...
  • 一、C++书籍推荐之手册类(适用所有级别) 1、C++程序设计语言(The C++ Programming Language) (更新到C++11) 作者:Bjarne Stroustrup,C++ 之父写的经典 C++ 书籍,内容覆盖C++的...2、C++标准程序库(C++ Stand.
  • 在新标准出现之前,C 和 C++ 都依赖于一个简单的 C 函数 rand 来生成随机数。此函数生成均匀分布的伪随机整数, 每个随机数的范围在 0 和一个系统相关的最大值(至少为 32767) 之间 rand 函数有一些问题: 很多...
  • Eclipse CDT功能很强大,安装完虽然可以编译运行c++程序,但有个问题,就是找不到c++标准库的头文件,无法打开诸如之类的文件,编译器警告如下:显示Unresolved inclusion:尽管不影响编译,却无法定位头文件中的符号...
  • C++标准模板记录

    2021-05-16 19:25:15
    C++标准模板记录 1.#include vector的数据安排以及操作方式,与array非常相似,两者的唯一差别在于空间的运用的灵活性… 2.#include 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是...
  • C++ 标准模板STL

    2021-08-09 15:59:33
    C++ 标准模板的核心包括以下三个组件: 组件 描述 容器(Containers) 容器是用来管理某一类对象的集合。C++ 提供了各种不同类型的容器,比如 deque、list、vector、map 等。 算法(Algorithms) ...
  • C++ 标准库の使用迷思

    2021-01-02 17:35:02
    转眼 2020 已经过去,回顾来看总有些迷幻,新年之际,自己倒不打算写些什么年终总结,想想还是记一小篇技术小文: C++ 标准库的使用迷思. 了解 C++ 的朋友对于标准模板肯定不陌生,平日用 C++ 开发时基本也是离不开标准...
  • C++ 标准模板 STL 关联容器

    千次阅读 2021-08-29 17:07:55
    C++ 标准模板 STL 关联容器 容器 数据结构 时间复杂度 顺序性 重复性 set 红黑树 插入、删除、查找 O(log2n) 有序 不可重复 multiset 红黑树 插入、删除、查找 O(log2n) 有序 可重复 map 红黑树 插入...
  • Boost是一个优秀的、可移植、开源的C++,它由C++标准委员会工作组成员发起,其中有些内容经常成为下一代C++标准库内容,在C++社区中影响甚大,是不折不扣的“准”标准。 Boost是一个开源免费的第三方,...
  • 2. C++对C的兼容性 3. C++库的简单介绍 4.最后 1.C语言和C++的关系 C++是C语言的一个超集,也就是说C语言有的,C++都有,而C++有的,C语言未必就有。 同时,g++能编译C++文件,同样也能编译C语言文件。 C...
  • C++标准模板&容器

    2021-06-03 10:00:07
    STL(Standard Template Library ,标准模板)是一套功能强大的C++类模板,它提供了通用的类模板和模板函数,可以实现多种常用算法和数据结构,如:向量,链表,
  • c++ primer》12.1.1章节 1、智能指针是为了更加安全(防止内存还被引用着就被释放)和方便(不必自己手动释放内存)地使用动态内存(静态内存和栈内存中的对象由编译器创建和销毁,动态内存由程序创建和销毁)而...
  • C标准&C++标准

    2021-03-27 21:50:27
    C: ISO/IEC 9899 C++: ISO/IEC 14882
  • C++语言之父的经典名著之最新版本,全面掌握标准C++11及其编程技术的权威指南!第1版1985年,第2版1991年,第3版1997年,特别版2000年,第4版2013年,经典无限延伸……C++程序设计语言(原书第4版)是在C++语言和程序...
  • 初探C++标准库

    2021-09-01 13:38:41
    初探C++标准库 3.1 C++标准环境的组成 3.2 C++的头文件 C++是在C语言的基础上开发的,早期的C++还不完善,不支持命名空间,没有自己的编译器,而是将C++代码翻译成C代码,再通过C编译器完成编译。这个时候的C++...
  • C++ 标准模板 STL 容器适配器

    千次阅读 2021-08-30 11:16:02
    C++ 标准模板 STL 容器适配器 容器 数据结构 时间复杂度 顺序性 重复性 stack deque / list 顶部插入、顶部删除 O(1) 无序 可重复 queue deque / list 尾部插入、头部删除 O(1) 无序 可重复 priority_...
  • C++ STL(标准模板)是一套功能强大的 C++ 模板类,提供了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如向量、链表、队列、栈。 C++ 标准模板的核心包括以下三个组件: ...
  • C++程序设计第二章

    2021-07-18 17:08:31
    C++程序设计第二章 C++简单程序设计 C++的基本数据类型 整数类型 实数类型 字符类型 布尔类型 C++的基本运算 算术运算 逻辑运算 程序要能输入数据,输出数据 C++的输入输出可以调用预定义的功能模块实现 程序的...
  • 2、基本数据类型,常量、变量和表达式3、C++标准输入输出【单选题】1、在C++中,源程序变为可执行程序的正确顺序应该是( ) 。A. 编辑、链接、编译、执行 B. 编辑、编译、链接、执行C. 编译、编辑、链接、执行D. ...
  • C++标准库中 ios_base 的用法

    千次阅读 2021-02-10 14:29:19
    ios_base 是C++标准程序库中的一个类,定义于头文件中。ios_base类封装了C++标准中的流输入输出中不依赖于读写的数据的类型的基本信息,如格式化信息、异常状态、事件回调函数等。 C++程序设计时,一般不会直接调用...
  • 目 录第 1章 C++语言概述 11.1 面向对象的概念 11.1.1 面向对象方法的由来 11.1.2 面向对象的基本概念 21.2 C++语言的特点 31.2.1 C++语言是面向对象的程序设计语言 31.2.2 C++语言继承了C语言 ...
  • C++封装zlib

    万次阅读 多人点赞 2021-01-20 21:23:19
    C++对zlib进行简单封装什么是zlib如何下载zlib源代码如何安装zlib合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容...
  • CRT与Windows API和C\C++的关系 ...后来在此基础上开发了C++ Runtime Library,所以现在CRT是指Microsoft开发的C/C++ Runtime Library。在VC的CRT/SRC目录下,可以看到CRT的源码,不仅有C的,也有C++的。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 253,124
精华内容 101,249
关键字:

c++标准程序库

c++ 订阅