C++ primer学习笔记 第三章 字符串、向量和数组

using声明

  • 使用某个命名空间:例如 using std::cin表示使用命名空间std中的名字cin
  • 头文件中不应该包含using声明。

string

  • 标准库类型string表示可变长的字符序列。
  • #include ,然后 using std::string;
  • string对象:注意,不同于字符串字面值。
  • s.emtpy()是否为空;
  • s.size()尺寸;
  • string::size_type定义了size的类型;
  • +:字符串连接;
  • str[i] 可以作为左值。
  • getline(is, s) 从is中读取一行赋给s,返回is
  • <, <=, >, >= 利用字符在字典中的顺序进行比较,对大小写敏感。
  • string io:
    • 执行读操作:忽略掉开头的空白(包括空格、换行符和制表符),直到遇到下一处空白为止。
    • getline:读取一整行,包括空白符。
  • 字符串字面值和string是不同的类型。
  • 遍历字符串:使用范围for(range for)语句: for (auto c: str),或者 for (auto &c: str)使用引用直接改变字符串中的字符。
  • ctype.h vs. cctype:C++修改了c的标准库,名称为去掉“.h”,前面加“c”。

对象初始化

  • 初始化string
    • 默认初始化:string s1; 是一个空字符串。
    • 拷贝初始化:string s1 = s2; s1s2的副本。
    • 直接初始化:
      • string s1 = "value";等价于 string s1("value");
      • string s1(n, 'c');初始化为n个'c'字符组成的字符串。
  • 拷贝初始化:使用等号=初始化一个变量,编译器把等号右侧的初始值拷贝到新创建的对象中去。
  • 直接初始化:不使用等号,显式地传入值自己初始化。

vector(存放任意类型的动态数组,能够增加和压缩数据

  • vector是一个容器,也是一个类模板;
  • #include  然后 using std::vector;
  • 容器:包含其他对象。
  • 类模板:本身不是类,但可以实例化instantiation出一个类。 vector是一个模板, vector是一个类型。
  • 通过将类型放在类模板名称后面的尖括号中来指定类型,如vector ivec
  • 列表初始化: vector v = {"a", "an", "the"} (C++11)
  • v.push_back(e) 在尾部增加元素。
  • 范围for语句内不应该改变其遍历序列的大小。
  • 下标操作v[i],只能对确知已存在的元素执行下标操作。
  • v.emtpy() 是否为空。
  • v.size() 尺寸。

迭代器iterator

  • vector::iterator iter
  • v.begin();返回指向第一个元素的迭代器;
  • v.end();返回指向最后一个元素的下一个(哨兵,尾后)的迭代器;
  • 如果容器为空, begin()和 end()返回的是同一个迭代器,都是尾后迭代器。
  • 使用解引用符*访问迭代器指向的元素。
  • 养成使用迭代器和!=的习惯(泛型编程)。
  • 容器:可以包含其他对象;但所有的对象必须类型相同。
  • 迭代器(iterator):每种标准容器都有自己的迭代器。C++倾向于用迭代器而不是下标遍历元素。
  • const_iterator:只能读取容器内元素不能改变。
  • 箭头运算符: 解引用+成员访问,it->mem等价于 (*it).mem
  • difference_type:保证足够大以存储任何两个迭代器对象间的距离,可正可负。

标准容器迭代器的运算符

运算符 解释
*iter 返回迭代器iter所指向的元素的引用
iter->mem 等价于(*iter).mem
++iter iter指示容器中的下一个元素
--iter iter指示容器中的上一个元素
iter1 == iter2 判断两个迭代器是否相等

数组

  • 相当于vector的低级版,长度固定。
  • 初始化:char input_buffer[buffer_size];,长度必须是const表达式,或者不写,让编译器自己推断。
  • 数组不允许直接赋值给另一个数组。
  • 数组下标的类型:size_t 。
  • 字符数组的特殊性:结尾处有一个空字符,如 char a[] = "hello"; 。
  • 用数组初始化 vector: int a[] = {1,2,3,4,5}; vector v(begin(a), end(a)); 。

数组和指针

  • 使用数组时,编译器一般会把它转换成指针。
  • 标准库类型限定使用的下标必须是无符号类型,而内置的下标可以处理负值。
  • 指针访问数组:在表达式中使用数组名时,名字会自动转换成指向数组的第一个元素的指针。

C风格字符串

  • 从C继承来的字符串。
  • 用空字符结束('\0')。
  •  : strlen(p)、 strcmp(p1, p2) 、 strcat(p1, p2) 、 strcpy(p1, p2) 。
  • 对大多数应用来说,使用标准库 string比使用C风格字符串更安全、更高效。
  • 获取 string 中的 cstring : const char *str = s.c_str(); 。

多维数组

  • 多维数组的初始化: int ia[3][4] = {{0,1,2,3}, ...}
  • 使用范围for语句时,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型。

指针vs引用

  • 引用总是指向某个对象,定义引用时没有初始化是错的。
  • 给引用赋值,修改的是该引用所关联的对象的值,而不是让引用和另一个对象相关联。

动态数组

  • 使用 new和 delete表达和c中mallocfree类似的功能,即在堆(自由存储区)中分配存储空间。
  • 定义: int *pia = new int[10]; 10可以被一个变量替代。
  • 释放: delete [] pia;,注意不要忘记[]

 

你可能感兴趣的:(C++学习笔记)