C++ primer学习笔记 第三章 字符串、向量和数组
using声明
- 使用某个命名空间:例如
using std::cin
表示使用命名空间std
中的名字cin
。 - 头文件中不应该包含
using
声明。
string
- 标准库类型string表示可变长的字符序列。
#include <string>
,然后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;
s1
是s2
的副本。 直接初始化:
string s1 = "value";
等价于string s1("value");
。string s1(n, 'c');
初始化为n个’c’字符组成的字符串。
- 默认初始化:
- 拷贝初始化:使用等号
=
初始化一个变量,编译器把等号右侧的初始值拷贝到新创建的对象中去。 - 直接初始化:不使用等号,显式地传入值自己初始化。
vector(存放任意类型的动态数组,能够增加和压缩数据)
- vector是一个容器,也是一个类模板;
#include <vector>
然后using std::vector;
- 容器:包含其他对象。
- 类模板:本身不是类,但可以实例化instantiation出一个类。
vector
是一个模板,vector<int>
是一个类型。 - 通过将类型放在类模板名称后面的尖括号中来指定类型,如
vector<int> ivec
。 - 列表初始化:
vector<string> v = {"a", "an", "the"}
(C++11) v.push_back(e)
在尾部增加元素。- 范围for语句内不应该改变其遍历序列的大小。
- 下标操作
v[i]
,只能对确知已存在的元素执行下标操作。 v.emtpy()
是否为空。v.size()
尺寸。
迭代器iterator
vector<int>::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<int> v(begin(a), end(a));
。
数组和指针
- 使用数组时,编译器一般会把它转换成指针。
- 标准库类型限定使用的下标必须是无符号类型,而内置的下标可以处理负值。
- 指针访问数组:在表达式中使用数组名时,名字会自动转换成指向数组的第一个元素的指针。
C风格字符串
- 从C继承来的字符串。
- 用空字符结束(’\0’)。
<cstring>
: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中malloc
和free
类似的功能,即在堆(自由存储区)中分配存储空间。 - 定义:
int *pia = new int[10];
10可以被一个变量替代。 - 释放:
delete [] pia;
,注意不要忘记[]
。
还没有评论,来说两句吧...