[C++ Primer] 第3章: 字符串, 向量和数组

标准库类型string

string初始化

string s2(s1);
string s2 = s1;
string s3("value");
string s3 = "value";
string s4(n, 'c');  // n个连续的c组成的字符串

读写string对象
读写未知数量的string对象

int main()
{
    string word;
    while(cin >> word)
        cout << word << endl;
    return 0;
}

使用getline读取一整行

int main()
{
    string line;
    while(getline(cin, line)) // line不含换行符, 第二个参数必须是string类型
        cout << line << endl;
    return 0;
}

size()返回类型为string::size_type, 推荐使用auto或者decltype推断变量的类型

auto len = line.size();
decltype(line.size()) len;

处理string中的字符
cctype头文件中的函数

函数说明
isalnum(int c)测试字符是否为英文或数字,在标准c中相当于使用isalpha(c)或 isdigit(c)
isalpha(int c)检查参数c是否为英文字母 ,在标准c中相当于使用isupper(c)或islower(c)
isascii(int c)检查参数c是否为ASCII码字符,也就是判断c的范围是否在0到127之间。
iscntrl(int c)检查参数c是否为ASCII控制码,也就是判断c的范围是否在0到30之间。
isdigit(int c)检查参数c是否为阿拉伯数字0到9。
isgraph(int c)检查参数c是否为可打印字符,若c所对映的ASCII码可打印,且非空格字符则返回TRUE。
islower(int c)检查参数c是否为小写英文字母。
isprint(int c)检查参数c是否为可打印字符,若c所对映的ASCII码可打印,其中包含空格字符,则返回TRUE。
isspace(int c)检查参数c是否为空格字符,也就是判断是否为空格('')、定位字符('\t')、CR('\r')、换行('\n')、垂直定位字符('\v')或翻页('\f')的情况。
ispunct(int c)检查参数c是否为标点符号或特殊符号。返回TRUE也就是代表参数c为非空格、非数字和非英文字母。
isupper(int c)检查参数c是否为大写英文字母。
isxdigit(int c)检查参数c是否为16进制数字,只要c为下列其中一个情况则返回TRUE。16进制数字:0123456789ABCDEF。
tolower(int c)如果c是大写字母则转成小写, 否则原样输出c
toupper(int c)如果c是小写字母则转成大写, 否则原样输出c

使用范围for循环处理每个字符

string s("Hello World!");
for(auto &c : s)
    c = toupper(c);  // c是一个引用, 因此赋值语句可以改变s中字符的值, 若无需改变s中的字符可以不使用引用
cout << s << endl;

注意: 当对字符串s使用下标操作单个字符时, 一般需要先判断s.empty()

标准库类型vector

定义和初始化

vector<T> v1;
vector<T> v2 = v1;
vector<T> v2(v1);
vector<T> v3(n, val); // 创建制定数量的元素, 包含n个重复元素, 每个元素的值都为val
vector<T> v4(n);      // 包含n个重复的执行值初始化, 内置类型如int初始化为0
vector<T> v5{a, b, c};// C++11支持
vector<T> v5 = {a, b, c};

重要操作

v.empty()
v.size()  // 返回类型为 std::vector<T>::size_type
v.push_back()
v1 = v2;  // 用v2元素拷贝替换v1中元素
v1 = {a, b, c...}; // 用列表中元素拷贝替换v1中元素
v1 == v2; v1 != v2; // 其他逻辑运算符同理

注意: 只能对已存在的元素执行下标操作, 尽量使用范围for循环可以有效确保下标合法

迭代器介绍

所有标准库容器都可以使用迭代器(string对象不属于容器类型, 但也支持迭代器). 通过begin和end成员获取迭代器.
标准容器迭代器的运算符

*iter           // 解引用, 返回迭代器所指元素的引用
iter->mem       // 等价(*iter).mem
++iter
--iter
iter1 == iter2
iter1 != iter2

所有标准库容器的迭代器都定义了==和!=, 但是他们中的大多数都没有定义<运算符. 因此要养成使用迭代器和!=的习惯, 就不用太在意用的到底是那种容器.
迭代器类型: 使用iterator和const_iterator表示迭代器类型

vector<int>::iterator it;        // 可读写
string::iterator it2;
vector<int>::const_iterator it3; // 只读
string::const_iterator it4;

若对象是常量, 则begin和end返回const_iterator, 否则返回iterator. 无论对象本身是否是常量, cbegin和cend都返回const_iterator.
注意: 凡是使用了迭代器的循环体, 都不要向迭代器所属的容器添加元素.
vector和string迭代器额外支持的运算符

iter + n, iter - n
iter += n, iter -= n
iter1 - iter2  // 类型为difference_type的带符号整数
>, >=, <, <=

数组

使用数据下标的时候, 通常将其定义为size_t类型. size_t类型是一种与机器相关的如符号类型, 它被设计的足够大以便能表示内存中任意对象的大小. 在cstddef头文件中定义了size_t类型.
指针也是迭代器
vector和string的迭代器支持的运算, 数组的指针全都支持, 为了获取尾后指针, C++11新标准引入两个名为begin和end的函数, 这两个函数与容器中的两个同名函数类似. 这两个函数定义在 iterator头文件中.

int ia[] = {1, 2, 3, 4};
int *beg = begin(ia);   // 首元素的指针
int *end = end(ia);     // 尾后元素指针, 不能执行解引用和递增操作
auto n = end(ia) - begin(ia); // 数组ia中的元素数量, n的类型为ptrdiff_t带符号类型, 该类型定义在头文件cstddef头文件中.

C风格字符串
C标准库String函数, 定义在ctring头文件中

strlen(p)       // 返回p的长度, 不含'\n'
strcmp(p1, p2)  // 比较p1, p2相等性, ==返回0, < 返回负值, > 返回正值
strcat(p1, p2)  // 将p2附加到p1之后, 返回p1
strcpy(p1, p2)  // 将p2拷贝给p1, 返回p1

混用string对象和C风格字符串

string s("Hello World");
const char *str = s.c_str(); // 如果后续操作改变了s, 可能导致str失效, 如果执行完c_str()函数后程序想一直使用返回的数组, 最好将该数组重新拷贝一份.

使用数组初始化vector对象

int iarr[] = {1, 2, 3, 4};
vector<int> ivec(begin(iarr), end(iarr));
vector<int> subVec(iarr + 1, iarr + 3); // 拷贝iarr[1], iarr[2]

多维数组

使用范围for循环处理多维数组, 除了最内层的循环外, 其他所有循环的控制变量都应该是引用类型.

int ia[3][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};
// 使用范围for循环
for(auto &raw : ia) // 使用引用类型是为了防止数组名自动转为指针类型
    for(auto col : raw) // 如果想要修改数组元素也需要使用引用类型, 单纯输出的话可以不使用引用类型
        printf("%d ", col);
// 使用标准库函数
for(auto p = begin(ia); p != end(ia); ++p)
    for(auto q = begin(*p); q != end(*p); ++q)
        printf("%d ", *q);
// 使用指针
for(int (*p)[4] = ia; p != ia + 3; ++p)
    for(int *q = *p; q != *p + 4; ++q)
        printf("%d ", *q);

转载于:https://www.cnblogs.com/moon1992/p/7252188.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值