3-字符串向量和数组

字符串向量和数组
  • using的使用说明

    • ::表示作用域限定符号,可以使用using namespace::name来统一使用命名空间;

      using namespace std;
      using std::cout;
      using std::cin;
    • 也可以通过using std::out这样的方式在,需要使用的时候进行使用,这样使用的话,每个using都需要引入一条声明;

    • 在自己声明的头文件里面,一般是不能够包含using声明的,防止和主文件里面命名空间发生冲突;
  • string对象的简单使用
    • 定义和初始化string对象string s1; string s2 = s1; string s3("hello"); string s4(10,'c');
    • 对于上面的初始化类型:如果使用=进行的是拷贝初始化,不使用=进行的是直接初始化操作;
    • 常用的操作:
      • 读入数据 string s; cin >> s;;在输入的过程中,会自动忽略开头的空白字符,但是不会忽略字符中间的空白字符,同时,
        支持cin >> s1 >> s2;;这种一次输入多个字符的操作;
      • 使用getline()来读取一行getline(cin,string line),函数的返回值是读取的字符长度;在字符输出的过程时,需要
        手动的加上换行符;因为读入line里面的不包含换行符号;
      • empty根据string对象是否为空,返回一个对应的bool值;
      • size用于返回字符串的长度;
      • size_type类型,是一个无符号类型的值,用于存放任何大小的,所以需要注意的是unsignedint是不能够进行比较
      • == and !=:用于判断字符串是否相等.严格区分大小写,严格按照字典序进行比较;
      • + 表示就是将字符串进行拼接,s1 + s2,同样的也支持字面值常量和string对象相加,但是两个字面值是没有办法
        相加的"hello"+"," 这种表示就是错误的
      • 切记字符串字面值和string是不同的类型;
  • 关于字符串处理的一些函数:

    函数名功能
    isalnum(c)表示c是字母或者是数字
    isalpha(c)表示c是字母
    iscntrl(c)是控制字符为真
    isdigit(c)表示是数字
    isgraph(c)表示不是空格但是可以打印
    islower(c)表示是小写字母
    isprint(c)表示是可打印字符
    ispunct(c)表示是标点符号
    ispace(c)表示是空白字符
    isupper(c)表示是大写字母
    isxdigit(c)表示是16进制数字
    tolower(c)如果是大写字母,输出相应的小写
    toupper(c)表示如果是小写字母,输出相应的大写
  • C++11支持的一种新的写法:

    for(declaration : expression){
            statement;
    }
  • 1.expression 表示的含义是一个对象,或者是一个队列;declaration用于定义一个变量,这个变量用于访问序列中的基础元素,每次进行迭代,这个元素的值,都会被初始化为下一个元素的值,如果希望改变对象中单个元素的值,就需要使用引用操作;

  • 2.同时也是可以使用下标运算符来访问string对象里面的元素的,需要严格保证下标不越界,如果使用下进行访问,首先应该确定对象是否为空s.empty()操作;
  • toupper.cpp;
#include<iostream>
#include <vector>
using namespace std;

int main(){
    vector<string> mystring{"Hello","world","this","is","a","freshman"};
    for(auto h:mystring){
        for(auto &m:h){
            m=toupper(m);
        }
        cout << h << " ";
    }
}
  • 对于string支持的常见操作就不赘述了;
标准库类型<vector>
  • <vector>:在C++语言中包含类模板和函数模板,<vector>表示的是类模板,模板本身并不是类或者函数,模板更像是一种说明,实例化表示的是编译器根据模板创建类或者函数的过程,也就是在使用模板时,需要声明模板的类型;例如vector<int> myvector;
  • <vector>支持大多数类型作为模板参数,但是引用不属于具体类型,所以引用不能够作为模板参数;
  • <vector> 作为模板参数<vector><vector><int>>这种那个情况也是支持的;
  • vector可以容纳大多数对象作为其模板参数,但是引用不是对象,所以不能够用作实例化,内置类型(除了引用)以及类类型,vector类型都是可以的;
