Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
ShujiaHuang committed Jul 21, 2021
1 parent 69b66ef commit 8deb4c9
Showing 1 changed file with 144 additions and 2 deletions.
146 changes: 144 additions & 2 deletions practice/booknotes.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,37 @@
C++总览简介

C++ 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言,支持过程化编程、面向对象编程和泛型编程。
C++ 被认为是一种中级语言,它综合了高级语言和低级语言的特点。
C++ 是由 Bjarne Stroustrup 于 1979 年在新泽西州美利山贝尔实验室开始设计开发的。C++ 进一步扩充和完善了 C 语言,最初命名为带类的C,后来在 1983 年更名为 C++。
C++ 是 C 的一个超集,事实上,任何合法的 C 程序都是合法的 C++ 程序。

注意:使用静态类型的编程语言是在编译时执行类型检查,而不是在运行时执行类型检查。

面向对象程序设计

C++最大的亮点就是面向对象程序设计理念的运用。包括面向对象开发的四大特性:
封装
抽象
继承
多态

C++的组成部分

标准的 C++ 由三个重要部分组成:
核心语言,提供了所有构件块,包括变量、数据类型和常量,等等。
C++ 标准库,提供了大量的函数,用于操作文件、字符串等。
标准模板库(STL),提供了大量的方法,用于操作数据结构等。



# 第一章 预备知识
(略)
# 第二章 开始学习 C++
(略)
C++用分号隔开每一个执行语句。
# 第三章 处理数据

**面向对象编程(OOP)的本质是设计并扩展自己的数据类型。设计 自己的数据类型就是让类型与数据匹配**
**面向对象编程(OOP)的本质是设计并扩展自己的数据类型。设计自己的数据类型就是让类型与数据匹配**

内置的C++类型分两组:基本类型和复合类型。本章将介绍基本类型,即整数和浮点数。似乎只有两种类型,但C++知道,没有任何一种整型和浮点型能够满足所有的编程要求,因此对于这两种数据,它提供 了多种变体。

Expand Down Expand Up @@ -272,35 +299,150 @@ C++的基本类型分为两组:一组由存储为整数的值组成,另一

对变量赋值、在运算中使用不同类型、使用强制类型转换时,C++将把值从一种类型转换为另一种类型。





# 第四章 复合类型

本章需要掌握的内容为:

- 创建和使用数组;
- 创建和使用C-风格字符串;
- 创建和使用 string 类字符串;
- 使用方法 getline() 和 get() 读取字符串;
- 混合输入字符串和数字;
- 创建和使用结构体;
- 创建和使用共用体;
- 创建和使用枚举类型;
- 创建和使用指针;
- 使用 new 和 delete 管理动态内存;
- 创建动态数组;
- 创建动态结构;
- 自动存储、静态存储和动态存储;
- vector 和 array 类简介。

## 4.1 数组

数组(array) 是一种数据格式,能够存储多个**同类型**的值。每个值都存储在一个独立的数组元素中,计算机在内存中依次存储数组的各个元素。

> 即数组所在的内存区域是连续的
> 即一个数组所在的内存区域是连续的
要创建数组,可使用声明语句。数组声明应指出以下三点:

- 存储在每个元素中的值的类型;
- 数组名;
- 数组中的元素数。

在C++中,通过在简单变量后面添加中括号(其中包含 元素数目)来完成数组声明。而数组中的每一个元素都看作是一个简单变量。声明数组的通用格式为 :

`typeName arrayName[arraySize]`

表达式arraySize指定元素数目,它必须是整型常数(如10)或const 值,也可以是常量表达式(如8 * sizeof(int)),即其中所有的值在编 译时都是已知的。具体说,arraySize不能是变量,变量的值是在程序 运行时设置的。如:

```Cpp
int months[12]; // 声明一个包含 12 个整数的数组
```

C++ 通过使用下标来访问数组中的每一个元素,C++ 数据从0开始编号,数组总长度-1 是最后一个元素,如上:months[0] 为第一个元素,months[11] 是最后一个元素。

