2017-5-9 C++笔记

c++primer笔记

加入光荣的进化吧


vector容器

  • vector的初始化
    • 引用不可以成为vector的元素,因为其不是对象。(vector的元素只能是对象。)
      • 对象:分配了空间、 并且有数据类型。
    • 可以用==花括号==初始化每一个值
    • 可以用==括号== 指定元素的个数或相同的元素值
    • 只能直接初始化,不能拷贝初始化。(++vector之间可以互相拷贝,但类型要一致++)(++类型即为定义vector时<>中的内容++);
    • vector v1 (==数量==,==内容==); //圆括号
    • vector v3{==内容==,==内容==,==内容==}; //花括号
    • vector v2 {==数量==,==“内容”==};//花括号
  • vector添加元素

    • C++中,一般在初始化的时候不会设置vector的大小,而是在之后使用中随用随加。
               vector<int> v2;  
        for(int i=0;i != 100;++i)
              v2.push_back(i);

  • ==while(cin>>s)== :一直循环到输入结束

  • toupper(s) 字符s如果为小写 则转换为大写。若不是字母,则不变!
  • isspace(s) 字符s若为空格,则返回1 否则返回0


  • vector操作:

    • v.empty()
    • v.size()
    • v.push_back()
    • v1=v2
    • v1={1,2,3,4,5,6…};
    • v1==v2
    • v1 != v20
  • vector只有使用时才会分配空间,所以不能通过下标给一个空vector赋值。
  • 确保下标合法的有效手段: ==尽可能使用范围for语句==

  • 迭代器iterator

    • v.begin() v.end();
    • auwo b=v.begin(); quto c=v.end();
    • begin为指向第一个元素的迭代器。 end为指向最后一个元素==下一位==的迭代器。
      • v.end()所指向的元素其实没有实际意义,被称为++尾后迭代器++,大多数情况用 if(v.begin==v.end) 判断迭代器是否为空。
    • 指令:
      • *iter :返回迭代器iter所指元素的引用》
      • iter->men :解引用iter 并获取该元素的名为men的成员。 相当于 (*iter).mem
      • ++iter –iter :令iter指示容器的下/上 一个元素。
    • 数据类型:
      • vector::iterator it;
      • string::iterator it2;
      • vector::const_iterator it3;
      • string::const_iterator it4;
      • 如果vector或者string的对象是常量,则只能使用 const_iterator, 若不是常量,则既可以使用iterator 也可以使用const_iterator

iterator和指针的区别

> 1.指针和iterator都支持与整数进行+,-运算,而且其含义都是从当前 位置向前或者向后移动n个位置  
> 2.指针和iterator都支持减法运算,指针-指针得到的是两个指针之间的 距离,迭代器-迭代器得到的是两个迭代器之间的距离  
> 3.通过指针或者iterator都能够修改其指向的元素  

通过上面这几点看,两者真的很像,但是两者也有着下面的几个不同地方

1.cout操作符可以直接输出指针的值,但是对迭代器进行在操作的时候会报错。通过看报错信息和头文件知道,迭代器返回的是对象引用而不是对象的值,所以cout只能输出迭代器使用*取值后的值而不能直接输出其自身。
2.指针能指向函数而迭代器不行,迭代器只能指向容器
这就说明了迭代器和指针其实是完全不一样的概念来的。指针是一种特殊的变量,它专门用来存放另一变量的地址,而迭代器只是参考了指针的特性进行设计的一种STL接口。
笔者曾在网上看到这样一种说法:迭代器是广义指针,而指针满足所有迭代器要求。迭代器是STL算法的接口,而指针是迭代器,因此STL算法可以使用指针来对基于指针的非STL容器进行操作。
笔者觉得上面说法也有几分道理,但是到底正不正确就留给看官自己判断了。但是有一点希望大家注意的是:千万不要把指针和迭代器搞混了。也许某些编译器使用指针来实现迭代器以至于有些人会误以为指针和迭代器是一个概念来的。


  • c++11新加了 cbegin 和cend 指令, 类似于v.begin 但是他们的返回值一律为const_iterator

  • 箭头运算符 ->

    • 把解引用和成员访问两个操作结合。
    • it->men 相当于 (*it).men
  • 某些vector对象的操作会导致迭代器失效
    • ==凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素==
    • 任何一种改变vector对象容量的操作 如push_back,都会使该对象的迭代器失效。
  • 使用迭代器时! 千万要记得《解引用》 (在迭代器前加*)!
  • 向量初始化后,再使用push_back 就是在那些数后面再插入一些东西。。


  • 迭代器运算
      -
  • 大概 好像只是对vector和string的迭代器提供了更多的运算符!
    • iter + n ; iter -n; 向前、向后移动若干==元素==
    • iter1+=n; iter1-=n;
    • iter1-iter2 右侧迭代器==向前==移动==差值==个元素后得到左侧的迭代器
      • 例如 auto mid= vi.begin() + vi.size()/2;
      • 假设vi中有20个元素 则 *mid 代表的就是vi[10]; (可以用来进行二分排序?)
    • 两个迭代器相减的结果可正可负, 数据类型是 ==difference_type== 代表右侧迭代器向前移动多少位置就能追上左侧的迭代器。
///二分搜索
    auto beg=text.begin(), end=text.end();
    auto mid=text.begin()+(end-beg)/2;
    while(mid != end && *mid!=sought){
    if(sought < *mid)
        end = mid;
    else 
        beg = mid + 1;
    mid=beg + (end - beg)/2;
} 
  • 二分搜索的两种表达方式

    • mid=(end+beg)/2;
    • mid=beg+(end-beg)/2;
    • 第一种会产生大于end的数值,可能溢出。 第二种算得满?噗
    • 尽量使用第二种。
  • 迭代器 ==*king++== 为错

    • 写成 (*king)++ 或者 ++(*king)

END

发布了29 篇原创文章 · 获赞 3 · 访问量 7160

猜你喜欢

转载自blog.csdn.net/liu432linux/article/details/71512771