int lk=10;
int rlk=lk;
//这种就是错误的;
vector<rlk> myvectorrlk;
  • 定义和初始化<vector>的方法

    方法含义
    vector<T> v1表示执行默认初始化
    vector<T> V2(V1)v2里面包含v1的所有副本
    vector<T> v2 = v1表示执行拷贝构造函数
    vector<T> V3(n,va1)等价于v2(v1),v2中包含所有v1的副本
    vector<T> V4(n)表示执行n个元素的初始化
    vector<T> V5(a,b,c,...)表示每个元素被付给相应的初始值
    vector<T> V5=(a,b,c,...)等价于前者
  • 关于初始化的几种例外情况

    • 1.在使用拷贝初始化时,只能够提供一个初始值;
    • 2.如果提供的是一个类里面的初始值,只能够使用拷贝初始化和{}形式的列表初始化;
    • 3.如果提供的是初始元素的列表,只能够在{}里面进行初始化;
    • {}()的区别:
    • ()里面的值只有一个时,用于说明元素的数量,里面的值有两个时,用于指定元素的数量和初始值;

      //表示mystring里面包含十个元素,但是不建议这样使用;
      vectro<string> mystring(10);
      //包含两个元素时,用于指定元素的数量以及元素;
      vector<string> mystring(10,"YCM");
    • {}里面的用于指定元素的初始值;

    • 特殊情况:
      • {}:首先执行的是列表初始化,如果无法执行,比如vector<string> V7{10},就会执行string V7个数的限定;
      • 这种情况编译器是允许的,但是不建议这样使用;
  • <vector>push_back()操作

    • push _back()操作的含义就是将元素放在当前数组的尾部;通畅不建议在开始就指定<vector>的大小,而是让其根据需要自己增长;
    • 使用下标操作可以访问已经存在的元素,但使不能够用于添加新的元素;尽可能使用范围for语句来避免循环超出范围;
    操作表示的含义
    v.empty()如果里面不包含任何元素返回真,否则翻回假
    v.size()返回里面元素的个数
    v.push_back()向当前的末尾添加一个元素
    v[n]返回v中第n个元素位置的引用
    v1 = v2进行元素的覆盖操作
    v1 == v2按照字典序判断是否相等
  • vector<>对于下标索引的操作和string<>类型是相同的;

  • vector<>,如果里面不包含任何的元素,那么是不能够使用下标索引来访问或者添加元素的,但是可以使用.push_back方法;
  • 对于vector来说,如果有向里面添加元素的语句,就不应该使用for循环,这里的for循环表示的是for(auto h:vector),这样的形式,但是还是可以使用范围for,通过改变保存的end的值来进行添加元素的;
迭代器
  • 所有的标准库容器都支持迭代器操作,但是并不都支持下标操作;
  • 迭代器可以从一个元素移动到另一个元素,有效的迭代器指向某一个元素;
  • 迭代器拥有.begin().end()成员分别用于指向第一个元素和最后一个元素的的下一个位置;
  • 如果迭代器为空,那么返回的就是同一个迭代器,都是尾迭代器;
  • 迭代器运算符
运算符含义
*iter用于返回迭代器iter元素的引用
iter->men解引用,并得到成员men
iter1 == iter2用于判断两个迭代器是否相等
  • 迭代器的操作比较适合于for循环来完成,例如for(auto iter=s.begin();iter != s.end();iter++);
  • 标准库提供了两种类型iteratorconst_iterator,前者用于表示可读写对象里面的元素,后者表示只能够访问,不能够操作;
  • 迭代器的类型是由beginend进行返回的,const vector<int>,那么迭代器的返回类型就是const_iterator否则就是前者,这是编译器的默认行为;
  • C++11提供了.cbegin()函数和.cend()来提供const_itertor,只读功能;
  • 如果使用了迭代器,就不能给迭代器所属的容器添加元素(很重要);
  • 迭代器支持常用的算数操作;
  • .end()-.begin()得到就是元素的个数,得到的结果的类型是difference_type

  • 使用迭代器实现的二分查找的例子