![image-20210721153711828](https://static.fungenomics.com/images/2021/07/image-20210721153711828.png)

### 4.1.1

C++可以在声明语句中初始化数组,只需提供一个用逗号分隔的值列表(初始化列表),并将它们用花 括号括起即可。如 :

```Cpp
int yamcosts[3] = {20, 30, 5};
```
如果没有初始化数组的值,则其元素值将是不确定的,这意味着元素的值为以前驻留在该内 存单元中的值。
> 将sizeof运算符用于数组名,得到的将是整个数组 中的字节数。
### 4.1.2 数组的初始化规则
只有在定义数组时才能使用初始化,此后就不能使用了,也不能将一个数组赋给另一个数组:
![image-20210721154858602](https://static.fungenomics.com/images/2021/07/image-20210721154858602.png)
> 这个方式和 Python 完全不同,原因可能是 Python 以引用为基础赋值,C++此处则是值赋值,只能一个一个来(声明时除外)。
但此后,仍然可以通过下标分别给数组中的元素赋值。注意,**这里是赋值不再是初始化**。
初始化数组时,提供的值可以少于数组的元素数目,编译器将把其他元素设置为 0。因此,将数组中所有的元素都初始化为0非常简单—只要显式地将第 一个元素初始化为0,然后编译器会自动将其他元素都初始化为0。
*还有一种方法,如果初始化数组时方括号内([ ])为空,C++编译器将计算元素个 数。但这是很糟糕的做法,不提倡,不举例。*
### 4.1.3 C++11数组初始化方法
数组以前就可使用列表初始化, 但C++11中的列表初始化新增了一些功能。
- 首先,初始化数组时,可省略等号(=);
- 其次,可不在大括号内包含任何东西,这将把所有元素都设置为零;
- 第三,列表初始化禁止缩窄转换。
![image-20210721160721085](https://static.fungenomics.com/images/2021/07/image-20210721160721085.png)
在上述代码中,第一条语句不能通过编译,因为将浮点数转换为整 型是缩窄操作,即使浮点数的小数点后面为零。第二条语句也不能通过 编译,因为1122011超出了char变量的取值范围(这里假设char变量的长 度为8位)。第三条语句可通过编译,因为虽然112是一个int值,但它在 char变量的取值范围内。
## 4.2 字符串
字符串是存储在内存的一片连续字节中的一系列字符,这里的**连续**是重点。
存储在连续字节中的一系列字符意味着可以将字符串存储在char数 组中,其中每个字符都位于自己的数组元素中。字符串提供了一种存储 文本信息的便捷方式。本章介绍两种处理字符串的方法:(1)C-风格字符串;(2)基于 string 类的方法。
C-风格字符串具有 一种特殊的性质:以空字符(null character)结尾,空字符被写作 \0, 其ASCII码为0,用来标记字符串的结尾。
![image-20210721161457763](https://static.fungenomics.com/images/2021/07/image-20210721161457763.png)
这两个数组都是char数组,但只有第二个数组是字符串,空字符对 C-风格字符串而言至关重要。C++有很多处理字符串的函数,其 中包括cout使用的那些函数。它们都逐个地处理字符串中的字符,直到 到达空字符为止。如果使用cout显示上面的cat这样的字符串,则将显示 前7个字符,发现空字符后停止。使用cout显示上面的dog数 组(它不是字符串),cout将打印出数组中的8个字母,并接着将内存 中随后的各个字节解释为要打印的字符,直到遇到空字符为止(因此不加空字符是C-风格字符串中极其危险的行为)。
有一种更好的、 将字符数组初始化为字符串的方法—只需使用一个用引号括起的字符串 即可,这种字符串被称为字符串常量(string constant)或字符串字面值 (string literal),如下所示:
![image-20210721162122919](https://static.fungenomics.com/images/2021/07/image-20210721162122919.png)
用引号括起来的字符串**隐式**地包括结尾的空字符,因此不用显式地包括它。
最需要注意的是,**使用C-风格字符串,在确定存储字符串所需的最短数组时,别忘了+1,要将结尾的空字符计算在内**。
![image-20210721162704816](https://static.fungenomics.com/images/2021/07/image-20210721162704816.png)
![image-20210721162840015](https://static.fungenomics.com/images/2021/07/image-20210721162840015.png)
> 这里的赋值改为:`char shirt_size[2] = "S";` 才是正确的。
### 4.2.1 拼接字符串常量
事实上,任何两个由空 白(空格、制表符和换行符)分隔的字符串常量都将自动拼接成一个。 因此,下面所有的输出语句都是等效的:
![image-20210721163221414](https://static.fungenomics.com/images/2021/07/image-20210721163221414.png)
注意,拼接时不会在被连接的字符串之间添加空格,第二个字符串 的第一个字符将紧跟在第一个字符串的最后一个字符(不考虑\0)后 面。第一个字符串中的\0字符将被第二个字符串的第一个字符取代。
### 4.2.2 在数组中使用字符串
从程序清单4.2中可以学到什么呢?
首先,sizeof运算符指出整个数组的长度:15字节,但 strlen( )函数返回的是存储在数组中的字符串的长度,而不是数组本身的长度。
另外,strlen( ) 只计算可见的字符,而不把空字符计算在内。因此,对于Basicman,返回的值为8,而不是 9。如果cosmic是字符串,则要存储该字符串,数组的长度不能短于strlen(cosmic)+1。
由于name1和name2是数组,所以可以用索引来访问数组中各个字符。例如,该程序使用 name1[0]找到数组的第一个字符。另外,该程序将name2[3]设置为空字符。这使得字符串在第 3个字符后即结束,虽然数组中还有其他的字符(参见图4.3)。
![image-20210721164300455](https://static.fungenomics.com/images/2021/07/image-20210721164300455.png)
程序清单 4.2 使用 cin 暗含两个问题:
- 遇到空格结束;
- 输入字符串长于目标数组。
### 4.2.3 字符串输入
cin是如何确定已完成字符串输入呢?由于不能通过键盘输入空字 符,因此cin需要用别的方法来确定字符串的结尾位置。cin使用空白 (空格、制表符和换行符)来确定字符串的结束位置,这意味着cin在 获取字符数组输入时只读取一个单词。读取该单词后,cin将该字符串 放到数组中,并自动在结尾添加空字符。
这个例子的实际结果是,cin把Alistair作为第一个字符串,并将它 放到name数组中。这把Dreeb留在输入队列中。当cin在输入队列中搜索 用户喜欢的甜点时,它发现了Dreeb,因此cin读取Dreeb,并将它放到 dessert数组中。
![image-20210721171126781](https://static.fungenomics.com/images/2021/07/image-20210721171126781.png)
另一个问题是,输入字符串可能比目标数组长(运行中没有揭示出 来)。像这个例子一样使用cin,确实不能防止将包含30个字符的字符 串放到20个字符的数组中的情况发生。
后续处理这个问题。
Expand Down

0 comments on commit 8deb4c9

Please sign in to comment.