Skip to content

Commit

Permalink
添加"字符串与数组"
Browse files Browse the repository at this point in the history
  • Loading branch information
arkingc committed Jun 1, 2019
1 parent ba88729 commit 97b8661
Showing 1 changed file with 172 additions and 9 deletions.
181 changes: 172 additions & 9 deletions C++/C++Primer.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@

|**变量**|**函数**|**面向对象**|**模板与泛型编程**|**内存管理**|
|**常见类型**|**函数**|**面向对象**|**模板与泛型编程**|**内存管理**|
|:--:|:--:|:--:|:--:|:--:|
|[变量](#ch1)<br>|||[模板与泛型编程](#ch2)<br>|[内存管理](#ch3)<br>|
|[变量](#ch1)<br>[字符串与数组](#ch4)|||[模板与泛型编程](#ch2)<br>|[内存管理](#ch3)<br>|

<br>
<br>

<h2 id="ch1"></h2>

* [变量](#一变量)
* [变量](#变量)
- [1.类型](#1类型)
- [2.大小](#2大小)
- [3.signed与unsigned](#3signed与unsigned)
Expand All @@ -23,6 +23,20 @@
- [12.auto](#12auto)
- [13.decltype](#13decltype)

<h2 id="ch4"></h2>

* [字符串与数组](#字符串与数组)
- [1.字符串](#1字符串)
+ [1.1 初始化](#11-初始化)
+ [1.2 大小](#12-大小)
+ [1.3 常见操作](#13-常见操作)
- [2.数组](#2数组)
+ [2.1 初始化](#21-初始化)
+ [2.2 大小](#22-大小)
+ [2.3 遍历](#23-遍历)
+ [2.4 auto与decltype](#24-auto与decltype)
+ [2.5 多维数组](#25-多维数组)

<h2 id="ch2"></h2>

* [模板与泛型编程](#模板与泛型编程)
Expand Down Expand Up @@ -67,7 +81,7 @@
<br>
<br>

# 一.变量
# 变量

## 1.类型

Expand Down Expand Up @@ -173,10 +187,11 @@ C++中初始化和赋值是2个完全不同的操作

## 6.声明与定义

* 声明:`extern 类型 变量名字;`
* 声明 + 定义:`类型 变量名字;`

`extern 类型 变量名字 = 值;`(如果在函数内则会报错)
* 声明:
* `extern 类型 变量名字;`
* 声明 + 定义:
* `类型 变量名字;`
* `extern 类型 变量名字 = 值;`(如果在函数内则会报错)

声明不会分配存储空间,定义会分配存储空间

Expand Down Expand Up @@ -204,7 +219,7 @@ C++中初始化和赋值是2个完全不同的操作

### 8.2 指针

* 指针不同与引用,指针本身就是一个对象
* 指针不同于引用,指针本身就是一个对象
* 因为引用不是对象,没有实际地址,所以不能定义指向引用的指针
* 指针是一个对象,所以存在对指针的引用
* 一般来说,指针类型和指向的对象类型也需严格匹配
Expand Down Expand Up @@ -371,6 +386,154 @@ const与指针的类型别名使用时,还原别名来理解const的限定是
<br>
<br>

# 字符串与数组

## 1.字符串

> 字符串也是一种顺序容器
```c++
#include<string>
using std::string
```

### 1.1 初始化

> 默认初始化为空串
* **拷贝初始化**
* `=`
* 允许使用以空字符结束的字符数组来初始化
* **直接初始化**
* `()`
* 如果传入一个`char*`
* 1)同时传入了长度,则拷贝`char*`指向字符数组的指定长度的字符
* 2)没有传入长度,则`char*`指向的字符数组必须以空字符结尾
* 示例:
* `string s(c,n); //s包含n个字符c`
* `string s(cp,n); //s是cp指向的数组(cp为char *)中前n个字符的拷贝`
* `string s(s2,pos2); //s是string s2从下标pos2开始的字符的拷贝。若pos2>s2.size(),则行为未定义(会抛出out_of_range异常)`
* `string s(s2,pos2,len2); //s是string s2从pos2下标开始,len2个字符的拷贝。若pos2>s2.size(),则行为未定义(会抛出out_of_range异常)。不管len2多长,至多拷贝到结尾`

### 1.2 大小

返回类型:`size::size_type`

无符号类型,注意与带符号数的运算

* 判断是否为空串
* `if(str.size() == 0)`
* `if(str.empty())`
* `if(str == "")`

### 1.3 常见操作

* **访问**
* **遍历**
* 不需修改:`for(auto c : s)``for(decltype(s.size()) i = 0; i < s.size( ); i++ )`
* 需要修改:`for(auto &c : s)​``for(decltype(s.size()) i = 0; i < s.size( ); i++ )`
* **访问某个字符**
* 下标运算符:`str[pos]`,接收的参数类型为`size::size_type`。返回“引用”,所以可以修改。越界结果不可预知
* `str.at(pos)`:会检查下标`pos`是否有效
* 迭代器
* **转化为字符数组**
* `c_str()`
* **获得子串**
* `s.substr(pos)`:返回从pos开始的尾串。如果超出范围会抛出out_of_range异常
* `s.substr(pos,n)`:返回从pos开始,长度为n的子串。超出范围则返回剩余所有部分
* **修改**
* **插入**
* `s.append(str)`:在字符串末尾插入str指向的字符串
* `s.insert(pos,n,c)`:在pos之前插入n个字符c
* `s.insert(pos,cstr)`:在pos之前插入字符指针cstr指向的字符串
* `s.insert(pos1,s2,pos2,n)`:在s的pos1位置插入s2从pos2开始的n个字符
* **删除**
* `s.erase(pos,n)`:从pos位置开始,删除n个字符,若n过大,则删完从pos开始的剩余字符
* **替换**
* `s.replace(pos,n,str)`:将pos位置开始的n个字符删除,然后在pos位置处插入str指向的字符串
* **搜索**
* 搜索成功返回`string::size_type`类型的下标;搜索失败返回`string::npos`
* `string::npos`:static变量,`const string::size_type`类型,初始化为`-1`。由于是一个unsigned类型,因此这个初始值意味着`npos`等于任何string最大的可能大小
* `s.find(args)`:查找s中`args`第一次出现的位置
* `s.rfind(args)`:在s中查找args中任何一个字符最后一次出现的位置(反向查找)
* `s.find_first_not_of(args)`:在s中查找第一个不在args中的字符
* `s.find_last_not_of(args)`:在s中查找最后一个不在args中的字符(反向查找)
* **比较**
* `s.compare(args)`:可以传入字符串或字符指针,以及位置,长度等
* **数值转换**
* **数值转字符串**
* `to_string(val)`:val可以是任何算术类型
* **字符串转数字**`p``size_t`类型变量,保存`s`中第一个非数值字符的下标,默认为`0``b`表示转换所用的基数,默认为`10`
* **转成整形**
* `stoi(s,p,b)`
* `stol(s,p,b)`
* `stoul(s,p,b)`
* `stoll(s,p,b)`
* `stoull(s,p,b)`
* **转成浮点数**
* `stof(s,p)`
* `stod(s,p)`
* `stold(s,p)`

<br>

## 2.数组

> 数组的元素为对象,不存在引用的数组​(`int &refs[10] = ...;` 错误)
### 2.1 初始化

* 默认情况下,数组的元素被默认初始化
* 字符数组可以使用字符串字面值初始化
* 不允许直接使用数组拷贝和赋值

### 2.2 大小

维度必须是一个常量表达式。类型定义为`size_t`,定义在头文件`cstddef`

### 2.3 遍历

数组遍历可以用`for(auto i : array)`,但是对于指针不行,即`array`不能是指针

* 数组迭代器:可以通过如下调用获取数组迭代器,函数定义在`iterator`头文件
* `begin(array)`
* `end(array)`

### 2.4 auto与decltype

```c++
int ia[ ] = {0,1,2,3,4...9};
​auto ia2(ia); //ia2是一个整形指针,指向ia的第一个元素
decltype(ia) ia3 = {0,1,2,3,4...9} //decltype(ia)返回的类型是由10个整数构成的数组
```
### 2.5 多维数组
> 严格来说,C++中没有多维数组,通常所说的多维数组其实是数组的数组
#### 1)初始化
```c++
int [2][3] = {{1,2,3},{4,5,6}};
int [2][3] = {1,2,3,4,5,6}; //和上面等价​
```

从内存分布上来说连续,就像是一维数组,但是并不能用`int*`来遍历。因为每3个元素实际上是一个`int[3]`类型​

#### 4)遍历

如果使用`for(:)`形式遍历多维数组,除了最内层循环,其它层循环的控制变量都应该是引用类型

#### 5)类型别名

```c++
using int_array = int[4];
typedef int int_array[4]; //等价的typedef声明​
```

<br>
<br>

# 模板与泛型编程

## 1.模板函数
Expand Down

0 comments on commit 97b8661

Please sign in to comment.