Skip to content

Commit 4050046

Browse files
authored
Merge pull request applenob#32 from curiositer/zy/patch1
Update ch01-ch04 notes
2 parents 6702bc0 + 542f816 commit 4050046

File tree

5 files changed

+219
-28
lines changed

5 files changed

+219
-28
lines changed

excersize/ch04.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ int main()
250250
{
251251
vector<int> ivec{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
252252

253-
for (auto i : ivec)
253+
for (auto &i : ivec)
254254
{
255255
cout << ((i & 0x1) ? i * 2 : i) << " ";
256256
}

notes/ch01.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,13 @@ UNIX和Mac下键盘输入文件结束符:`ctrl+d`,Windows下:`ctrl+z`
113113

114114
- 单行注释: `//`
115115
- 多行注释: `/**/`。编译器将`/*``*/`之间的内容都作为注释内容忽略。注意不能嵌套。
116+
```cpp
117+
#define SALESITEM_H
118+
/*
119+
* 多行注释格式
120+
* 每一行加一个*
121+
*/
122+
```
116123

117124
## while语句
118125

notes/ch02.md

Lines changed: 72 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,17 @@
4040
- 使用空格连接,继承自C。
4141
- 字符字面值:单引号, `'a'`
4242
- 字符串字面值:双引号, `"Hello World""`
43+
- 分多行书写字符串。
44+
```
45+
std:cout<<"wow, a really, really long string"
46+
"literal that spans two lines" <<std::endl;
47+
```
4348
- 转义序列。`\n`、`\t`等。
4449
- 布尔字面值。`true`,`false`。
4550
- 指针字面值。`nullptr`
4651
52+
> 字符串型实际上时常量字符构成的数组,结尾处以`'\0'`结束,所以字符串类型实际上长度比内容多1。
53+
4754
## 变量
4855
4956
**变量**提供一个**具名**的、可供程序操作的存储空间。 `C++`中**变量**和**对象**一般可以互换使用。
@@ -56,15 +63,25 @@
5663
- 初始化 = 创建变量 + 赋予初始值
5764
- 赋值 = 擦除对象的当前值 + 用新值代替
5865
- **列表初始化**:使用花括号`{}`,如`int units_sold{0};`
59-
- 默认初始化:定义时没有指定初始值会被默认初始化;在函数体内部的内置类型变量将不会被初始化。
66+
- 默认初始化:定义时没有指定初始值会被默认初始化;**在函数体内部的内置类型变量将不会被初始化**
6067
- 建议初始化每一个内置类型的变量。
6168
6269
### 变量的**声明**(declaration) vs **定义**(define)
6370
- 为了支持分离式编译,`C++`将声明和定义区分开。**声明**使得名字为程序所知。**定义**负责创建与名字关联的实体。
6471
- **extern**:只是说明变量定义在其他地方。
6572
- 只声明而不定义: 在变量名前添加关键字 `extern`,如`extern int i;`。但如果包含了初始值,就变成了定义:`extern double pi = 3.14;`
66-
- 变量只能被定义一次,但是可以多次声明。
67-
- 名字的**作用域**(namescope)
73+
- 变量只能被定义一次,但是可以多次声明。定义只出现在一个文件中,其他文件使用该变量时需要对其声明。
74+
- 名字的**作用域**(namescope)`{}`
75+
- **第一次使用变量时再定义它**。
76+
- 嵌套的作用域
77+
- 同时存在全局和局部变量时,已定义局部变量的作用域中可用`::reused`显式访问全局变量reused。
78+
- **但是用到全局变量时,尽量不适用重名的局部变量。**
79+
80+
#### 变量命名规范
81+
1. 需体现实际意义
82+
2. 变量名用小写字母
83+
3. 自定义类名用大写字母开头:Sales_item
84+
4. 标识符由多个单词组成,中间须有明确区分:student_loan或studentLoan,不要用studentloan。
6885
6986
## 左值和右值
7087
@@ -76,35 +93,57 @@
7693
7794
### 引用
7895
96+
> 一般说的引用是指的左值引用
7997
- **引用**:引用是一个对象的别名,引用类型引用(refer to)另外一种类型。如`int &refVal = val;`。
8098
- 引用必须初始化。
81-
- 引用和它的初始值是**绑定bind**在一起的,而**不是拷贝**
99+
- 引用和它的初始值是**绑定bind**在一起的,而**不是拷贝**。一旦定义就不能更改绑定为其他的对象
82100
83101
### 指针
84102
103+
> int *p; //**指向int型对象**的指针
104+
85105
- 是一种 `"指向(point to)"`另外一种类型的复合类型。
86-
- **定义**指针类型: `int *ip1;`**从右向左读**`ip1`是指向`int`类型的指针。
106+
107+
- **定义**指针类型: `int *ip1;`,**从右向左读有助于阅读**,`ip1`是指向`int`类型的指针。
108+
87109
- 指针存放某个对象的**地址**。
110+
88111
- 获取对象的地址: `int i=42; int *p = &i;`。 `&`是**取地址符**。
112+
113+
- 指针的类型与所指向的对象类型必须一致(均为同一类型int、double等)
114+
89115
- 指针的值的四种状态:
90116
- 1.指向一个对象;
91117
- 2.指向紧邻对象的下一个位置;
92118
- 3.空指针;
93119
- 4.无效指针。
94-
- 指针访问对象: `cout << *p;``*`**解引用符**
95-
- 空指针不指向任何对象。
96-
- `void*`指针可以存放**任意**对象的地址。
120+
- >**对无效指针的操作均会引发错误,第二种和第三种虽为有效的,但理论上是不被允许的**
121+
122+
- 指针访问对象: `cout << *p;`输出p指针所指对象的数据, `*`是**解引用符**。
123+
124+
- 空指针不指向任何对象。使用`int *p=nullptr;`来使用空指针。
125+
126+
- > 指针和引用的区别:引用本身并非一个对象,引用定义后就不能绑定到其他的对象了;指针并没有此限制,相当于变量一样使用。
127+
128+
- > 赋值语句永远改变的是**左侧**的对象。
129+
130+
- `void*`指针可以存放**任意**对象的地址。因无类型,仅操作内存空间,对所存对象无法访问。
131+
97132
- 其他指针类型必须要与所指对象**严格匹配**。
133+
98134
- 两个指针相减的类型是`ptrdiff_t`。
135+
99136
- 建议:初始化所有指针。
100137
138+
- `int* p1, p2;//*是对p1的修饰,所以p2还是int型`
139+
101140
## const限定符
102141
103142
- 动机:希望定义一些不能被改变值的变量。
104143
105144
### 初始化和const
106145
- const对象**必须初始化**,且**不能被改变**。
107-
- const变量默认不能被其他文件访问,非要访问,必须在指定const前加extern
146+
- const变量默认不能被其他文件访问,非要访问,必须在指定const定义之前加extern。要想在多个文件中使用const变量共享,定义和声明都加const关键字即可
108147
109148
### const的引用
110149
@@ -115,14 +154,14 @@
115154
### 指针和const
116155
117156
- **pointer to const**(指向常量的指针):不能用于改变其所指对象的值, 如 `const double pi = 3.14; const double *cptr = &pi;`。
118-
- **const pointer**:指针本身是常量,如 `int i = 0; int *const ptr = &i;`
157+
- **const pointer**:指针本身是常量,也就是说指针固定指向该对象,(存放在指针中的地址不变,地址所对应的那个对象值可以修改)如 `int i = 0; int *const ptr = &i;`
119158
120159
### 顶层const
121160
122161
- `顶层const`:指针本身是个常量。
123162
- `底层const`:指针指向的对象是个常量。拷贝时严格要求相同的底层const资格。
124163
125-
### `constexpr`和常量表达式
164+
### `constexpr`和常量表达式(▲可选)
126165
127166
- 常量表达式:指值不会改变,且在编译过程中就能得到计算结果的表达式。
128167
- `C++11`新标准规定,允许将变量声明为`constexpr`类型以便由编译器来验证变量的值是否是一个常量的表达式。
@@ -134,26 +173,40 @@
134173
- 传统别名:使用**typedef**来定义类型的同义词。 `typedef double wages;`
135174
- 新标准别名:别名声明(alias declaration): `using SI = Sales_item;`(C++11)
136175
137-
### auto类型说明符
176+
```cpp
177+
// 对于复合类型(指针等)不能代回原式来进行理解
178+
typedef char *pstring; // pstring是char*的别名
179+
const pstring cstr = 0; // 指向char的常量指针
180+
// 如改写为const char *cstr = 0;不正确,为指向const char的指针
181+
182+
// 辅助理解(可代回后加括号)
183+
// const pstring cstr = 0;代回后const (char *) cstr = 0;
184+
// const char *cstr = 0;即为(const char *) cstr = 0;
185+
```
186+
187+
### auto类型说明符 c++11
138188

139189
- **auto**类型说明符:让编译器**自动推断类型**
190+
- 一条声明语句只能有一个数据类型,所以一个auto声明多个变量时只能相同的变量类型(包括复杂类型&和*)。`auto sz = 0, pi =3.14//错误`
140191
- `int i = 0, &r = i; auto a = r;` 推断`a`的类型是`int`
141192
- 会忽略`顶层const`
142-
- `const int ci = 1; const auto f = ci;`推断类型是`int`,需要自己加`const`
143-
- `C++11`
193+
- `const int ci = 1; const auto f = ci;`推断类型是`int`,如果希望是顶层const需要自己加`const`
144194

145195
### decltype类型指示符
146196

147197
- 从表达式的类型推断出要定义的变量的类型。
148198
- **decltype**:选择并返回操作数的**数据类型**
149199
- `decltype(f()) sum = x;` 推断`sum`的类型是函数`f`的返回类型。
150200
- 不会忽略`顶层const`
201+
- 如果对变量加括号,编译器会将其认为是一个表达式,如int i-->(i),则decltype((i))得到结果为int&引用。
202+
- 赋值是会产生引用的一类典型表达式,引用的类型就是左值的类型。也就是说,如果 i 是 int,则表达式 i=x 的类型是 int&。
151203
- `C++11`
152204

153205
## 自定义数据结构
154206

155207
### struct
156208

209+
> 尽量不要吧类定义和对象定义放在一起。如`struct Student{} xiaoming,xiaofang;`
157210
- 类可以以关键字`struct`开始,紧跟类名和类体。
158211
- 类数据成员:类体定义类的成员。
159212
- `C++11`:可以为类数据成员提供一个**类内初始值**(in-class initializer)。
@@ -167,12 +220,15 @@
167220
- **预处理器**(preprocessor):确保头文件多次包含仍能安全工作。
168221
- 当预处理器看到`#include`标记时,会用指定的头文件内容代替`#include`
169222
- **头文件保护符**(header guard):头文件保护符依赖于预处理变量的状态:已定义和未定义。
223+
- `#indef`已定义时为真
224+
- `#inndef`未定义时为真
225+
- 头文件保护符的名称需要唯一,且保持全部大写。养成良好习惯,不论是否该头文件被包含,要加保护符。
170226

171227
```cpp
172-
#ifndef SALES_DATA_H
228+
#ifndef SALES_DATA_H //SALES_DATA_H未定义时为真
173229
#define SALES_DATA_H
174230
strct Sale_data{
175231
...
176232
}
177233
#endif
178-
```
234+
```

notes/ch03.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,20 @@
4141
| `s1=s2` |`s2`的副本代替`s1`中原来的字符 |
4242
| `s1==s2` | 如果`s1``s2`中所含的字符完全一样,则它们相等;`string`对象的相等性判断对字母的大小写敏感 |
4343
| `s1!=s2` | 同上 |
44-
| `<`, `<=`, `>`, `>=` | 利用字符在字典中的顺序进行比较,且对字母的大小写敏感 |
44+
| `<`, `<=`, `>`, `>=` | 利用字符在字典中的顺序进行比较,且对字母的大小写敏感(对第一个不相同的位置进行比较) |
4545

4646
- string io:
4747
- 执行读操作`>>`:忽略掉开头的空白(包括空格、换行符和制表符),直到遇到下一处空白为止。
4848
- `getline`:读取一整行,**包括空白符**
49-
- 字符串字面值和string是不同的类型。
49+
- `s.size()`返回的时`string::size_type`类型,记住是一个**无符号**类型的值,不要和`int`混用
50+
- `s1+s2`使用时,保证至少一侧是string类型。`string s1 = "hello" + "world" // 错误,两侧均为字符串字面值`
51+
- **字符串字面值和string是不同的类型。**
5052

5153
### 处理string对象中的字符
5254

5355
- **ctype.h vs. cctype**:C++修改了c的标准库,名称为去掉`.h`,前面加`c`
56+
> 如c++版本为`cctype`,c版本为`ctype.h`
57+
- **尽量使用c++版本的头文件**,即`cctype`
5458

5559
`cctype`头文件中定义了一组标准函数:
5660

@@ -71,6 +75,7 @@
7175
| `toupper(c)` |`c`是小写字母,输出对应的大写字母;否则原样输出`c` |
7276

7377
- 遍历字符串:使用**范围for**(range for)语句: `for (auto c: str)`,或者 `for (auto &c: str)`使用引用直接改变字符串中的字符。 (C++11)
78+
- `str[x]`,[]输入参数为`string::size_type`类型,给出`int`整型也会自动转化为该类型
7479

7580
## vector
7681
- vector是一个**容器**,也是一个类模板;
@@ -135,7 +140,7 @@
135140
- **迭代器(iterator)**:每种标准容器都有自己的迭代器。`C++`倾向于用迭代器而不是下标遍历元素。
136141
- **const_iterator**:只能读取容器内元素不能改变。
137142
- **箭头运算符**: 解引用 + 成员访问,`it->mem`等价于 `(*it).mem`
138-
- **谨记**但凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素
143+
- **谨记**但凡是使用了**迭代器**的循环体,都**不要**向迭代器所属的容器**添加元素**
139144

140145
标准容器迭代器的运算符:
141146

@@ -199,10 +204,11 @@ C标准库String函数,定义在`<cstring>` 中:
199204
| `strcat(p1, p2)` |`p2`附加到`p1`之后,返回`p1` |
200205
| `strcpy(p1, p2)` |`p2`拷贝给`p1`,返回`p1` |
201206

207+
**尽量使用vector和迭代器,少用数组**
202208
## 多维数组
203209

204210
- **多维数组的初始化**`int ia[3][4] = {{0,1,2,3}, ...}`
205-
- 使用范围for语句时,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型
211+
- 使用范围for语句时,除了最内层的循环外,其他所有循环的控制变量都应该是**引用**类型
206212

207213
## 指针vs引用
208214

0 commit comments

Comments
 (0)