ch3 字符串、向量和数组

1. 命名空间的using声明
  • using声明形式:
using namespace::name;
  • 头文件不应包含using声明
2. 标准库类型string
1. string初始化
string s3("value") //s3是字面值"value"的副本,除了字面值最后的那个空字符外
  • 如果使用等号(=)初始化一个变量,实际上执行的是拷贝初始化,编译器把等号右侧的初始值拷贝到新创建的对象中去。如果不使用等号,则执行的是直接初始化。
2. string对象操作
getline(is, s) //从is中读取一行赋给s,返回is
s[n] //返回s中第n个字符的引用,位置n从0计起
读写string对象
  • string对象会自动忽略开头的空白(即空格符、换行符、制表符等)并从第一个真正的字符开始读起,直到遇见下一处空白为止
  • string::size_type是一个无符号类型的值而且能足够存放下任何string对象的大小
比较string对象
  • 如果两个string对象在某些对应的位置上不一致,则string对象比较的结果其实是string对象中第一对相异字符比较的结果
字面值和string对象相加
string s4 = s1 + ", ";      // 正确:把一个string对象和一个字面值相加  
string s5 = "hello" + ", ";     // 错误:两个运算对象都不是string  
  • 必须确保每个加法运算符(+)的两侧的运算对象至少有一个是string
3. 处理string对象中的字符
范围的for语句
//expression部分是一个对象,用于表示一个序列。
//declaration部分负责定义一个变量,该变量将被用于访问序列中的基础元素
for (declaration : expression)  
    statement 

string str("some string");  
// 每行输出str中的一个字符。  
for (auto c : str)          // 对于str中的每个字符  
     cout << c << endl;         // 输出当前字符,后面紧跟一个换行符    
改变字符串中字符
  • 想要改变string对象中字符的值,必须把循环变量定义成引用类型
string s("Hello World!!!");  
// 转换成大写形式。  
for (auto &c : s)       // 对于s中的每个字符(注意:c是引用)  
    c = toupper(c);         // c是一个引用,因此赋值语句将改变s中字符的值  
cout << s << endl; 
  • string对象中的单个字符有两种方式:一种是使用下标,另外一种是使用迭代器
  • 在访问指定字符之前,首先检查s是否为空
3. 标准库类型vector
  • 标准库类型vector表示对象的集合,其中所有对象的类型都相同
1. 初始化vector
#include <vector> 
using std::vector;

vector<int> ivec;               // ivec保存int类型的对象  
vector<Sales_item> Sales_vec;   // 保存Sales_item类型的对象  
vector<vector<string>> file;    // 该向量的元素是vector对象 
2. 向vector中添加元素
vector<int> v2;      // 空vector对象  
for (int i = 0; i != 100; ++i)  
    v2.push_back(i); // 依次把整数值放到v2尾端  
// 循环结束后v2有100个元素,值从0到99
  • push_back负责把一个值当成vector对象的尾元素”压到(push)”vector对象的”尾端(back)
  • vector支持下标操作,但不能用下标形式添加元素
4. 迭代器介绍
1. 使用迭代器
// b表示v的第一个元素,e表示v尾元素的下一位置  
auto b = v.begin(), e = v.end(); //b 和e的类型相同 
  • 如果容器为空,则begin和end返回的是同一个迭代器,都是尾后迭代器
标准容器迭代器的运算符
*iter //返回迭代器iter所指元素的引用
iter->mem //解引用iter并获取该元素的名为mem的成员,
等价于(*iter).mem
  • 使用迭代器把string对象的第一个字母改为了大写形式
string s("some string");  
for (auto it = s.begin(); it != s.end() && !isspace(*it); ++it) { 
    *it = toupper(*it); // 将当前字符改成大写形式  
}
迭代器类型
vector<int>::iterator it;   // it能读写vector<int>的元素  
string::iterator it2;       // it2能读写string对象中的字符  

vector<int>::const_iterator it3;    // it3只能读元素,不能写元素
string::const_iterator it4;         // it4只能读字符,不能写字符  
2. 迭代器运算
  • cbegin()和cend()
auto it = v.cbegin(); // it的类型是vector<int>::const_iterator 
两种情况使迭代器失效
  • 不能在范围for循环中向vector对象添加元素
  • 任何一种可能改变vector对象容量的操作,比如push_back,都会使该vector对象的迭代器失效