auto beg = text.begin(),end = text.end();
auto mid = (text.begin()+text.end())/2;
while(mid != end && *mid != sought){
    if(sought < *mid){
        end = mid;
    }
    else {
        beg = mid +1;
    }
    mid = beg + (end - mid)/2;
}
数组
  • 数组在申请大小之后是不能够改变的,不能够随意的向数组中添加超过数组容量的元素;
  • 如果无法确定元素的个数,请使用数组;
  • 对于复杂的数组声明,没有()按照从右往左的顺序,如果有() ,应该按照从内往外的顺序进行分析,例如int *(&arry)[10],首先来说&arry表示这是一个引用,和下标运算符结合,就是一个包含10个元素的数组的引用,根据类型运算符,这是指针类型,这个声明的含义就是包含10个int型指针的数组的引用;
  • 数组元素的访问可以使用for语句结合下标运算符来,数组下表应该定义为size_t类型,而不是int类型;书上推荐使用for(auto i:score),这样的方法来访问数组元素,避免出错;
  • 数组的下标越界检查,仍然是程序员不应该违反的准则;
  • 对于数组里面元素的访问也是可以使用

    for(auto &h:arryname){
    do_something;
    }
数组和指针
  • 数组名表示的就是数组元素的首地址,对于数组中的其他元素可以使用&运算符得到地址;
  • 在很多时候需要使用数组名的地方,编译器都会替换成为数组的地址;
  • 当时用auto ia2(数组名),auto的类型实际上是一个数组指针,默认是进行了转换的,所以ia2是不能够进行整型赋值的;
  • decltype,进行变量的声明得到的将是一个和数组,并且和已知的数组由相同个数的元素;
  • C++11对于数组的下标操作引入了两个函数,begin()和end(),使用数组名作为参数,用来获得首地址和尾地址;
  • 对于数组最后一个元素的下一个指针,是不能够进行自操作,也不能够进行解引用操作;
  • 指针相减的类型是一种ptrdiff_t的标准库类型,包含在头文件<cstddef>里面;
  • 两个指针进行比较的前提是必须指向同一个对象;
  • 标准库限定了使用的下标运算符必须是无符号类型,内置的下标运算符是可以处理负值的,但是前提是处理后的结果仍然在数组表示的范围里面(包括尾元素的下一个位置);
  • string的对象支持算数运算符的比较,但是C里面的字符串数组是不支持的,通常需要使用C语言提供的函数来进行比较;
  • 通常来说任何出现字符串字面值的地方都可以使用空字符结束的字符串数组来替代;
  • 允许使用以空字符结束的字符数组来初始化string对象,或者为string对象赋值;
  • string对象的加法中,允许使用以空字符结束的字符数组作为其中一个运算对象,但是不能两个都是字符数组;`
  • 如果需要通过string对象来初始化字符数组,就需要使用函数.c_str();
数组和vector对象
  • 不能够通过vector对象来初始化数组,但是可以通过数组来初始化vector对象; vector<int> ivec(begin(int_arr),end(int_arr));
  • 多维数组

    • 多维数组其实就是数组的数组,前者用于表示数组的元素,后者用于表示数组每个元素里面有多少个元素;
    • 如果需要改变多维数组里面的值,那么每层循环都需要使用&操作;
    • 如果仅仅是需要遍历多维数组,那么除了最内层循环之外,其余的需要使用&操作,是为了防止最内层之外的转换成指针,对指针进行遍历,没有价值;
    • 对于指针来说也可以是迭代器;
    int arr[]={1,2,3,4,5,6,7,8,9};
    int *parr = arr;
    int i=0;
    for(parr;i<sizeof(arr)/sizeof(arr[0]);++i){
        do_something;
        parr++;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值