5. 数组
1. 定义和初始化内置数组
  • 维度必须是一个常量表达式
int arr[10];                // 含有10个整数的数
string bad[cnt];            // 错误:cnt不是常量表达式
显式初始化数组元素
int a3[5] = {0, 1, 2};          //等价于a3[] = {0, 1, 2, 0, 0}  
string a4[3] = {"hi", "bye"};   // 等价于 a4[] = {"hi", "bye", ""} 
字符数组的特殊性
  • 一定要注意字符串字面值的结尾处还有一个空字符
char a1[] = {'C', '+', '+'};        // 列表初始化,没有空字符  
char a2[] = {'C', '+', '+', '\0'};  //列表初始化,含有显式的空字符  
char a3[] = "C++";                  // 自动添加表示字符串结束的空字符  
const char a4[6] = "Daniel";        // 错误:没有空间可存放空字符! 
不允许拷贝和赋值
  • 不能将数组的内容拷贝给其他数组作为其初始值,也不能用数组为其他数组赋值
int a[] = {0, 1, 2};    // 含有3个整数的数组  
int a2[] = a;           // 错误:不允许使用一个数组初始化另一个数组  
aa2 = a;                // 错误:不能把一个数组直接赋值给另一个数组 
复杂的数组声明
int *(&arry)[10] = ptrs; // arry是数组的引用,该数组含有10个指针 
2. 访问数组元素
  • 下标访问
3. 指针和数组
string nums[] = {"one", "two", "three"}; // 数组的元素是string对象  
string *p = &nums[0];  // p指向nums的第一个元素
string *p2 = nums; // 等价于p2 = &nums[0] 
指针也是迭代器
int arr[] = {0,1,2,3,4,5,6,7,8,9};  
int *p = arr;   // p指向arr的第一个元素  
++p;            // p指向arr[1] 
int *e = &arr[10]; //指向arr尾元素的下一位置的指针 

int ia[] = {0,1,2,3,4,5,6,7,8,9}; // ia是一个含有10个整数的数组 
int *beg = begin(ia);       // 指向ia首元素的指针  
int *last = end(ia);        //指向arr尾元素的下一位置的指针 
指针运算
  • 给(从)一个指针加上(减去)某整数值,结果仍是指针。新指针指向的元素与原来的指针相比前进了(后退了)该整数值个位置
  • 和迭代器一样,两个指针相减的结果是它们之间的距离
  • 只要两个指针指向同一个数组的元素,或者指向该数组的尾元素的下一位置,就能利用关系运算符对其进行比较
解引用和指针运算的交互
int ia[] = {0,2,4,6,8};     // 含有5个整数的数组  
int last = *(ia + 4);   // 正确:把last初始化成8,也就是ia[4]的值 
last = *ia + 4; // 正确: last = 4等价于ia[0] + 4 
下标和指针
int i = ia[2];      // ia转换成指向数组首元素的指针  
                   // ia[2]得到(ia + 2) 所指的元素  
int *p = ia;        // p指向ia的首元素  
i = *(p + 2);       // 等价于i = ia[2] 


int *p = &ia[2];    // p指向索引为2的元素  
int j = p[1];       // p[1]等价于 *(p + 1),就是ia[3]表示的那个元素  
int k = p[-2];      // p[-2]是ia[0]表示的那个元素  
6. 多维数组
多维数组的初始化
  • 使用花括号括起来的一组值初始化多维数组,和普通的数组一样
  • 也可去掉花括号
  • 初始化每一行的第一个元素
int ia[3][4] = {{ 0 }, { 4 }, { 8 }}; 
  • 初始化第1行
int ia[3][4] = {0, 3, 6, 9 };
多维数组的下标引用
// 用arr的首元素为ia最后一行的最后一个元素赋值  
ia[2][3] = arr[0][0][0];  
int (&row)[4] = ia[1]; // 把row绑定到ia的第二个4元素数组上
指针与多维数组
int ia[3][4];       //大小为3的数组,每个元素是含有4个整数的数组 int (*p)[4] = ia;   // p指向含有4个整数的数组  
p = &ia[2];             // p指向ia的尾元素
  • tips:二维数组必须指定列的数量,行的数量可以不指定
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值