docs(book): 添加现代 C++教程及相关代码
- 新增现代 C++ 教程的 Preface 章节,包括英文和中文版本 - 添加 C++ Primer 练习代码 - 新增 Learn C++ 教程的 C++ 开发简介章节 - 添加头文件解析文档 - 更新 mkdocs.yml,包含新教程的目录结构 - 修改项目设置,使用 Python 3.10环境
4
.idea/material_theme_project_new.xml
generated
@ -3,7 +3,9 @@
|
||||
<component name="MaterialThemeProjectNewConfig">
|
||||
<option name="metadata">
|
||||
<MTProjectMetadataState>
|
||||
<option name="userId" value="-3282f873:197ddb2289e:-7e4d" />
|
||||
<option name="migrated" value="true" />
|
||||
<option name="pristineConfig" value="false" />
|
||||
<option name="userId" value="21c1c7ee:193388d497c:-7ff9" />
|
||||
</MTProjectMetadataState>
|
||||
</option>
|
||||
</component>
|
||||
|
||||
68
docs/CPlusPlus-main/01_C++的注释.ipynb
Normal file
@ -0,0 +1,68 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的注释"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 注释"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 在代码中的加一些说明和解释,这些说明和解释就叫注释。\n",
|
||||
"\n",
|
||||
"② 注释能方便自己和其他程序员阅读代码。\n",
|
||||
"\n",
|
||||
"③ C++的注释,有两种格式:\n",
|
||||
"\n",
|
||||
"1. 单行注释: // 描述信息 \n",
|
||||
" - note:通常放在一行代码的上方,或者一条语句的末尾,对该行代码说明。\n",
|
||||
"2. 多行注释: /* 描述信息 */ \n",
|
||||
" - note:编译器在编译代码时,会忽略注释的内容,即不会执行。"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
14
docs/CPlusPlus-main/01_C++的注释.md
Normal file
@ -0,0 +1,14 @@
|
||||
# C++的注释
|
||||
|
||||
# 1. 注释
|
||||
|
||||
① 在代码中的加一些说明和解释,这些说明和解释就叫注释。
|
||||
|
||||
② 注释能方便自己和其他程序员阅读代码。
|
||||
|
||||
③ C++的注释,有两种格式:
|
||||
|
||||
1. 单行注释: // 描述信息
|
||||
- note:通常放在一行代码的上方,或者一条语句的末尾,对该行代码说明。
|
||||
2. 多行注释: /* 描述信息 */
|
||||
- note:编译器在编译代码时,会忽略注释的内容,即不会执行。
|
||||
91
docs/CPlusPlus-main/02_C++的main函数.ipynb
Normal file
@ -0,0 +1,91 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的main函数"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. main函数"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① main函数是一个程序的入口\n",
|
||||
"\n",
|
||||
"② 每个程序都必须有这么一个函数,并且有且只有一个。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"//下面11行代码的含义就是在屏幕中输出一个 Hello World\n",
|
||||
"\n",
|
||||
"#include<iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main() {\n",
|
||||
"\n",
|
||||
" cout << \"hello C++\" << endl; //屏幕显示“hello C++”\n",
|
||||
" system(\"pause\"); //按任意键继续,退出程序\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - hello C++ \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
28
docs/CPlusPlus-main/02_C++的main函数.md
Normal file
@ -0,0 +1,28 @@
|
||||
# C++的main函数
|
||||
|
||||
# 1. main函数
|
||||
|
||||
① main函数是一个程序的入口
|
||||
|
||||
② 每个程序都必须有这么一个函数,并且有且只有一个。
|
||||
|
||||
|
||||
```python
|
||||
//下面11行代码的含义就是在屏幕中输出一个 Hello World
|
||||
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
|
||||
cout << "hello C++" << endl; //屏幕显示“hello C++”
|
||||
system("pause"); //按任意键继续,退出程序
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- hello C++
|
||||
- 请按任意键继续. . .
|
||||
91
docs/CPlusPlus-main/03_C++的打印.ipynb
Normal file
@ -0,0 +1,91 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的打印"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 打印"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① cout << \"XXXX\" << endl; 会使得屏幕打印双引号里面的字符串。\n",
|
||||
"\n",
|
||||
"② system(\"pause\"); 会使得屏幕的打印界面暂停到该语句这里,按任意键后才会继续运行。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"//下面11行代码的含义就是在屏幕中输出一个 Hello World\n",
|
||||
"\n",
|
||||
"#include<iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main() {\n",
|
||||
"\n",
|
||||
" cout << \"hello C++\" << endl; //屏幕显示“hello C++”\n",
|
||||
" system(\"pause\"); //按任意键继续,退出程序\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - hello C++\n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
28
docs/CPlusPlus-main/03_C++的打印.md
Normal file
@ -0,0 +1,28 @@
|
||||
# C++的打印
|
||||
|
||||
# 1. 打印
|
||||
|
||||
① cout << "XXXX" << endl; 会使得屏幕打印双引号里面的字符串。
|
||||
|
||||
② system("pause"); 会使得屏幕的打印界面暂停到该语句这里,按任意键后才会继续运行。
|
||||
|
||||
|
||||
```python
|
||||
//下面11行代码的含义就是在屏幕中输出一个 Hello World
|
||||
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
|
||||
cout << "hello C++" << endl; //屏幕显示“hello C++”
|
||||
system("pause"); //按任意键继续,退出程序
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- hello C++
|
||||
- 请按任意键继续. . .
|
||||
156
docs/CPlusPlus-main/04_C++的常量.ipynb
Normal file
@ -0,0 +1,156 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的常量"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 常量"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 常量,用于记录程序中不可更改的数据。\n",
|
||||
"\n",
|
||||
"② C++定义常量两种方式,如下所示:\n",
|
||||
"\n",
|
||||
"1. #define 宏常量:#define 常量名 常量值 \n",
|
||||
" - note:通常在文件上方定义,表示一个常量。\n",
|
||||
"2. const修饰的变量 const 数据类型 常量名 = 常量值 \n",
|
||||
" - note:通常在变量定义前加关键字const,修饰该变量为常量,不可修改。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.1 #define 常量名 常量值"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"#define Day 7 \n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
"\n",
|
||||
" /*\n",
|
||||
" Day = 14; //错误,Day是常量,一旦修改就会报错\n",
|
||||
" cout << \"一周总共有:\" << Day << \"天\" << endl;\n",
|
||||
" */\n",
|
||||
"\n",
|
||||
" cout << \"一周总共有:\" << Day << \"天\" << endl;\n",
|
||||
"\n",
|
||||
" // 输出语句:cout << \"提示语\" << 变量 << endl; \n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 一周总共有:7天 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.2 const 数据类型 常量名 = 常量值"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" /*\n",
|
||||
" const int month = 12;\n",
|
||||
" month = 24; //错误,const修饰的变量也称为常量\n",
|
||||
" */\n",
|
||||
"\n",
|
||||
" int month = 12;\n",
|
||||
" month = 24; //正确,这样可以修改变量的值\n",
|
||||
"\n",
|
||||
" cout << \"一年总共有:\" << month << \"个月\" << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 一年总共有:24个月 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
74
docs/CPlusPlus-main/04_C++的常量.md
Normal file
@ -0,0 +1,74 @@
|
||||
# C++的常量
|
||||
|
||||
# 1. 常量
|
||||
|
||||
① 常量,用于记录程序中不可更改的数据。
|
||||
|
||||
② C++定义常量两种方式,如下所示:
|
||||
|
||||
1. #define 宏常量:#define 常量名 常量值
|
||||
- note:通常在文件上方定义,表示一个常量。
|
||||
2. const修饰的变量 const 数据类型 常量名 = 常量值
|
||||
- note:通常在变量定义前加关键字const,修饰该变量为常量,不可修改。
|
||||
|
||||
## 1.1 #define 常量名 常量值
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define Day 7
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
/*
|
||||
Day = 14; //错误,Day是常量,一旦修改就会报错
|
||||
cout << "一周总共有:" << Day << "天" << endl;
|
||||
*/
|
||||
|
||||
cout << "一周总共有:" << Day << "天" << endl;
|
||||
|
||||
// 输出语句:cout << "提示语" << 变量 << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 一周总共有:7天
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.2 const 数据类型 常量名 = 常量值
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
/*
|
||||
const int month = 12;
|
||||
month = 24; //错误,const修饰的变量也称为常量
|
||||
*/
|
||||
|
||||
int month = 12;
|
||||
month = 24; //正确,这样可以修改变量的值
|
||||
|
||||
cout << "一年总共有:" << month << "个月" << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 一年总共有:24个月
|
||||
- 请按任意键继续. . .
|
||||
100
docs/CPlusPlus-main/05_C++的变量.ipynb
Normal file
@ -0,0 +1,100 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的变量"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 变量"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 变量的作用就是就是给一段指定的内存空间起名,方便操作这段内存。\n",
|
||||
"\n",
|
||||
"② 语法:数据类型 变量名 = 初始值;\n",
|
||||
"\n",
|
||||
"③ 变量存在的意义:方便我们管理内存空间。\n",
|
||||
"\n",
|
||||
"④ 每一段内存都有一个地址编号。\n",
|
||||
"\n",
|
||||
"⑤ C++规定在创建一个常量或变量时,必须要指出相应的数据类型,否则无法给变量分配内存。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
"\n",
|
||||
" //变量创建的语法:数据类型 变量名 = 变量初始值\n",
|
||||
" int a = 10; \n",
|
||||
"\n",
|
||||
" cout << \"a = \" << a << endl; // 输出语句 cout << \"提示语\" << 变量 << endl; \n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - a = 10\n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
37
docs/CPlusPlus-main/05_C++的变量.md
Normal file
@ -0,0 +1,37 @@
|
||||
# C++的变量
|
||||
|
||||
# 1. 变量
|
||||
|
||||
① 变量的作用就是就是给一段指定的内存空间起名,方便操作这段内存。
|
||||
|
||||
② 语法:数据类型 变量名 = 初始值;
|
||||
|
||||
③ 变量存在的意义:方便我们管理内存空间。
|
||||
|
||||
④ 每一段内存都有一个地址编号。
|
||||
|
||||
⑤ C++规定在创建一个常量或变量时,必须要指出相应的数据类型,否则无法给变量分配内存。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
//变量创建的语法:数据类型 变量名 = 变量初始值
|
||||
int a = 10;
|
||||
|
||||
cout << "a = " << a << endl; // 输出语句 cout << "提示语" << 变量 << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- a = 10
|
||||
- 请按任意键继续. . .
|
||||
143
docs/CPlusPlus-main/06_C++的关键字.ipynb
Normal file
@ -0,0 +1,143 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的关键字"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 关键字"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 关键字是C++中预先保留的单词(标识符)。\n",
|
||||
"\n",
|
||||
"② 在定义变量或者常量的时候,不要用关键字。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.1 int关键字"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
"\n",
|
||||
" // int int = 10; // 错误,第二个int是关键字,不可以作为变量的名称\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.2 sizeof关键字"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① sizeof关键字可以统计数据类型所占内存大小。\n",
|
||||
"\n",
|
||||
"② sizeof关键字,语法:sizeof ( 数据类型 / 变量 )"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
"\n",
|
||||
" cout << \"short 类型所占内存空间为:\" << sizeof(short) << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - short 类型所占内存空间为:2 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
56
docs/CPlusPlus-main/06_C++的关键字.md
Normal file
@ -0,0 +1,56 @@
|
||||
# C++的关键字
|
||||
|
||||
# 1. 关键字
|
||||
|
||||
① 关键字是C++中预先保留的单词(标识符)。
|
||||
|
||||
② 在定义变量或者常量的时候,不要用关键字。
|
||||
|
||||
## 1.1 int关键字
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
// int int = 10; // 错误,第二个int是关键字,不可以作为变量的名称
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.2 sizeof关键字
|
||||
|
||||
① sizeof关键字可以统计数据类型所占内存大小。
|
||||
|
||||
② sizeof关键字,语法:sizeof ( 数据类型 / 变量 )
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
cout << "short 类型所占内存空间为:" << sizeof(short) << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- short 类型所占内存空间为:2
|
||||
- 请按任意键继续. . .
|
||||
116
docs/CPlusPlus-main/07_C++的标识符.ipynb
Normal file
@ -0,0 +1,116 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的标识符"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 标识符"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 标识符就是 C++ 给变量、常量的命名。\n",
|
||||
"\n",
|
||||
"② 标识符有一套自己的命名规则:\n",
|
||||
"\n",
|
||||
"1. 标识符不能使关键字。\n",
|
||||
"2. 标识符只能由字母、数字、下划线组成。\n",
|
||||
"3. 第一个字符必须为字母或下划线。\n",
|
||||
"4. 标识符中字母区分大小写。\n",
|
||||
"\n",
|
||||
"③ 建议:给标识符命名时,争取做到见名知意,方便自己和他人的阅读。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //1、标识符不可以是关键字\n",
|
||||
" //int int = 10; //报错\n",
|
||||
" \n",
|
||||
" //2、标识符由字母、数字、下划线构成\n",
|
||||
" int abc = 10;\n",
|
||||
" int _abc = 20;\n",
|
||||
" int _123abc = 40;\n",
|
||||
" \n",
|
||||
" //3、标识符第一个字符只能是字母或下划线\n",
|
||||
" //int 123abc = 50; //报错\n",
|
||||
"\n",
|
||||
" //4、标识符区分大小写\n",
|
||||
" int aaa = 100;\n",
|
||||
" //cout << AAA << endl; //报错,AAA和aaa不是同一个名称\n",
|
||||
"\n",
|
||||
" //建议:给变量起名的时候,最好能够做到见名知意\n",
|
||||
" int num1 = 10;\n",
|
||||
" int num2 = 20;\n",
|
||||
" int sum = num1 + num2; //建议用num1、num2、sum表示加法,而不是用a、b、c来表示\n",
|
||||
" cout << sum << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 30\n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
53
docs/CPlusPlus-main/07_C++的标识符.md
Normal file
@ -0,0 +1,53 @@
|
||||
# C++的标识符
|
||||
|
||||
# 1. 标识符
|
||||
|
||||
① 标识符就是 C++ 给变量、常量的命名。
|
||||
|
||||
② 标识符有一套自己的命名规则:
|
||||
|
||||
1. 标识符不能使关键字。
|
||||
2. 标识符只能由字母、数字、下划线组成。
|
||||
3. 第一个字符必须为字母或下划线。
|
||||
4. 标识符中字母区分大小写。
|
||||
|
||||
③ 建议:给标识符命名时,争取做到见名知意,方便自己和他人的阅读。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//1、标识符不可以是关键字
|
||||
//int int = 10; //报错
|
||||
|
||||
//2、标识符由字母、数字、下划线构成
|
||||
int abc = 10;
|
||||
int _abc = 20;
|
||||
int _123abc = 40;
|
||||
|
||||
//3、标识符第一个字符只能是字母或下划线
|
||||
//int 123abc = 50; //报错
|
||||
|
||||
//4、标识符区分大小写
|
||||
int aaa = 100;
|
||||
//cout << AAA << endl; //报错,AAA和aaa不是同一个名称
|
||||
|
||||
//建议:给变量起名的时候,最好能够做到见名知意
|
||||
int num1 = 10;
|
||||
int num2 = 20;
|
||||
int sum = num1 + num2; //建议用num1、num2、sum表示加法,而不是用a、b、c来表示
|
||||
cout << sum << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 30
|
||||
- 请按任意键继续. . .
|
||||
447
docs/CPlusPlus-main/08_C++的数据类型.ipynb
Normal file
@ -0,0 +1,447 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的数据类型"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 数据类型"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.1 整形"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 作用:整型变量表示的是整数类型的数据。\n",
|
||||
"\n",
|
||||
"② C++中能够表示整形的类型有以下几种方式,区别在于所占内存空间不同。\n",
|
||||
"\n",
|
||||
"③ 数据类型 占用空间 取值范围\n",
|
||||
"\n",
|
||||
"1. short(短整型) 2字节 -2^15-2^15-1\n",
|
||||
"2. int(整型) 4字节 -2^31-2^31-1\n",
|
||||
"3. long(长整型) Windows为4字节,Linux为4字节(32位),8字节(64位) -2^31-2^31-1\n",
|
||||
"4. long long(长长整型) 8字节 -2^63-2^63-1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //1、短整型(-32768~32767)\n",
|
||||
" short num1 = 10;\n",
|
||||
" short num5 = 32768; //溢出了,打印出来是-23768\n",
|
||||
" short num6 = 32770; //溢出了,打印出来是-32766\n",
|
||||
"\n",
|
||||
" //2、整型\n",
|
||||
" int num2 = 10;\n",
|
||||
"\n",
|
||||
" //3、长整型\n",
|
||||
" long num3 = 10;\n",
|
||||
"\n",
|
||||
" //4、长长整型\n",
|
||||
" long long num4 = 10;\n",
|
||||
"\n",
|
||||
" cout << \"num1 = :\" << num1 << endl;\n",
|
||||
" cout << \"num2 = :\" << num2 << endl;\n",
|
||||
" cout << \"num3 = :\" << num3 << endl;\n",
|
||||
" cout << \"num4 = :\" << num4 << endl;\n",
|
||||
" cout << \"num5 = :\" << num5 << endl;\n",
|
||||
" cout << \"num6 = :\" << num6 << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - num1 = :10 \n",
|
||||
" - num2 = :10 \n",
|
||||
" - num3 = :10 \n",
|
||||
" - num4 = :10 \n",
|
||||
" - num5 = :-32768 \n",
|
||||
" - num6 = :-32766 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.2 实型(浮点型)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 作用:用于表示小数。\n",
|
||||
"\n",
|
||||
"② 浮点型变量分为下面两种,两个的区别在于表示有效数字范围不同。\n",
|
||||
"\n",
|
||||
"1. 单精度float\n",
|
||||
"2. 双精度double\n",
|
||||
"\n",
|
||||
"③ 数据类型 占用字节 有效数字范围\n",
|
||||
"\n",
|
||||
"1. float 4字节 7位有效数字\n",
|
||||
"2. double 8字节 15-16位有效数字"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### 1.2.1 单精度、双精度"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //1、单精度 float\n",
|
||||
" //2、双精度 double\n",
|
||||
" //默认情况下,无论单精度还是双精度,都只会显示6位有效数字\n",
|
||||
" float f1 = 3.1415926; //默认为双精度,前面加float相当于把双精度转换为单精度\n",
|
||||
" float f2 = 3.1415926f; //后面加一个f,直接创建的是单精度\n",
|
||||
"\n",
|
||||
" cout << \"f1 = :\" << f1 << endl;\n",
|
||||
"\n",
|
||||
" double d1 = 3.1415926;\n",
|
||||
"\n",
|
||||
" cout << \"d1 = :\" << d1 << endl;\n",
|
||||
"\n",
|
||||
" cout << \"float 占用内存空间为\" << sizeof(float) << endl;\n",
|
||||
" cout << \"double 占用内层空间为\" << sizeof(double) << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - f1 = :3.14159 \n",
|
||||
" - d1 = :3.14159 \n",
|
||||
" - float 占用内存空间为4 \n",
|
||||
" - double 占用内层空间为8 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### 1.2.2 科学计数法"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //科学计数法\n",
|
||||
" float f3 = 3e2; // 3 * (10 ^ 2)\n",
|
||||
" cout << \"f3 = :\" << f3 << endl;\n",
|
||||
"\n",
|
||||
" float f4 = 3e-2; // 3 * (0.1 ^ 2)\n",
|
||||
" cout << \"f4 = :\" << f4 << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - f3 = :300 \n",
|
||||
" - f4 = :0.03 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.3 字符型"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 字符型变量用于显示单个字符。\n",
|
||||
"\n",
|
||||
"② 语法:char ch = 'a';\n",
|
||||
"\n",
|
||||
"③ 在显示字符型变量时,用单引号字符括起来,不要用双引号。\n",
|
||||
"\n",
|
||||
"④ 单引号内只能有一个字符,不可以是字符串。\n",
|
||||
"\n",
|
||||
"⑤ C和C++中字符型变量只占用1个字节。\n",
|
||||
"\n",
|
||||
"⑥ 字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放入到存储单元。\n",
|
||||
"\n",
|
||||
"⑦ ASCII码大致由以下两部分组成:\n",
|
||||
"\n",
|
||||
"1. ASCII非打印控制字符:ASCII表上的数字0-31分配给了控制字符,用于控制像打印机等一些外围设备。\n",
|
||||
"2. ASCII打印字符:数字21-126分配给了能在键盘上找到的字符,当查看或打印文档时就会出现。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
"\n",
|
||||
" //1、字符型变量创建方式\n",
|
||||
" char ch = 'a';\n",
|
||||
" cout << ch << endl;\n",
|
||||
"\n",
|
||||
" //2、字符型变量所占内存大小\n",
|
||||
" cout << \"char字符型变量所占内存:\" << sizeof(char) << endl;\n",
|
||||
"\n",
|
||||
" //3、字符型变量常见错误\n",
|
||||
" char ch2 = 'b'; //创建字符型变量时候,要用单引号\n",
|
||||
" //char ch3 = \"b\"; //错误,创建字符型变量时候,不能用双引号\n",
|
||||
" //char ch4 = 'abcdef'; //错误,创建字符型变量时候,单引号内只能有一个字符\n",
|
||||
"\n",
|
||||
" //4、字符型变量对应ASCII编码\n",
|
||||
" cout << (int)ch << endl; // (int)ch 为字符'a'的ASCIII码值\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - a \n",
|
||||
" - char字符型变量所占内存:1 \n",
|
||||
" - 97 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.4 字符串型"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 用于表示一串字符。\n",
|
||||
"\n",
|
||||
"② 字符串型有两种风格\n",
|
||||
"\n",
|
||||
"③ C风格字符串:char 变量名[] = \"字符串值\"\n",
|
||||
"\n",
|
||||
"④ C++风格字符串:string 变量名 = \"字符串值\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include <string> //用C++风格字符串时候,要包含这个头文件\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
"\n",
|
||||
" //1、C风格字符串\n",
|
||||
" //char 字符 = 这是一个字符\n",
|
||||
" //char 字符[] = 这是一个字符串\n",
|
||||
" //表示字符串时,等号后面,要用双引号\n",
|
||||
"\n",
|
||||
" char str[] = \"hello world\";\n",
|
||||
" cout << str << endl;\n",
|
||||
"\n",
|
||||
" //2、C++风格字符串\n",
|
||||
" string str2 = \"hello world\";\n",
|
||||
" cout << str2 << endl;\n",
|
||||
" \n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - hello world \n",
|
||||
" - hello world \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.5 布尔类型 bool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 布尔数据类型代表真或假的值。\n",
|
||||
"\n",
|
||||
"② bool类型只有两个值:\n",
|
||||
"\n",
|
||||
"1. true -- 真 (本质是1)\n",
|
||||
"2. false -- 假(本质是0)\n",
|
||||
"\n",
|
||||
"③ bool类型占1个字节大小"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
"\n",
|
||||
" //1、创建bool数据类型\n",
|
||||
"\n",
|
||||
" bool flag1 = true; //true代表真\n",
|
||||
" cout << flag1 << endl;\n",
|
||||
" \n",
|
||||
" bool flag2 = false; //flag 代表假\n",
|
||||
" cout << flag2 << endl;\n",
|
||||
" \n",
|
||||
" //本质上 1代表真 0代表假\n",
|
||||
"\n",
|
||||
" //2、查看bool类型所占空间\n",
|
||||
" cout << \"bool所占内存空间:\" << sizeof(flag1) << endl;\n",
|
||||
" cout << \"bool所占内存空间:\" << sizeof(flag2) << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 1 \n",
|
||||
" - 0 \n",
|
||||
" - bool所占内存空间:1 \n",
|
||||
" - bool所占内存空间:1 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
284
docs/CPlusPlus-main/08_C++的数据类型.md
Normal file
@ -0,0 +1,284 @@
|
||||
# C++的数据类型
|
||||
|
||||
# 1. 数据类型
|
||||
|
||||
## 1.1 整形
|
||||
|
||||
① 作用:整型变量表示的是整数类型的数据。
|
||||
|
||||
② C++中能够表示整形的类型有以下几种方式,区别在于所占内存空间不同。
|
||||
|
||||
③ 数据类型 占用空间 取值范围
|
||||
|
||||
1. short(短整型) 2字节 -2^15-2^15-1
|
||||
2. int(整型) 4字节 -2^31-2^31-1
|
||||
3. long(长整型) Windows为4字节,Linux为4字节(32位),8字节(64位) -2^31-2^31-1
|
||||
4. long long(长长整型) 8字节 -2^63-2^63-1
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//1、短整型(-32768~32767)
|
||||
short num1 = 10;
|
||||
short num5 = 32768; //溢出了,打印出来是-23768
|
||||
short num6 = 32770; //溢出了,打印出来是-32766
|
||||
|
||||
//2、整型
|
||||
int num2 = 10;
|
||||
|
||||
//3、长整型
|
||||
long num3 = 10;
|
||||
|
||||
//4、长长整型
|
||||
long long num4 = 10;
|
||||
|
||||
cout << "num1 = :" << num1 << endl;
|
||||
cout << "num2 = :" << num2 << endl;
|
||||
cout << "num3 = :" << num3 << endl;
|
||||
cout << "num4 = :" << num4 << endl;
|
||||
cout << "num5 = :" << num5 << endl;
|
||||
cout << "num6 = :" << num6 << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- num1 = :10
|
||||
- num2 = :10
|
||||
- num3 = :10
|
||||
- num4 = :10
|
||||
- num5 = :-32768
|
||||
- num6 = :-32766
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.2 实型(浮点型)
|
||||
|
||||
① 作用:用于表示小数。
|
||||
|
||||
② 浮点型变量分为下面两种,两个的区别在于表示有效数字范围不同。
|
||||
|
||||
1. 单精度float
|
||||
2. 双精度double
|
||||
|
||||
③ 数据类型 占用字节 有效数字范围
|
||||
|
||||
1. float 4字节 7位有效数字
|
||||
2. double 8字节 15-16位有效数字
|
||||
|
||||
### 1.2.1 单精度、双精度
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//1、单精度 float
|
||||
//2、双精度 double
|
||||
//默认情况下,无论单精度还是双精度,都只会显示6位有效数字
|
||||
float f1 = 3.1415926; //默认为双精度,前面加float相当于把双精度转换为单精度
|
||||
float f2 = 3.1415926f; //后面加一个f,直接创建的是单精度
|
||||
|
||||
cout << "f1 = :" << f1 << endl;
|
||||
|
||||
double d1 = 3.1415926;
|
||||
|
||||
cout << "d1 = :" << d1 << endl;
|
||||
|
||||
cout << "float 占用内存空间为" << sizeof(float) << endl;
|
||||
cout << "double 占用内层空间为" << sizeof(double) << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- f1 = :3.14159
|
||||
- d1 = :3.14159
|
||||
- float 占用内存空间为4
|
||||
- double 占用内层空间为8
|
||||
- 请按任意键继续. . .
|
||||
|
||||
### 1.2.2 科学计数法
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//科学计数法
|
||||
float f3 = 3e2; // 3 * (10 ^ 2)
|
||||
cout << "f3 = :" << f3 << endl;
|
||||
|
||||
float f4 = 3e-2; // 3 * (0.1 ^ 2)
|
||||
cout << "f4 = :" << f4 << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- f3 = :300
|
||||
- f4 = :0.03
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.3 字符型
|
||||
|
||||
① 字符型变量用于显示单个字符。
|
||||
|
||||
② 语法:char ch = 'a';
|
||||
|
||||
③ 在显示字符型变量时,用单引号字符括起来,不要用双引号。
|
||||
|
||||
④ 单引号内只能有一个字符,不可以是字符串。
|
||||
|
||||
⑤ C和C++中字符型变量只占用1个字节。
|
||||
|
||||
⑥ 字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放入到存储单元。
|
||||
|
||||
⑦ ASCII码大致由以下两部分组成:
|
||||
|
||||
1. ASCII非打印控制字符:ASCII表上的数字0-31分配给了控制字符,用于控制像打印机等一些外围设备。
|
||||
2. ASCII打印字符:数字21-126分配给了能在键盘上找到的字符,当查看或打印文档时就会出现。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
//1、字符型变量创建方式
|
||||
char ch = 'a';
|
||||
cout << ch << endl;
|
||||
|
||||
//2、字符型变量所占内存大小
|
||||
cout << "char字符型变量所占内存:" << sizeof(char) << endl;
|
||||
|
||||
//3、字符型变量常见错误
|
||||
char ch2 = 'b'; //创建字符型变量时候,要用单引号
|
||||
//char ch3 = "b"; //错误,创建字符型变量时候,不能用双引号
|
||||
//char ch4 = 'abcdef'; //错误,创建字符型变量时候,单引号内只能有一个字符
|
||||
|
||||
//4、字符型变量对应ASCII编码
|
||||
cout << (int)ch << endl; // (int)ch 为字符'a'的ASCIII码值
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- a
|
||||
- char字符型变量所占内存:1
|
||||
- 97
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.4 字符串型
|
||||
|
||||
① 用于表示一串字符。
|
||||
|
||||
② 字符串型有两种风格
|
||||
|
||||
③ C风格字符串:char 变量名[] = "字符串值"
|
||||
|
||||
④ C++风格字符串:string 变量名 = "字符串值"
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string> //用C++风格字符串时候,要包含这个头文件
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
//1、C风格字符串
|
||||
//char 字符 = 这是一个字符
|
||||
//char 字符[] = 这是一个字符串
|
||||
//表示字符串时,等号后面,要用双引号
|
||||
|
||||
char str[] = "hello world";
|
||||
cout << str << endl;
|
||||
|
||||
//2、C++风格字符串
|
||||
string str2 = "hello world";
|
||||
cout << str2 << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- hello world
|
||||
- hello world
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.5 布尔类型 bool
|
||||
|
||||
① 布尔数据类型代表真或假的值。
|
||||
|
||||
② bool类型只有两个值:
|
||||
|
||||
1. true -- 真 (本质是1)
|
||||
2. false -- 假(本质是0)
|
||||
|
||||
③ bool类型占1个字节大小
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
//1、创建bool数据类型
|
||||
|
||||
bool flag1 = true; //true代表真
|
||||
cout << flag1 << endl;
|
||||
|
||||
bool flag2 = false; //flag 代表假
|
||||
cout << flag2 << endl;
|
||||
|
||||
//本质上 1代表真 0代表假
|
||||
|
||||
//2、查看bool类型所占空间
|
||||
cout << "bool所占内存空间:" << sizeof(flag1) << endl;
|
||||
cout << "bool所占内存空间:" << sizeof(flag2) << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 1
|
||||
- 0
|
||||
- bool所占内存空间:1
|
||||
- bool所占内存空间:1
|
||||
- 请按任意键继续. . .
|
||||
106
docs/CPlusPlus-main/09_C++的转义字符.ipynb
Normal file
@ -0,0 +1,106 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的转义字符"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 转义字符"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 用于表示一些不能显示出来的ASCII字符。\n",
|
||||
"\n",
|
||||
"② 我们常用的转义字符有:\\n、\\\\、\\t。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
"\n",
|
||||
" //换行符 \\n\n",
|
||||
"\n",
|
||||
" cout << \"hello world\\n\";\n",
|
||||
"\n",
|
||||
" //反斜杠 \\\\ 要输出反斜杠\\时,要在前面加上一个反斜杠\n",
|
||||
"\n",
|
||||
" cout << \"\\\\\" << endl;\n",
|
||||
"\n",
|
||||
" //水平制表符\\t 可以整齐的输出数据\n",
|
||||
" cout << \"aaaa\\thellowworld\" << endl;\n",
|
||||
" cout << \"aa\\thellowworld\" << endl;\n",
|
||||
" cout << \"aaaaaa\\thellowworld\" << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果:\n",
|
||||
" - hello world\n",
|
||||
" - \\\n",
|
||||
" - aaaa hellowworld\n",
|
||||
" - aa hellowworld\n",
|
||||
" - aaaaaa hellowworld\n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
43
docs/CPlusPlus-main/09_C++的转义字符.md
Normal file
@ -0,0 +1,43 @@
|
||||
# C++的转义字符
|
||||
|
||||
# 1. 转义字符
|
||||
|
||||
① 用于表示一些不能显示出来的ASCII字符。
|
||||
|
||||
② 我们常用的转义字符有:\n、\\、\t。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
//换行符 \n
|
||||
|
||||
cout << "hello world\n";
|
||||
|
||||
//反斜杠 \\ 要输出反斜杠\时,要在前面加上一个反斜杠
|
||||
|
||||
cout << "\\" << endl;
|
||||
|
||||
//水平制表符\t 可以整齐的输出数据
|
||||
cout << "aaaa\thellowworld" << endl;
|
||||
cout << "aa\thellowworld" << endl;
|
||||
cout << "aaaaaa\thellowworld" << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- hello world
|
||||
- \
|
||||
- aaaa hellowworld
|
||||
- aa hellowworld
|
||||
- aaaaaa hellowworld
|
||||
- 请按任意键继续. . .
|
||||
135
docs/CPlusPlus-main/10_C++的数据输入.ipynb
Normal file
@ -0,0 +1,135 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的数据输入"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 数据输入"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 数据的输入,作用:用于从键盘获取数据。\n",
|
||||
"\n",
|
||||
"② 数据的输入,关键字:cin\n",
|
||||
"\n",
|
||||
"③ 数据饿输入,语法:cin >> 变量"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include <string> //包含string的头文件\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
"\n",
|
||||
" //1、创建bool数据类型\n",
|
||||
" int a = 0;\n",
|
||||
" cout << \"请给整型变量 a 赋值:\" << endl;\n",
|
||||
" cin >> a;\n",
|
||||
" cout << \"整型变量a = \" << a << endl;\n",
|
||||
"\n",
|
||||
" //2、浮点型\n",
|
||||
" float f = 3.14f;\n",
|
||||
" cout << \"请给浮点型变量 f 赋值:\" << endl;\n",
|
||||
" cin >> f;\n",
|
||||
" cout << \"浮点型变量 f = \" << f << endl;\n",
|
||||
"\n",
|
||||
" //3、字符型\n",
|
||||
" char ch ; //仅仅声明了,没有初始化\n",
|
||||
" cout << \"请给字符型变量 ch 赋值:\" << endl;\n",
|
||||
" cin >> ch;\n",
|
||||
" cout << \"字符型变量 ch = \" << ch << endl;\n",
|
||||
"\n",
|
||||
" //4、字符型\n",
|
||||
" string str = \"hello\";\n",
|
||||
" cout << \"请给字符串 str 赋值:\" << endl;\n",
|
||||
" cin >> str;\n",
|
||||
" cout << \"字符型变量 str = \" << str << endl;\n",
|
||||
"\n",
|
||||
" //4、布尔型\n",
|
||||
" bool flag = false;\n",
|
||||
" cout << \"请给布尔类型 flag 赋值:\" << endl;\n",
|
||||
" cin >> flag; //布尔类型 只要是非0的值都代表真\n",
|
||||
" cout << \"布尔类型 flag = \" << flag << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 请给整型变量 a 赋值:\n",
|
||||
" - 23\n",
|
||||
" - 整型变量a = 23\n",
|
||||
" - 请给浮点型变量 f 赋值:\n",
|
||||
" - 23.4\n",
|
||||
" - 浮点型变量 f = 23.4\n",
|
||||
" - 请给字符型变量 ch 赋值:\n",
|
||||
" - w\n",
|
||||
" - 字符型变量 ch = w\n",
|
||||
" - 请给字符串 str 赋值:\n",
|
||||
" - asfg\n",
|
||||
" - 字符型变量 str = asfg\n",
|
||||
" - 请给布尔类型 flag 赋值:\n",
|
||||
" - 4562\n",
|
||||
" - 布尔类型 flag = 1\n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
72
docs/CPlusPlus-main/10_C++的数据输入.md
Normal file
@ -0,0 +1,72 @@
|
||||
# C++的数据输入
|
||||
|
||||
# 1. 数据输入
|
||||
|
||||
① 数据的输入,作用:用于从键盘获取数据。
|
||||
|
||||
② 数据的输入,关键字:cin
|
||||
|
||||
③ 数据饿输入,语法:cin >> 变量
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string> //包含string的头文件
|
||||
int main()
|
||||
{
|
||||
|
||||
//1、创建bool数据类型
|
||||
int a = 0;
|
||||
cout << "请给整型变量 a 赋值:" << endl;
|
||||
cin >> a;
|
||||
cout << "整型变量a = " << a << endl;
|
||||
|
||||
//2、浮点型
|
||||
float f = 3.14f;
|
||||
cout << "请给浮点型变量 f 赋值:" << endl;
|
||||
cin >> f;
|
||||
cout << "浮点型变量 f = " << f << endl;
|
||||
|
||||
//3、字符型
|
||||
char ch ; //仅仅声明了,没有初始化
|
||||
cout << "请给字符型变量 ch 赋值:" << endl;
|
||||
cin >> ch;
|
||||
cout << "字符型变量 ch = " << ch << endl;
|
||||
|
||||
//4、字符型
|
||||
string str = "hello";
|
||||
cout << "请给字符串 str 赋值:" << endl;
|
||||
cin >> str;
|
||||
cout << "字符型变量 str = " << str << endl;
|
||||
|
||||
//4、布尔型
|
||||
bool flag = false;
|
||||
cout << "请给布尔类型 flag 赋值:" << endl;
|
||||
cin >> flag; //布尔类型 只要是非0的值都代表真
|
||||
cout << "布尔类型 flag = " << flag << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 请给整型变量 a 赋值:
|
||||
- 23
|
||||
- 整型变量a = 23
|
||||
- 请给浮点型变量 f 赋值:
|
||||
- 23.4
|
||||
- 浮点型变量 f = 23.4
|
||||
- 请给字符型变量 ch 赋值:
|
||||
- w
|
||||
- 字符型变量 ch = w
|
||||
- 请给字符串 str 赋值:
|
||||
- asfg
|
||||
- 字符型变量 str = asfg
|
||||
- 请给布尔类型 flag 赋值:
|
||||
- 4562
|
||||
- 布尔类型 flag = 1
|
||||
- 请按任意键继续. . .
|
||||
481
docs/CPlusPlus-main/11_C++的运算符.ipynb
Normal file
@ -0,0 +1,481 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的运算符"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 运算符"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 运算符作用:用于执行代码的运算。\n",
|
||||
"\n",
|
||||
"② 运算符类型主要有四种:\n",
|
||||
"\n",
|
||||
"1. 算术运算符:用于处理四则运算。 \n",
|
||||
"2. 赋值运算符:用于将表达式的值赋给变量 \n",
|
||||
"3. 比较运算符:用于表达式的比较,并返回一个真值或假值。 \n",
|
||||
"4. 逻辑运算法:用于表达式的值返回真值或假值。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 2. 算术运算符"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2.1 加减乘除运算"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
"\n",
|
||||
" int a1 = 10;\n",
|
||||
" int b1 = 3;\n",
|
||||
"\n",
|
||||
" cout << a1 + b1 << endl;\n",
|
||||
" cout << a1 - b1 << endl;\n",
|
||||
" cout << a1 * b1 << endl;\n",
|
||||
" cout << a1 / b1 << endl; //两个整数相除,结果依然是整数,将小数部分去除\n",
|
||||
"\n",
|
||||
" int a2 = 10;\n",
|
||||
" int b2 = 20;\n",
|
||||
"\n",
|
||||
" cout << a2 / b2 << endl;\n",
|
||||
"\n",
|
||||
" int a3 = 10;\n",
|
||||
" int b3 = 0;\n",
|
||||
"\n",
|
||||
" //cout << a3 / b3 << endl; //两个数相除,除数不可以为0\n",
|
||||
"\n",
|
||||
" //两个小数可以相除\n",
|
||||
" double d1 = 0.51; //如果d1为0.5,运算结果为整数2\n",
|
||||
" double d2 = 0.25;\n",
|
||||
" \n",
|
||||
" cout << d1 / d2 << endl; //运算结果也可以是小数\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 13 \n",
|
||||
" - 7 \n",
|
||||
" - 30 \n",
|
||||
" - 3 \n",
|
||||
" - 0 \n",
|
||||
" - 2.04 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2.2 取模运算"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //取摸运算本质 就是求余数\n",
|
||||
" int a1 = 10;\n",
|
||||
" int b1 = 3;\n",
|
||||
"\n",
|
||||
" cout << a1 % b1 << endl;\n",
|
||||
"\n",
|
||||
" /*两个数相除,除数不可以为0,所以也做不了取模运算\n",
|
||||
" int a2 = 10;\n",
|
||||
" int b2 = 0;\n",
|
||||
"\n",
|
||||
" cout << a2 % b2 << endl; //\n",
|
||||
" */\n",
|
||||
"\n",
|
||||
" /*两个小数是不可以做取模运算的\n",
|
||||
" double d1 = 3.14;\n",
|
||||
" double d2 = 1.1;\n",
|
||||
"\n",
|
||||
" cout << d1 % d2 << endl;\n",
|
||||
" */\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 1 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2.3 递增递减运算"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //1、前置递增\n",
|
||||
"\n",
|
||||
" int a = 10;\n",
|
||||
" ++a;\n",
|
||||
" cout << \"a=\" << a << endl;\n",
|
||||
"\n",
|
||||
" //2、后置递增\n",
|
||||
"\n",
|
||||
" int b = 15;\n",
|
||||
" b++;\n",
|
||||
" cout << \"b=\" << b << endl;\n",
|
||||
"\n",
|
||||
" //3、前置和后置的区别\n",
|
||||
" //前置递增,先让变量+1 然后进行表达式运算\n",
|
||||
" int a2 = 10;\n",
|
||||
" int b2 = ++a2 * 10;\n",
|
||||
" cout << \"a2= \" << a2 << endl;\n",
|
||||
" cout << \"b2= \" << b2 << endl;\n",
|
||||
"\n",
|
||||
" //后置递增,先进行表达式运算,后让变量+1\n",
|
||||
" int a3 = 10;\n",
|
||||
" int b3 = a3++ * 10;\n",
|
||||
" cout << \"a3= \" << a3 << endl;\n",
|
||||
" cout << \"b3= \" << b3 << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - a=11 \n",
|
||||
" - b=16 \n",
|
||||
" - a2= 11 \n",
|
||||
" - b2= 110 \n",
|
||||
" - a3= 11 \n",
|
||||
" - b3= 100 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 3. 赋值运算符"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
"\n",
|
||||
" // = 赋值\n",
|
||||
" int a = 10;\n",
|
||||
" a = 100;\n",
|
||||
" cout << \"a= \" << a << endl;\n",
|
||||
"\n",
|
||||
" // += 加等于\n",
|
||||
" int b = 10;\n",
|
||||
" b = 10;\n",
|
||||
" b += 2;\n",
|
||||
" cout << \"b= \" << b << endl;\n",
|
||||
"\n",
|
||||
" // -= 减等于\n",
|
||||
" int c = 10;\n",
|
||||
" c = 10;\n",
|
||||
" c -= 2;\n",
|
||||
" cout << \"c= \" << c << endl;\n",
|
||||
"\n",
|
||||
" // *= 乘等于\n",
|
||||
" int d = 10;\n",
|
||||
" d = 10;\n",
|
||||
" d *= 2;\n",
|
||||
" cout << \"d= \" << d << endl;\n",
|
||||
"\n",
|
||||
" // /= 除等于\n",
|
||||
" int e = 10;\n",
|
||||
" e = 10;\n",
|
||||
" e /= 2;\n",
|
||||
" cout << \"e= \" << e << endl;\n",
|
||||
" \n",
|
||||
" // %= 模等于\n",
|
||||
" int f = 10;\n",
|
||||
" f = 10;\n",
|
||||
" f %= 2;\n",
|
||||
" cout << \"f= \" << f << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - a= 100 \n",
|
||||
" - b= 12 \n",
|
||||
" - c= 8 \n",
|
||||
" - d= 20 \n",
|
||||
" - e= 5 \n",
|
||||
" - f= 0 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 4. 比较运算符"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 作用:用于表达式的比较,并返回一个真值或假值。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //比较运算符\n",
|
||||
" \n",
|
||||
" // ==\n",
|
||||
" int a = 10;\n",
|
||||
" int b = 20;\n",
|
||||
" cout << (a == b) << endl;\n",
|
||||
"\n",
|
||||
" // !=\n",
|
||||
" cout << (a != b) << endl;\n",
|
||||
"\n",
|
||||
" // >\n",
|
||||
" cout << (a > b) << endl;\n",
|
||||
"\n",
|
||||
" // <\n",
|
||||
" cout << (a < b) << endl;\n",
|
||||
"\n",
|
||||
" // >=\n",
|
||||
" cout << (a >= b) << endl;\n",
|
||||
" \n",
|
||||
" // <=\n",
|
||||
" cout << (a <= b) << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 0 \n",
|
||||
" - 1 \n",
|
||||
" - 0 \n",
|
||||
" - 1 \n",
|
||||
" - 0 \n",
|
||||
" - 1 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 5. 逻辑运算符"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 作用:用于根据表达式的值返回真值或假值。\n",
|
||||
"\n",
|
||||
"1. !a 表示非,如果a为假,则!a为真;如果a为真,则!a为假。\n",
|
||||
"2. a&&b 表示与,如果a和b都为真,则结果为真,否则为假。\n",
|
||||
"3. a||b 表示或,如果a和b有一个为真,则结果为真,二者都为假时,结果为假。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //逻辑运算符\n",
|
||||
"\n",
|
||||
" // !=\n",
|
||||
" int a = 10;\n",
|
||||
" int b = 30;\n",
|
||||
"\n",
|
||||
" cout << (!a) << endl; //在C++中除了0,都为真\n",
|
||||
" cout << (!!a) << endl;\n",
|
||||
"\n",
|
||||
" // &&\n",
|
||||
" a = 10;\n",
|
||||
" b = 30;\n",
|
||||
"\n",
|
||||
" cout << (a && b) << endl;\n",
|
||||
"\n",
|
||||
" a = 0;\n",
|
||||
" b = 10;\n",
|
||||
" cout << (a && b) << endl;\n",
|
||||
"\n",
|
||||
" // ||\n",
|
||||
" a = 10;\n",
|
||||
" b = 30;\n",
|
||||
" cout << (a || b) << endl;\n",
|
||||
"\n",
|
||||
" a = 0;\n",
|
||||
" b = 10;\n",
|
||||
" cout << (a || b) << endl;\n",
|
||||
"\n",
|
||||
" a = 0;\n",
|
||||
" b = 0;\n",
|
||||
" cout << (a || b) << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 0 \n",
|
||||
" - 1 \n",
|
||||
" - 1 \n",
|
||||
" - 0 \n",
|
||||
" - 1 \n",
|
||||
" - 1 \n",
|
||||
" - 0 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
328
docs/CPlusPlus-main/11_C++的运算符.md
Normal file
@ -0,0 +1,328 @@
|
||||
# C++的运算符
|
||||
|
||||
# 1. 运算符
|
||||
|
||||
① 运算符作用:用于执行代码的运算。
|
||||
|
||||
② 运算符类型主要有四种:
|
||||
|
||||
1. 算术运算符:用于处理四则运算。
|
||||
2. 赋值运算符:用于将表达式的值赋给变量
|
||||
3. 比较运算符:用于表达式的比较,并返回一个真值或假值。
|
||||
4. 逻辑运算法:用于表达式的值返回真值或假值。
|
||||
|
||||
# 2. 算术运算符
|
||||
|
||||
## 2.1 加减乘除运算
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
int a1 = 10;
|
||||
int b1 = 3;
|
||||
|
||||
cout << a1 + b1 << endl;
|
||||
cout << a1 - b1 << endl;
|
||||
cout << a1 * b1 << endl;
|
||||
cout << a1 / b1 << endl; //两个整数相除,结果依然是整数,将小数部分去除
|
||||
|
||||
int a2 = 10;
|
||||
int b2 = 20;
|
||||
|
||||
cout << a2 / b2 << endl;
|
||||
|
||||
int a3 = 10;
|
||||
int b3 = 0;
|
||||
|
||||
//cout << a3 / b3 << endl; //两个数相除,除数不可以为0
|
||||
|
||||
//两个小数可以相除
|
||||
double d1 = 0.51; //如果d1为0.5,运算结果为整数2
|
||||
double d2 = 0.25;
|
||||
|
||||
cout << d1 / d2 << endl; //运算结果也可以是小数
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 13
|
||||
- 7
|
||||
- 30
|
||||
- 3
|
||||
- 0
|
||||
- 2.04
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 2.2 取模运算
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//取摸运算本质 就是求余数
|
||||
int a1 = 10;
|
||||
int b1 = 3;
|
||||
|
||||
cout << a1 % b1 << endl;
|
||||
|
||||
/*两个数相除,除数不可以为0,所以也做不了取模运算
|
||||
int a2 = 10;
|
||||
int b2 = 0;
|
||||
|
||||
cout << a2 % b2 << endl; //
|
||||
*/
|
||||
|
||||
/*两个小数是不可以做取模运算的
|
||||
double d1 = 3.14;
|
||||
double d2 = 1.1;
|
||||
|
||||
cout << d1 % d2 << endl;
|
||||
*/
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 1
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 2.3 递增递减运算
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//1、前置递增
|
||||
|
||||
int a = 10;
|
||||
++a;
|
||||
cout << "a=" << a << endl;
|
||||
|
||||
//2、后置递增
|
||||
|
||||
int b = 15;
|
||||
b++;
|
||||
cout << "b=" << b << endl;
|
||||
|
||||
//3、前置和后置的区别
|
||||
//前置递增,先让变量+1 然后进行表达式运算
|
||||
int a2 = 10;
|
||||
int b2 = ++a2 * 10;
|
||||
cout << "a2= " << a2 << endl;
|
||||
cout << "b2= " << b2 << endl;
|
||||
|
||||
//后置递增,先进行表达式运算,后让变量+1
|
||||
int a3 = 10;
|
||||
int b3 = a3++ * 10;
|
||||
cout << "a3= " << a3 << endl;
|
||||
cout << "b3= " << b3 << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- a=11
|
||||
- b=16
|
||||
- a2= 11
|
||||
- b2= 110
|
||||
- a3= 11
|
||||
- b3= 100
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 3. 赋值运算符
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
// = 赋值
|
||||
int a = 10;
|
||||
a = 100;
|
||||
cout << "a= " << a << endl;
|
||||
|
||||
// += 加等于
|
||||
int b = 10;
|
||||
b = 10;
|
||||
b += 2;
|
||||
cout << "b= " << b << endl;
|
||||
|
||||
// -= 减等于
|
||||
int c = 10;
|
||||
c = 10;
|
||||
c -= 2;
|
||||
cout << "c= " << c << endl;
|
||||
|
||||
// *= 乘等于
|
||||
int d = 10;
|
||||
d = 10;
|
||||
d *= 2;
|
||||
cout << "d= " << d << endl;
|
||||
|
||||
// /= 除等于
|
||||
int e = 10;
|
||||
e = 10;
|
||||
e /= 2;
|
||||
cout << "e= " << e << endl;
|
||||
|
||||
// %= 模等于
|
||||
int f = 10;
|
||||
f = 10;
|
||||
f %= 2;
|
||||
cout << "f= " << f << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- a= 100
|
||||
- b= 12
|
||||
- c= 8
|
||||
- d= 20
|
||||
- e= 5
|
||||
- f= 0
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 4. 比较运算符
|
||||
|
||||
① 作用:用于表达式的比较,并返回一个真值或假值。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//比较运算符
|
||||
|
||||
// ==
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
cout << (a == b) << endl;
|
||||
|
||||
// !=
|
||||
cout << (a != b) << endl;
|
||||
|
||||
// >
|
||||
cout << (a > b) << endl;
|
||||
|
||||
// <
|
||||
cout << (a < b) << endl;
|
||||
|
||||
// >=
|
||||
cout << (a >= b) << endl;
|
||||
|
||||
// <=
|
||||
cout << (a <= b) << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 0
|
||||
- 1
|
||||
- 0
|
||||
- 1
|
||||
- 0
|
||||
- 1
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 5. 逻辑运算符
|
||||
|
||||
① 作用:用于根据表达式的值返回真值或假值。
|
||||
|
||||
1. !a 表示非,如果a为假,则!a为真;如果a为真,则!a为假。
|
||||
2. a&&b 表示与,如果a和b都为真,则结果为真,否则为假。
|
||||
3. a||b 表示或,如果a和b有一个为真,则结果为真,二者都为假时,结果为假。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//逻辑运算符
|
||||
|
||||
// !=
|
||||
int a = 10;
|
||||
int b = 30;
|
||||
|
||||
cout << (!a) << endl; //在C++中除了0,都为真
|
||||
cout << (!!a) << endl;
|
||||
|
||||
// &&
|
||||
a = 10;
|
||||
b = 30;
|
||||
|
||||
cout << (a && b) << endl;
|
||||
|
||||
a = 0;
|
||||
b = 10;
|
||||
cout << (a && b) << endl;
|
||||
|
||||
// ||
|
||||
a = 10;
|
||||
b = 30;
|
||||
cout << (a || b) << endl;
|
||||
|
||||
a = 0;
|
||||
b = 10;
|
||||
cout << (a || b) << endl;
|
||||
|
||||
a = 0;
|
||||
b = 0;
|
||||
cout << (a || b) << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 0
|
||||
- 1
|
||||
- 1
|
||||
- 0
|
||||
- 1
|
||||
- 1
|
||||
- 0
|
||||
- 请按任意键继续. . .
|
||||
1589
docs/CPlusPlus-main/12_C++的程序流程结构.ipynb
Normal file
1173
docs/CPlusPlus-main/12_C++的程序流程结构.md
Normal file
763
docs/CPlusPlus-main/13_C++的数组.ipynb
Normal file
533
docs/CPlusPlus-main/13_C++的数组.md
Normal file
@ -0,0 +1,533 @@
|
||||
# C++的数组
|
||||
|
||||
# 1. 数组特点
|
||||
|
||||
① 所谓数组,就是一个集合,里面存放了相同类型的数据元素。
|
||||
|
||||
1. 特点1:数组中每个元素都是相同的数据类型。
|
||||
2. 特点2:数组是由连续的内存位置组成的。
|
||||
|
||||
# 2. 一维数组
|
||||
|
||||
## 2.1 定义方式
|
||||
|
||||
① 一维数组定义:
|
||||
|
||||
1. 数组类型 数组名 [ 数组长度 ]
|
||||
2. 数组类型 数组名 [ 数组长度 ] = { 值1,值2,.... }
|
||||
3. 数组类型 数组名 [ ] = { 值1,值2,..... }
|
||||
|
||||
② 数组名的命名规范与变量名命名规范一致,不要和变量重名。
|
||||
|
||||
③ 数组中下标是从0开始索引。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//1、数组类型 数组名 [ 数组长度 ]
|
||||
int arr[5];
|
||||
//数组元素的下标是从0开始索引的
|
||||
//给数组中的元素进行赋值
|
||||
arr[0] = 10;
|
||||
arr[1] = 20;
|
||||
arr[2] = 30;
|
||||
arr[3] = 40;
|
||||
arr[4] = 50;
|
||||
|
||||
|
||||
//访问数据元素
|
||||
cout << arr[0] << endl;
|
||||
cout << arr[1] << endl;
|
||||
cout << arr[2] << endl;
|
||||
cout << arr[3] << endl;
|
||||
cout << arr[4] << endl;
|
||||
|
||||
//2、数据类型 数组名 [ 数组长度 ] = { 值1,值2,... }
|
||||
//如果在初始化数据的时候,没有完全填写完,会用0来填补剩余数据
|
||||
int arr2[5] = { 10,20,30 };
|
||||
|
||||
/*
|
||||
方式一:
|
||||
cout << arr2[0] << endl;
|
||||
cout << arr2[1] << endl;
|
||||
cout << arr2[2] << endl;
|
||||
cout << arr2[3] << endl;
|
||||
cout << arr2[4] << endl;
|
||||
*/
|
||||
|
||||
|
||||
// 方式二:利用循环输出数组中的元素
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
cout << arr2[i] << endl;
|
||||
}
|
||||
|
||||
//3、数据类型 数组名 [ ] = { 值1,值2,.... }
|
||||
int arr3[] = { 90,80,70,60,50,40,30,20,10 }; //以后自定义变量,不要 int arr3 = 100,这样避免以后调用arr3到底是调用变量还是数组产生模糊。
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
cout << arr3[i] << endl;
|
||||
}
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 10
|
||||
- 20
|
||||
- 30
|
||||
- 40
|
||||
- 50
|
||||
- 10
|
||||
- 20
|
||||
- 30
|
||||
- 0
|
||||
- 0
|
||||
- 90
|
||||
- 80
|
||||
- 70
|
||||
- 60
|
||||
- 50
|
||||
- 40
|
||||
- 30
|
||||
- 20
|
||||
- 10
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 2.2 数组名
|
||||
|
||||
① 一维数组名的用途:
|
||||
|
||||
1. 可以统计整个数组在内存中的长度。
|
||||
2. 可以获取数组在内存中的首地址。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//数组名用途
|
||||
//1、可以通过数组名统计整个数组占用内存大小
|
||||
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
|
||||
cout << "整个数组占用内存空间为:" << sizeof(arr) << endl;
|
||||
cout << "每个元素占用内存空间为:" << sizeof(arr[0]) << endl;
|
||||
cout << "数组中元素的个数为:" << sizeof(arr)/sizeof(arr[0]) << endl;
|
||||
|
||||
//2、可以通过数组名查看数组首地址
|
||||
cout << "数组首地址为:" << (int)arr << endl;
|
||||
cout << "数组中第一个元素地址为:" << (int)&arr[0] << endl; //int使得将十六位地址通过int转换为10位地址,&表示取址符号,取一个元素的首地址
|
||||
cout << "数组中第二个元素地址为:" << (int)&arr[1] << endl; //第二个元素和第一个元素差四个字节
|
||||
|
||||
//数组名是常量,值为数组首地址,不可以进行赋值操作
|
||||
//arr = 100; 不可以这样赋值修改
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 整个数组占用内存空间为:40
|
||||
- 每个元素占用内存空间为:4
|
||||
- 数组中元素的个数为:10
|
||||
- 数组首地址为:12582108
|
||||
- 数组中第一个元素地址为:12582108
|
||||
- 数组中第二个元素地址为:12582112
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 2.3 五只小猪称体重
|
||||
|
||||
案例描述:在一个数组中记录了五只小猪的体重,如:int arr[5]={300,350,200,400,250},找出并打印最重的小猪体重。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//1、创建5只小猪体重的数组
|
||||
int arr[5] = { 300,350,200,400,250 };
|
||||
|
||||
//2、从数组中找到最大值
|
||||
int max = 0; //先认定一个最大值为0
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
//cout << arr[i] << endl;
|
||||
if (arr[i] > max)
|
||||
{
|
||||
max = arr[i];
|
||||
}
|
||||
}
|
||||
|
||||
//3、打印最大值
|
||||
cout << max << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 400
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 2.4 数组元素逆置
|
||||
|
||||
案例描述:请声明一个5个元素的数组,并且将元素逆置。(如原数组元素为:1,3,2,5,4;逆置后输出的结果为:4,5,2,3,1)。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//实现数组元素逆置
|
||||
|
||||
//1、创建数组
|
||||
int arr[5] = { 1,3,2,5,4 };
|
||||
cout << "数组逆置前" << endl;
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
cout << arr[i] << endl;
|
||||
}
|
||||
//2、实现逆置
|
||||
//2.1 记录起始下标位置
|
||||
//2.2 记录结束下标位置
|
||||
//2.3 起始下标与结束下标的元素互换
|
||||
//2.4 起始位置++ 结束位置--
|
||||
//2.5 循环执行2.1操作,直到起始位置 >= 结束位置
|
||||
int start = 0; //起始下标
|
||||
int end = sizeof(arr) / sizeof(arr[0]) - 1; //结束下标,先计算除法
|
||||
|
||||
while (start < end)
|
||||
{
|
||||
int temp = arr[start];
|
||||
arr[start] = arr[end];
|
||||
arr[end] = temp;
|
||||
|
||||
//下标更新
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
|
||||
//3、打印逆置后的数组
|
||||
cout << "数组逆置后" << endl;
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
cout << arr[i] << endl;
|
||||
}
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 数组逆置前
|
||||
- 1
|
||||
- 3
|
||||
- 2
|
||||
- 5
|
||||
- 4
|
||||
- 数组逆置后
|
||||
- 4
|
||||
- 5
|
||||
- 2
|
||||
- 3
|
||||
- 1
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 2.5 冒泡排序
|
||||
|
||||
① 冒泡排序作用:最常用的排序算法,对数组内元素进行排序。
|
||||
|
||||
1. 比较相邻的元素,如果第一个比第二个大,就交换他们两个。
|
||||
2. 对每一对相邻元素做同样的go牛牛公主,执行完毕后,找到第一个最大值。
|
||||
3. 重复以上的步骤,每次比较次数-1.直到不需要比较。
|
||||
|
||||
② 示例:将数组(4,2,8,0,5,7,1,3,9)进行排序。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
int arr[9] = { 4,2,8,0,5,7,1,3,9 };
|
||||
cout << "排序前" << endl;
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
cout << arr[i] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
//开始冒泡排序
|
||||
for (int i = 0; i < 9 - 1; i++)
|
||||
{
|
||||
//内层循环对比 次数=元素个数=当前轮数-1
|
||||
for (int j = 0; j < 9 - 1 - i; j++) //最后一位数,已经是最大数了,不需要排序了
|
||||
{
|
||||
//如果第一个数字,比第二个数字大,交换两个数字
|
||||
if (arr[j] > arr[j + 1])
|
||||
{
|
||||
int temp = arr[j];
|
||||
arr[j] = arr[j+1];
|
||||
arr[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//排序后结果
|
||||
cout << "排序后" << endl;
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
cout << arr[i] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 排序前
|
||||
- 4 2 8 0 5 7 1 3 9
|
||||
- 排序后
|
||||
- 0 1 2 3 4 5 7 8 9
|
||||
- 请按任意键继续. . .
|
||||
|
||||
运行结果:
|
||||
|
||||
|
||||
# 3. 二维数组
|
||||
|
||||
## 3.1 定义方式
|
||||
|
||||
① 二维数组就是在一维数组上,多加一个维度。
|
||||
|
||||

|
||||
|
||||
② 二维数组定义的四种方式:
|
||||
|
||||
1. 数据类型 数组名 [ 行数 ][ 列数 ];
|
||||
2. 数据类型 数组名 [ 行数 ][ 列数 ] = { { 数据1,数据2} , { 数据3,数据4 } }
|
||||
3. 数据类型 数组名 [ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4 };
|
||||
4. 数据类型 数组名 [ ][ 列数 ] = { 数据1,数据2,数据3,数据4 };
|
||||
|
||||
③ 以上4种定义方式,利用第二种更加直观,提高代码的可读性。
|
||||
|
||||
④ 定义二维数组的时候,如果初始化了数据,可以省略行数。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
//1、数据类型 数组名 [ 行数 ][ 列数 ];
|
||||
int arr[2][3];
|
||||
arr[0][0] = 1;
|
||||
arr[0][1] = 2;
|
||||
arr[0][2] = 3;
|
||||
arr[1][0] = 4;
|
||||
arr[1][1] = 5;
|
||||
arr[1][2] = 6;
|
||||
|
||||
//外层循环打印行数,内层循环打印列数
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
cout << arr[i][j] << endl;
|
||||
}
|
||||
}
|
||||
|
||||
//2、数据类型 数组名 [ 行数 ][ 列数 ] = { { 数据1,数据2} , { 数据3,数据4 } }
|
||||
int arr2[2][3] =
|
||||
{
|
||||
{1,2,3},
|
||||
{4,5,6}
|
||||
};
|
||||
|
||||
for (int i = 0; i<2;i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
cout << arr2[i][j] << " "; //打印一个元素后打印一个空格
|
||||
}
|
||||
cout << endl; //换行语句
|
||||
}
|
||||
|
||||
//3、数据类型 数组名 [ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4 };
|
||||
int arr3[2][3] = { 1,2,3,4,5,6 }; //可以省去行数,但是列数不能再省略了
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
cout << arr2[i][j] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
//4、数据类型 数组名 [ ][ 列数 ] = { 数据1,数据2,数据3,数据4 };
|
||||
int arr4[][3] = { 1,2,3,4,5,6 }; //可以省去行数,但是列数不可以省略
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
cout << arr2[i][j] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- 4
|
||||
- 5
|
||||
- 6
|
||||
- 1 2 3
|
||||
- 4 5 6
|
||||
- 1 2 3
|
||||
- 4 5 6
|
||||
- 1 2 3
|
||||
- 4 5 6
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 3.2 数组名
|
||||
|
||||
① 查看二维数组所占内存空间。
|
||||
|
||||
② 获取二维数组首地址。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//二维数组名称用途
|
||||
//1、可以查看占用内存空间大小
|
||||
int arr[2][3] =
|
||||
{
|
||||
{1,2,3},
|
||||
{4,5,6}
|
||||
};
|
||||
|
||||
cout << "二维数组占用内存空间为: " << sizeof(arr) << endl;
|
||||
cout << "二维数组第一行占用内存为:" << sizeof(arr[0]) << endl;
|
||||
cout << "二维数组第一个元素占用内存为:" << sizeof(arr[0][0]) << endl;
|
||||
|
||||
cout << "二维数组行数为:" << sizeof(arr)/sizeof(arr[0]) << endl;
|
||||
cout << "二维数组列数为:" << sizeof(arr[0])/sizeof(arr[0][0]) << endl;
|
||||
|
||||
//2、可以查看二维数组的首地址
|
||||
cout << "二维数组首地址为:" << (int)arr << endl;
|
||||
cout << "二维数组第一行首地址为:" << (int)arr << endl;
|
||||
cout << "二维数组第一行首地址为:" << (int)arr[0] << endl;
|
||||
cout << "二维数组第二行首地址为:" << (int)arr[1] << endl;
|
||||
|
||||
cout << "二维数组第一个元素首地址为:" << (int)&arr[0][0] << endl;
|
||||
cout << "二维数组第二个元素首地址为:" << (int)&arr[0][1] << endl; //每个元素地址相差4个字节
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 二维数组占用内存空间为: 24
|
||||
- 二维数组第一行占用内存为:12
|
||||
- 二维数组第一个元素占用内存为:4
|
||||
- 二维数组行数为:2
|
||||
- 二维数组列数为:3
|
||||
- 二维数组首地址为:3733652
|
||||
- 二维数组第一行首地址为:3733652
|
||||
- 二维数组第一行首地址为:3733652
|
||||
- 二维数组第二行首地址为:3733664
|
||||
- 二维数组第一个元素首地址为:3733652
|
||||
- 二维数组第二个元素首地址为:3733656
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 3.3 考试成绩
|
||||
|
||||
案例描述:有三名同学(张三,李四,王五),在一次考试中的成绩分别如下表,请分别输出三名同学的成绩。
|
||||
|
||||
| 姓名 | 语文 | 数学 | 英语 |
|
||||
| :------:| :------: | :------: | :------: |
|
||||
| 张三 | 100 | 100 | 100 |
|
||||
| 李四 | 90 | 50 | 100 |
|
||||
| 王五 | 60 | 70 | 80 |
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//二维数组案例-考试成绩统计
|
||||
//1、创建二维数组
|
||||
int scores[3][3] =
|
||||
{
|
||||
{100,100,100},
|
||||
{90,50,100},
|
||||
{60,70,80}
|
||||
};
|
||||
|
||||
//2、统计每个人的总和分数
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
int sum = 0; //统计分数总和不变
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
sum += scores[i][j];
|
||||
//cout << scores[i][j] << " ";
|
||||
}
|
||||
cout << "第" << i + 1 << "个人的总分为:" << sum << endl;
|
||||
}
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 第1个人的总分为:300
|
||||
- 第2个人的总分为:240
|
||||
- 第3个人的总分为:210
|
||||
- 请按任意键继续. . .
|
||||
BIN
docs/CPlusPlus-main/13_C++的数组_files/image.png
Normal file
|
After Width: | Height: | Size: 376 KiB |
891
docs/CPlusPlus-main/14_C++的函数.ipynb
Normal file
610
docs/CPlusPlus-main/14_C++的函数.md
Normal file
@ -0,0 +1,610 @@
|
||||
# C++的函数
|
||||
|
||||
# 1. 函数
|
||||
|
||||
## 1.1 函数概述
|
||||
|
||||
① 函数作用:将一段经常使用的代码封装起来,减少重复代码。
|
||||
|
||||
② 一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能。
|
||||
|
||||
## 1.2 函数定义
|
||||
|
||||
① 函数的定义主要有5个部分:
|
||||
|
||||
1. 返回值类型:一个函数可以返回一个值。
|
||||
2. 函数名:给函数起个名称。
|
||||
3. 参数列表:使用该函数时,传入的数据。
|
||||
4. 函数体语句:花括号内的代码,函数内需要执行的语句。
|
||||
5. return表达式:和返回值类型挂钩,函数执行完后,返回相应的数据。
|
||||
|
||||
② 语法格式如下所示:
|
||||
|
||||
|
||||
```python
|
||||
返回值类型 函数名 (参数列表)
|
||||
{
|
||||
函数体语句
|
||||
|
||||
return 表达式
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//函数的定义
|
||||
//语法:返回值类型 函数名 (参数列表) { 函数体语句 return表达式 }
|
||||
|
||||
//加法函数,实现两个整型相加,并且将相加的结果进行返回
|
||||
int add(int num1, int num2)
|
||||
{
|
||||
int sum = num1 + num2;
|
||||
return sum;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
system("pause"); //按任意键继续
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## 1.3 函数调用
|
||||
|
||||
① 功能:使用定义好的函数
|
||||
|
||||
② 语法:函数名(参数)
|
||||
|
||||
③ 函数定义里小括号内称为形参,函数调用时传入的参数称为实参
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//函数的定义
|
||||
//语法:
|
||||
//返回值类型 函数名 (参数列表) { 函数体语句 return表达式 }
|
||||
|
||||
//定义加法函数
|
||||
//函数定义的时候,num1和num2并不是真实数据
|
||||
//它们只是一个形式上的参数,简称形参
|
||||
int add(int num1, int num2)
|
||||
{
|
||||
int sum = num1 + num2;
|
||||
return sum;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
//main函数中调用add函数
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
|
||||
//函数调用语法:函数名称:(参数)
|
||||
//a和b称为 实际参数,简称实参
|
||||
//当调用函数的时候,实参的值会传递给形参
|
||||
int c = add(a, b);
|
||||
|
||||
cout << "c = " << c << endl;
|
||||
|
||||
system("pause"); //按任意键继续
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- c = 30
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.4 函数值传递
|
||||
|
||||
① 所谓值传递,就是函数调用时实参将数值传入给形参。
|
||||
|
||||
② 值传递时,如果形参发生改变,并不影响实参。
|
||||
|
||||
③ 在下面代码例子中,实参传进去时,新参会产生新的内存空间赋值,对num1、num2的操作并不会改变实参a、b的值。
|
||||
|
||||

|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//值传递
|
||||
//定义函数,实现两个数字进行交换函数
|
||||
|
||||
//如果函数不需要返回值,声明的时候可以写void
|
||||
void swap(int num1, int num2)
|
||||
{
|
||||
cout << "交换前:" << endl;
|
||||
cout << "num1= " << num1 << endl;
|
||||
cout << "num2= " << num2 << endl;
|
||||
|
||||
int temp = num1;
|
||||
num1 = num2;
|
||||
num2 = temp;
|
||||
|
||||
cout << "交换后:" << endl;
|
||||
cout << "num1= " << num1 << endl;
|
||||
cout << "num2= " << num2 << endl;
|
||||
|
||||
return; //前面写了void,所以不需要返回值。返回值不需要的时候,也可以不写return。
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
//main函数中调用add函数
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
|
||||
cout << "a = " << a << endl;
|
||||
cout << "b = " << b << endl;
|
||||
|
||||
//当我们把值传递的时候,函数的形参发生发生改变,并不会影响实参
|
||||
swap(a, b);
|
||||
cout << "a = " << a << endl;
|
||||
cout << "b = " << b << endl;
|
||||
|
||||
system("pause"); //按任意键继续
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- a = 10
|
||||
- b = 20
|
||||
- 交换前:
|
||||
- num1= 10
|
||||
- num2= 20
|
||||
- 交换后:
|
||||
- num1= 20
|
||||
- num2= 10
|
||||
- a = 10
|
||||
- b = 20
|
||||
|
||||
## 1.5 函数常见样式
|
||||
|
||||
① 常见的函数样式有四种
|
||||
|
||||
1. 无参无返
|
||||
2. 有参无返
|
||||
3. 无参有返
|
||||
4. 有参有返
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//函数常见样式
|
||||
//1、无参无返
|
||||
void test01()
|
||||
{
|
||||
cout << "this is test01" << endl;
|
||||
}
|
||||
|
||||
//2、有参无返
|
||||
void test02(int a)
|
||||
{
|
||||
cout << "this is test 02 a = " << a << endl;
|
||||
}
|
||||
|
||||
//3、无参有返
|
||||
int test03()
|
||||
{
|
||||
cout << "this is test 03 " << endl;
|
||||
|
||||
return 1000;
|
||||
}
|
||||
|
||||
//4、有参有返
|
||||
int test04(int a )
|
||||
{
|
||||
cout << "this is test 04 a = " << a << endl;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
//无参无返函数调用
|
||||
test01();
|
||||
|
||||
//有参无返函数调用
|
||||
test02(100);
|
||||
|
||||
//无参有返函数调用
|
||||
int num1 = test03();
|
||||
cout << "num1 = " << num1 << endl;
|
||||
|
||||
//有参有返函数调用
|
||||
int num2 = test04(10000);
|
||||
cout << "num2 = " << num2 << endl;
|
||||
|
||||
system("pause"); //按任意键继续
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- this is test01
|
||||
- this is test 02 a = 100
|
||||
- this is test 03
|
||||
- num1 = 1000
|
||||
- this is test 04 a = 10000
|
||||
- num2 = 10000
|
||||
|
||||
## 1.6 函数声明
|
||||
|
||||
① 作用:告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。
|
||||
|
||||
② 函数的声明可以多次,但是函数的定义只能有一次。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//函数的声明
|
||||
//比较函数,实现两个整型数字进行比较,返回较大的值。
|
||||
|
||||
//提前告诉编译器函数的存在,可以利用函数的声明
|
||||
//函数的声明
|
||||
//声明可以写多次,但是定义只能有一次
|
||||
int max(int a, int b);
|
||||
int max(int a, int b);
|
||||
int max(int a, int b);
|
||||
|
||||
int main()
|
||||
{
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
cout << max(a, b) << endl;
|
||||
|
||||
system("pause"); //按任意键继续
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
//函数定义在main函数之后,必须要在main函数之前写函数的声明
|
||||
int max(int a, int b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 20
|
||||
|
||||
## 1.7 函数分文件编写
|
||||
|
||||
① 作用:让代码结构更加清晰。
|
||||
|
||||
② 函数分文件编写一般有4个步骤:
|
||||
|
||||
1. 创建后缀名为.h的头文件。
|
||||
2. 创建后缀名为.cpp的源文件。
|
||||
3. 在头文件中写函数的声明。
|
||||
4. 在源文件中写函数的定义。
|
||||
|
||||
### 1.7.1 swap.h头文件
|
||||
|
||||
|
||||
```python
|
||||
//这个是swap.h头文件
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//函数的声明
|
||||
void swap(int a, int b);
|
||||
```
|
||||
|
||||
### 1.7.2 swap.pp源文件
|
||||
|
||||
|
||||
```python
|
||||
//这个是swap.pp源文件
|
||||
|
||||
#include "swap.h"
|
||||
|
||||
//函数的定义
|
||||
void swap(int a, int b)
|
||||
{
|
||||
int temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
|
||||
cout << "a = " << a << endl;
|
||||
cout << "b = " << b << endl;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### 1.7.3 主文件 .cpp文件
|
||||
|
||||
|
||||
```python
|
||||
//主文件,调用函数分文件
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include "swap.h" //包含要调用的函数的头文件,双引号表示我们自己写的头文件
|
||||
|
||||
int main()
|
||||
{
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
cout << max(a, b) << endl;
|
||||
|
||||
system("pause"); //按任意键继续
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## 1.8 函数默认参数
|
||||
|
||||
① 在C++中,函数的形参列表中的形参是可以有默认值的。
|
||||
|
||||
② 语法:返回值类型 函数名 (参数 = 默认值) {}
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//函数默认参数
|
||||
|
||||
//如果我们自己传入数据,就用自己的数据,如果没有,那么永默认值
|
||||
//语法:返回值类型 函数名(形参 = 默认值)
|
||||
int func01(int a,int b,int c)
|
||||
{
|
||||
return a + b + c;
|
||||
}
|
||||
//注意事项
|
||||
//1、如果某个位置以及有了默认参数,那么从这个位置往后,从左到右都必须有默认值
|
||||
int func02(int a, int b = 40, int c = 50)
|
||||
{
|
||||
return a + b + c;
|
||||
}
|
||||
|
||||
//2、如果函数声明有默认参数,函数实现就不能有默认参数
|
||||
//例如,函数定义为 int func03(int a = 20, int b = 20){return a + b;},而函数声明为int func03(int a = 10, int b = 10);那么编译器不知道按照哪个默认参数来运行
|
||||
//声明和实现只能有一个有默认参数
|
||||
int func03(int a = 10, int b = 10);
|
||||
|
||||
//这个是函数的实现
|
||||
int func03(int a , int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << func01(10, 20, 30) << endl;
|
||||
cout << func02(10) << endl;
|
||||
cout << func02(10, 20) << endl;
|
||||
cout << func02(10, 20,30) << endl;
|
||||
|
||||
cout << func03() << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 60
|
||||
- 100
|
||||
- 80
|
||||
- 60
|
||||
- 20
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.9 函数占位参数
|
||||
|
||||
① C++中函数的形参列表里可以有占位参数,用来做占位,调用函数时必须填补该位置。
|
||||
|
||||
② 语法:返回值类型 函数名 (数据类型) {}
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//占位参数
|
||||
//返回值类型 函数名(数据类型){}
|
||||
|
||||
//目前,占位参数还用不到,后面会用到
|
||||
void func01(int a,int)
|
||||
{
|
||||
cout << "this is func01" << endl; //函数内部无法调用第二个参数,无法像a+b这样调用第二个参数
|
||||
}
|
||||
|
||||
//占位参数,还可以有默认参数
|
||||
void func02(int a, int = 10)
|
||||
{
|
||||
cout << "this is func02" << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
func01(10, 20);
|
||||
func02(10); //有默认参数,可以只输入一个参数
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- this is func01
|
||||
- this is func02
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 2. 函数重载
|
||||
|
||||
## 2.1 函数重载条件
|
||||
|
||||
① 作用:函数名可以相同,提高复用性。
|
||||
|
||||
② 函数重载满足条件:
|
||||
|
||||
1. 同一个作用域下。
|
||||
2. 函数名称相同。
|
||||
3. 函数参数类型不同 或者 个数不同 或者 顺序不同。
|
||||
|
||||
③ 函数的返回值不可以作为函数重载的条件。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//函数重载
|
||||
//可以让函数名相同,提高复用性
|
||||
|
||||
//函数重载的满足条件
|
||||
//1、同一作用域下
|
||||
//2、函数名称相同
|
||||
//3、函数参数类型不同,或者个数不同,或者顺序不同
|
||||
void func()
|
||||
{
|
||||
cout << "func 的调用" << endl;
|
||||
}
|
||||
|
||||
void func(int a)
|
||||
{
|
||||
cout << "func (int a) 的调用" << endl;
|
||||
}
|
||||
|
||||
void func(double a)
|
||||
{
|
||||
cout << "func (double a) 的调用" << endl;
|
||||
}
|
||||
|
||||
void func(double a, int b)
|
||||
{
|
||||
cout << "func (double a, int b) 的调用" << endl;
|
||||
}
|
||||
|
||||
void func(int a, double b)
|
||||
{
|
||||
cout << "func (int a, double b) 的调用" << endl;
|
||||
}
|
||||
|
||||
/*
|
||||
注意事项
|
||||
函数的返回值不可以作为函数重载的条件
|
||||
int func(int a, double b)
|
||||
//调用func(3.14,3)时,编译器不知道是调用int func(int a, double b){}还是调用void func(int a, double b){}
|
||||
{
|
||||
cout << "func (int a, double b) 的调用" << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
func(); // 根据传入参数的个数不同,调用不同的函数
|
||||
func(10);
|
||||
|
||||
func(3.14); // 根据传入参数的类型不同,调用不同的函数
|
||||
|
||||
func(3,3.14); // 根据传入参数的顺序不同,调用不同的函数
|
||||
func(3.14,3); // 根据传入参数的顺序不同,调用不同的函数
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- func 的调用
|
||||
- func (int a) 的调用
|
||||
- func (double a) 的调用
|
||||
- func (int a, double b) 的调用
|
||||
- func (double a, int b) 的调用
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 2.2 函数重载注意事项
|
||||
|
||||
① 引用作为重载条件。
|
||||
|
||||
② 函数重载碰到函数默认参数。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//函数重载的注意事项
|
||||
//1、引用作为重载的条件
|
||||
void fun(int& a) // int &a = 10; 不合法,所以fun(10);无法调用
|
||||
{
|
||||
cout << "func(int &a)调用" << endl;
|
||||
}
|
||||
// const int &a = 10; 合法
|
||||
void fun(const int& a) //语法是可以的,const引用和普通引用属于类型不同,fun(10)可以调用
|
||||
{
|
||||
cout << "func(const int &a)调用" << endl;
|
||||
}
|
||||
|
||||
//2、函数重载碰到默认参数
|
||||
void func2(int a,int b = 20)
|
||||
{
|
||||
cout << "func2(int a,int b = 20) 的调用" << endl;
|
||||
}
|
||||
|
||||
void func2(int a)
|
||||
{
|
||||
cout << "func2(int a) 的调用" << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int a = 10;
|
||||
//变量可读可写,所以调用变量时,是调用可读可写的引用函数,const int a = 10的fun(a);调用func(const int &a)调用
|
||||
fun(a);
|
||||
fun(10);
|
||||
//既可以调用void func2(int a,int b = 20),也可以调用void func2(int a)
|
||||
//func2(10); //当函数重载碰到默认参数,出现二义性,报错,尽量避免这种情况
|
||||
|
||||
func2(10,20); //不会出现二义性
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- func(int &a)调用
|
||||
- func(const int &a)调用
|
||||
- func2(int a,int b = 20) 的调用
|
||||
- 请按任意键继续. . .
|
||||
BIN
docs/CPlusPlus-main/14_C++的函数_files/image.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
596
docs/CPlusPlus-main/15_C++的指针.ipynb
Normal file
385
docs/CPlusPlus-main/15_C++的指针.md
Normal file
@ -0,0 +1,385 @@
|
||||
# C++的指针
|
||||
|
||||
# 1. 指针
|
||||
|
||||
## 1.1 指针概念
|
||||
|
||||
① 指针的作用:可以通过指针间接访问内存。
|
||||
|
||||
1. 内存编号是从0开始记录的,一般用十六进制数字表示。
|
||||
2. 可以利用指针变量保存地址。
|
||||
|
||||
## 1.2 指针变量定义和使用
|
||||
|
||||
① 指针变量定义语法:数据类型 + 变量名;
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//1、定义指针
|
||||
int a = 10;
|
||||
|
||||
//指针定义的语法:数据类型 * 指针变量
|
||||
int * p; //创建p为指针变量
|
||||
|
||||
//让指针记录变量a的地址
|
||||
p = &a; // &为取址符号
|
||||
|
||||
cout << "a的地址为:" << &a << endl;
|
||||
|
||||
cout << "指针p为:" << p << endl; // 指针p存储的值 和变量a的地址是一样的
|
||||
|
||||
//2、使用指针
|
||||
//可以通过解引用的方式来找到指针指向的内存
|
||||
//指针前加 * 代表解引用,找到指针指向的内存中的数据
|
||||
|
||||
*p = 1000; //通过*p访问内存,并修改内存的值
|
||||
cout << "a= " << a << endl;
|
||||
cout << "*p:" << *p << endl;
|
||||
|
||||
system("pause"); //按任意键继续
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- a的地址为:00FBFC78
|
||||
- 指针p为:00FBFC78
|
||||
- a= 1000
|
||||
- *p:1000
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.3 指针所占内存空间
|
||||
|
||||
① 在32位操作系统下,不管什么类型的指针都占4个字节的内存。
|
||||
|
||||
② 在64位操作系统下,不管什么类型的指针都占8个字节的内存,但是实际开发环境一般都是32位操作系统下。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//指针所占内存空间
|
||||
int a = 10;
|
||||
|
||||
/*
|
||||
int * p; //p变量是 int * 数据类
|
||||
p = &a;
|
||||
|
||||
等价于:
|
||||
int * p = &a;
|
||||
*/
|
||||
|
||||
int * p = &a;
|
||||
|
||||
cout << "sizeof(int * )= " << sizeof(p) << endl;
|
||||
cout << "sizeof(int * )= " << sizeof(int(*)) << endl;
|
||||
cout << "sizeof(float * )= " << sizeof(float(*)) << endl;
|
||||
cout << "sizeof(double * )= " << sizeof(double(*)) << endl;
|
||||
cout << "sizeof(char * )= " << sizeof(char(*)) << endl;
|
||||
|
||||
system("pause"); //按任意键继续
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- sizeof(int * )= 4
|
||||
- sizeof(int * )= 4
|
||||
- sizeof(float * )= 4
|
||||
- sizeof(double * )= 4
|
||||
- sizeof(char * )= 4
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.4 空指针
|
||||
|
||||
① 指针变量指向内存中编号为0的空间。
|
||||
|
||||
② 用途:初始化指针变量。
|
||||
|
||||
③ 空指针指向的内存是不可以访问的。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//空指针
|
||||
//1、空指针用于给指针变量进行初始化
|
||||
int* p = NULL;
|
||||
|
||||
//2、空指针是不可以进行访问的
|
||||
//0~255之间的内存编号是系统占用的,因此不可以访问。
|
||||
*p = 100; //对空指针解引用,然后操作它,这样是报错的
|
||||
|
||||
system("pause"); //按任意键继续
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## 1.5 野指针
|
||||
|
||||
① 野指针:指针变量指向非法的内存空间。
|
||||
|
||||
② 野指针和空指针都不是我们申请的空间,所以不要访问。
|
||||
|
||||
③ 例如,创建了一个整型变量a,是申请了一个整型变量的空间,由于是申请的空间,所以可以通过指针访问它。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//野指针
|
||||
int* p = (int*)0x1100; // 0x1100是一个十六进制数,int*使得十六进制数强行转换为地址。
|
||||
// 拿指针随便指向并没有申请这个内存的访问权限的内存。
|
||||
|
||||
cout << *p << endl; // 报错,地址并没有申请,你还要去访问它,就会报错
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## 1.6 const修饰指针
|
||||
|
||||
① 看const右侧紧跟着的是指针还是常量,是指针就是常量指针,是常量就是指针常量。
|
||||
|
||||
② 如果 const后面跟的是指针(*),就不能做 *p=20 操作,即不能修改指针指向的值。
|
||||
|
||||
③ 如果const 后面跟的常量(p),就不能做 p = &b 操作,即不能修改指针的指向。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
int a = 10;
|
||||
int b = 10;
|
||||
|
||||
//1、const修饰指针 常量指针
|
||||
const int* p = &a; // const(常量) *(指针) → 常量指针
|
||||
// *p = 20; 错误,常量指针 → 指针指向的值不可以改,指针的指向可以改
|
||||
p = &b; // 正确
|
||||
|
||||
//2、const修饰指针 指针常量
|
||||
int* const p2 = &a; // *(指针)const(常量) → 指针常量
|
||||
*p2 = 100; //正确的
|
||||
p2 = &b; //错误,指针的指向不可以改,指针指向的 值可以改
|
||||
|
||||
//3、const修饰指针和常量
|
||||
const int* const p3 = &a;
|
||||
*p3 = 100; //错误
|
||||
p3 = &b; //错误
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## 1.7 指针和数组
|
||||
|
||||
① 利用指针访问数组中元素。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
//指针和数组
|
||||
//利用指针访问数组中的元素
|
||||
|
||||
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
|
||||
|
||||
cout << "第一个元素为:" << arr[0] << endl;
|
||||
|
||||
int* p = arr; //数组名arr就是数组的首地址
|
||||
|
||||
cout << "利用指针访问第一个元素:" << *p << endl;
|
||||
|
||||
p++;
|
||||
|
||||
cout << "利用指针访问第二个元素:" << *p << endl;
|
||||
|
||||
cout << "利用指针遍历数组:" << endl;
|
||||
|
||||
int* p2 = arr;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
//cout << arr[i] << endl;
|
||||
cout << *p2 << endl;
|
||||
p2++;
|
||||
|
||||
}
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 第一个元素为:1
|
||||
- 利用指针访问第一个元素:1
|
||||
- 利用指针访问第二个元素:2
|
||||
- 利用指针遍历数组:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- 4
|
||||
- 5
|
||||
- 6
|
||||
- 7
|
||||
- 8
|
||||
- 9
|
||||
- 10
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.8 指针和函数
|
||||
|
||||
① 利用指针作函数的参数,可以修改实参的值。
|
||||
|
||||
② 地址传递可以改变实参的数据,值传递不可以改变实参的值。
|
||||
|
||||
③ 如果不想修改实参,就用值传递,如果想修改实参,就用地址传递。
|
||||
|
||||
④ 代码例子中,temp的值会传递给 *p2 地址中的值,所以a、b实参的值改变了。
|
||||
|
||||

|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
void swap(int* p1, int* p2)
|
||||
{
|
||||
int temp = *p1;
|
||||
*p1 = *p2;
|
||||
*p2 = temp;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
//指针和函数
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
|
||||
swap(&a, &b);
|
||||
|
||||
//如果是地址传递,可以修改实参,原来 a = 10;b = 20,地址传递后 a = 20,b = 10.
|
||||
cout << "a =" << a << endl;
|
||||
cout << "b =" << b << endl;
|
||||
//如果是值传递,不可以修改实参,原来 a = 10;b = 20,值传递后 a = 10,b = 20.
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- a =20
|
||||
- b =10
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.9 指针配合数组和函数案例
|
||||
|
||||
案例描述:封装一个函数,利用冒泡排序,实现对整型数字的升序排列。
|
||||
|
||||
例如: int arr[10] = {4,3,6,9,1,2,10,8,7,5}
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//冒泡排序函数
|
||||
void bubbleSort(int * arr, int len)
|
||||
{
|
||||
for (int i = 0; i < len - 1; i++)
|
||||
{
|
||||
for (int j = 0; j < len - i - 1; j++)
|
||||
{
|
||||
//如果j>j+1的值,交换数字
|
||||
if (arr[j] > arr[j + 1])
|
||||
{
|
||||
int temp = arr[j];
|
||||
arr[j] = arr[j + 1];
|
||||
arr[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//打印数组
|
||||
void printArray(int* arr, int len)
|
||||
{
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
cout << arr[i] << endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
//1、先创建数组
|
||||
int arr[10] = { 4,3,6,1,2,9,10,8,7,5 };
|
||||
|
||||
//数组长度
|
||||
int len = sizeof(arr) / sizeof(arr[0]);
|
||||
|
||||
//2、创建函数,实现冒泡排序
|
||||
bubbleSort(arr, len);
|
||||
|
||||
//3、打印排序后的数组
|
||||
printArray(arr, len);
|
||||
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- 4
|
||||
- 5
|
||||
- 6
|
||||
- 7
|
||||
- 8
|
||||
- 9
|
||||
- 10
|
||||
- 请按任意键继续. . .
|
||||
BIN
docs/CPlusPlus-main/15_C++的指针_files/image.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
897
docs/CPlusPlus-main/16_C++的结构体.ipynb
Normal file
@ -0,0 +1,897 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的结构体"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 结构体"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。\n",
|
||||
"\n",
|
||||
"② 语法:struct 结构体名 { 结构体成员列表 }\n",
|
||||
"\n",
|
||||
"③ 通过结构体创建变量的方式有三种:\n",
|
||||
"\n",
|
||||
"1. struct 结构体名 变量名\n",
|
||||
"2. struct 结构体名 变量名 = { 成员1值,成员2值 }\n",
|
||||
"3. 定义结构体时顺便创建变量\n",
|
||||
"\n",
|
||||
"④ 结构体变量利用点.访问成员"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include <string>\n",
|
||||
"//自定义数据类型,一些类型的集合组成一个类型\n",
|
||||
"//语法 struct 类型名称 { 成员列表 }\n",
|
||||
"//结构体定义的时候,struct关键字不能省略\n",
|
||||
"//1、创建学生数据类型:学生包括(姓名,年龄,分数)\n",
|
||||
"struct Student\n",
|
||||
"{\n",
|
||||
" //成员列表\n",
|
||||
"\n",
|
||||
" //姓名\n",
|
||||
" string name;\n",
|
||||
" //年龄\n",
|
||||
" int age;\n",
|
||||
" //分数\n",
|
||||
" int score;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //2.1 struct Student s1 s1类似结构体的实例值,类似变量赋值:int a = 10 → 属性 变量 变量值\n",
|
||||
" //结构体创建的时候,struct 关键字可以省略;上面结构体定义的时候 struct 可以省略\n",
|
||||
" struct Student s1;\n",
|
||||
" //给s1属性赋值,通过点.访问结构体变量中的属性\n",
|
||||
" s1.name = \"张三\";\n",
|
||||
" s1.age = 18;\n",
|
||||
" s1.score = 100;\n",
|
||||
"\n",
|
||||
" cout << \"姓名:\" << s1.name << \"年龄:\" << s1.age << \"分数:\" << s1.score << endl;\n",
|
||||
"\n",
|
||||
" //2.2 struct Student s2 = { ... }\n",
|
||||
" struct Student s2 = { \"李四\",19,80 };\n",
|
||||
" cout << \"姓名:\" << s2.name << \"年龄:\" << s2.age << \"分数:\" << s2.score << endl;\n",
|
||||
" \n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 姓名:张三年龄:18分数:100 \n",
|
||||
" - 姓名:李四年龄:19分数:80 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include <string>\n",
|
||||
"//自定义数据类型,一些类型的集合组成一个类型\n",
|
||||
"struct Student\n",
|
||||
"{\n",
|
||||
" //成员列表\n",
|
||||
"\n",
|
||||
" //姓名\n",
|
||||
" string name;\n",
|
||||
" //年龄\n",
|
||||
" int age;\n",
|
||||
" //分数\n",
|
||||
" int score;\n",
|
||||
"}s3; //2.3 创建结构体的时候,顺便创建个结构体变量\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //2.3 \n",
|
||||
" s3.name = \"王五\";\n",
|
||||
" s3.age = 20;\n",
|
||||
" s3.score = 60;\n",
|
||||
"\n",
|
||||
" cout << \"姓名:\" << s3.name << \"年龄:\" << s3.age << \"分数:\" << s3.score << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 姓名:王五年龄:20分数:60 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.1 结构体定义和使用"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 作用:将自定义的结构体放入到数组中方便维护。\n",
|
||||
"\n",
|
||||
"② 语法:struct 结构体名 数组名[元素个数] = { {},{},...,{} }"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include <string>\n",
|
||||
"//自定义数据类型,一些类型的集合组成一个类型\n",
|
||||
"struct Student\n",
|
||||
"{\n",
|
||||
" //成员列表\n",
|
||||
"\n",
|
||||
" //姓名\n",
|
||||
" string name;\n",
|
||||
" //年龄\n",
|
||||
" int age;\n",
|
||||
" //分数\n",
|
||||
" int score;\n",
|
||||
"}; \n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //2、创建结构体数组\n",
|
||||
" struct Student stuArray[3] =\n",
|
||||
" {\n",
|
||||
" {\"张三\",18,100},\n",
|
||||
" {\"李四\",28,99},\n",
|
||||
" {\"王五\",38,66}\n",
|
||||
" };\n",
|
||||
"\n",
|
||||
" //3、给结构体数组中的元素赋值\n",
|
||||
" stuArray[2].name = \"赵六\";\n",
|
||||
" stuArray[2].age = 80;\n",
|
||||
" stuArray[2].score = 60;\n",
|
||||
"\n",
|
||||
" //4、遍历结构体数组\n",
|
||||
" for (int i = 0; i < 3; i++)\n",
|
||||
" {\n",
|
||||
" cout << \"姓名:\" << stuArray[i].name << \"年龄:\" << stuArray[i].age << \"分数:\" << stuArray[i].score << endl;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 姓名:张三年龄:18分数:100 \n",
|
||||
" - 姓名:李四年龄:28分数:99 \n",
|
||||
" - 姓名:赵六年龄:80分数:60\n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.2 结构体数组"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 作用:将自定义的结构体放入到数组中方便维护。\n",
|
||||
"\n",
|
||||
"② 语法:struct 结构体名 数组名[元素个数] = { {},{},...,{} }"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include <string>\n",
|
||||
"//自定义数据类型,一些类型的集合组成一个类型\n",
|
||||
"struct Student\n",
|
||||
"{\n",
|
||||
" //成员列表\n",
|
||||
"\n",
|
||||
" //姓名\n",
|
||||
" string name;\n",
|
||||
" //年龄\n",
|
||||
" int age;\n",
|
||||
" //分数\n",
|
||||
" int score;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //2、创建结构体数组\n",
|
||||
" struct Student stuArray[3] =\n",
|
||||
" {\n",
|
||||
" {\"张三\",18,100},\n",
|
||||
" {\"李四\",28,99},\n",
|
||||
" {\"王五\",38,66}\n",
|
||||
" };\n",
|
||||
"\n",
|
||||
" //3、给结构体数组中的元素赋值\n",
|
||||
" stuArray[2].name = \"赵六\";\n",
|
||||
" stuArray[2].age = 80;\n",
|
||||
" stuArray[2].score = 60;\n",
|
||||
"\n",
|
||||
" //4、遍历结构体数组\n",
|
||||
" for (int i = 0; i < 3; i++)\n",
|
||||
" {\n",
|
||||
" cout << \"姓名:\" << stuArray[i].name << \"年龄:\" << stuArray[i].age << \"分数:\" << stuArray[i].score << endl;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 姓名:张三年龄:18分数:100 \n",
|
||||
" - 姓名:李四年龄:28分数:99 \n",
|
||||
" - 姓名:赵六年龄:80分数:60 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.3 结构体指针"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 作用:通过指针访问结构体中的成员。\n",
|
||||
"\n",
|
||||
"② 利用操作符 · > 可以通过结构体指针访问结构体属性。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include <string>\n",
|
||||
"\n",
|
||||
"//结构体指针\n",
|
||||
"\n",
|
||||
"//定义学生结构体\n",
|
||||
"struct Student\n",
|
||||
"{\n",
|
||||
" string name; //姓名\n",
|
||||
" int age; //年龄\n",
|
||||
" int score; //分数\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" // 1、创建学生结构体变量,这里的 struct 可以省略\n",
|
||||
" struct Student s = { \"张三\",18,100 };\n",
|
||||
"\n",
|
||||
" //2、通过指针指向结构体变量\n",
|
||||
" struct Student* p = &s; //对s取地址, tudent * p 类似 int * p,这里的 struct 可以省略\n",
|
||||
"\n",
|
||||
" //3、通过指针访问结构体变量中的数据\n",
|
||||
" //通过结构体指针 访问结构体中的属性,需要利用'->'\n",
|
||||
" cout << \"姓名:\" << p->name << \"年龄:\" << p->age << \"分数:\" << p->score << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
"- 姓名:张三年龄:18分数:100 \n",
|
||||
"- 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.4 结构体嵌套结构体"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 结构体中的成员可以是另一个结构体。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include <string>\n",
|
||||
"\n",
|
||||
"//因为老师的结构体里有学生的结构体,所以学生结构体要在老师结构体前面先定义\n",
|
||||
"//定义学生结构体\n",
|
||||
"struct student\n",
|
||||
"{\n",
|
||||
" string name; //姓名\n",
|
||||
" int age; //年龄\n",
|
||||
" int score; //分数\n",
|
||||
"}; \n",
|
||||
"\n",
|
||||
"//定义老师结构体\n",
|
||||
"struct teacher\n",
|
||||
"{\n",
|
||||
" int id; //教师编号\n",
|
||||
" string name; //教师姓名\n",
|
||||
" int age; //年龄\n",
|
||||
" struct student stu; //学生结构体\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //结构体嵌套结构体\n",
|
||||
" //创建老师\n",
|
||||
" teacher t;\n",
|
||||
" t.id = 10000;\n",
|
||||
" t.name = \"老王\";\n",
|
||||
" t.age = 50;\n",
|
||||
" t.stu.name = \"小王\";\n",
|
||||
" t.stu.age = 20;\n",
|
||||
" t.stu.score = 60;\n",
|
||||
"\n",
|
||||
" cout << \"老师姓名:\" << t.name << \"老师编号:\" << t.id << \"老师年龄:\" << t.age\n",
|
||||
" << \"老师辅导的学生姓名:\" << t.stu.name << \"学生年龄:\" << t.stu.age \n",
|
||||
" << \"学生考试分数:\" << t.stu.score << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 老师姓名:老王 老师编号:10000 老师年龄:50 老师辅导的学生姓名:小王 学生年龄:20 学生考试分数:60\n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.5 结构体做函数参数"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 作用:将结构体作为参数向函数中传递,传递方式有两种。\n",
|
||||
"\n",
|
||||
"② 传递方式有两种:\n",
|
||||
"\n",
|
||||
"1. 值传递\n",
|
||||
"2. 地址传递"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include <string>\n",
|
||||
"\n",
|
||||
"//定义学生结构体\n",
|
||||
"struct student\n",
|
||||
"{\n",
|
||||
" string name; //姓名\n",
|
||||
" int age; //年龄\n",
|
||||
" int score; //分数\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"//定义老师结构体\n",
|
||||
"struct teacher\n",
|
||||
"{\n",
|
||||
" int id; //教师编号\n",
|
||||
" string name; //教师姓名\n",
|
||||
" int age; //年龄\n",
|
||||
" struct student stu; //学生结构体\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"//打印学生信息的函数\n",
|
||||
"//1、值传递\n",
|
||||
"void printStudent1(struct student s)\n",
|
||||
"{\n",
|
||||
" cout << \"子函数 值传递前 姓名:\" << s.name << \"年龄:\" << s.age << \"分数:\" << s.score << endl;\n",
|
||||
"\n",
|
||||
" s.age = 100;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"//2、地址传递\n",
|
||||
"void printStudent2(struct student* p)\n",
|
||||
"{\n",
|
||||
" cout << \"子函数 地址传递前 姓名:\" << p->name << \"年龄:\" << p->age << \"分数:\" << p->score << endl;\n",
|
||||
"\n",
|
||||
" p->score = 90;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //结构体做函数参数\n",
|
||||
" //将学生传入到一个参数中,打印学生身上的所有信息\n",
|
||||
"\n",
|
||||
" //创建结构体变量\n",
|
||||
" struct student s;\n",
|
||||
" s.name = \"张三\";\n",
|
||||
" s.age = 20;\n",
|
||||
" s.score = 85;\n",
|
||||
"\n",
|
||||
" cout << \"main函数 传递前 姓名:\" << s.name << \"年龄:\" << s.age << \"分数:\" << s.score << endl;\n",
|
||||
"\n",
|
||||
" printStudent1(s);\n",
|
||||
"\n",
|
||||
" cout << \"子函数 值传递后 姓名:\" << s.name << \"年龄:\" << s.age << \"分数:\" << s.score << endl;\n",
|
||||
"\n",
|
||||
" printStudent2(&s);\n",
|
||||
"\n",
|
||||
" cout << \"子函数 地址传递后 姓名:\" << s.name << \"年龄:\" << s.age << \"分数:\" << s.score << endl;\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" cout << \"main函数 传递后 姓名:\" << s.name << \"年龄:\" << s.age << \"分数:\" << s.score << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - main函数 传递前 姓名:张三年龄:20分数:85 \n",
|
||||
" - 子函数 值传递前 姓名:张三年龄:20分数:85 \n",
|
||||
" - 子函数 值传递后 姓名:张三年龄:20分数:85 \n",
|
||||
" - 子函数 地址传递前 姓名:张三年龄:20分数:85 \n",
|
||||
" - 子函数 地址传递后 姓名:张三年龄:20分数:90 \n",
|
||||
" - main函数 传递后 姓名:张三年龄:20分数:90 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.6 结构体中const使用"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 作用:const来防止误操作。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include <string>\n",
|
||||
"\n",
|
||||
"//const 的使用场景\n",
|
||||
"\n",
|
||||
"struct student\n",
|
||||
"{\n",
|
||||
" //姓名\n",
|
||||
" string name;\n",
|
||||
" //年龄\n",
|
||||
" int age;\n",
|
||||
" //分数\n",
|
||||
" int score;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"//将函数中形参设置为指针,用地址传递,而不是值传递,可以减少内存空间,而且不会复制新的副本\n",
|
||||
"//值传递需要复制新的副本,如果有成千上万个学生调用结构体,会复制成千上个副本\n",
|
||||
"void printStudents(const student* s)\n",
|
||||
"{\n",
|
||||
" s->age = 150; //报错,因为假如const之后,一旦有修改的操作就会报错,可以防止我们的误操作。\n",
|
||||
" cout << \"姓名:\" << s->name << \"年龄:\" << s->age << \"分数:\" << s->score << endl;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //创建结构体变量\n",
|
||||
" struct student s = { \"张三\",15,70 };\n",
|
||||
"\n",
|
||||
" //通过函数打印结构体变量信息\n",
|
||||
" printStudents(&s);\n",
|
||||
"\n",
|
||||
" cout << \"main中张三年龄为:\" << s.age << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.7 结构体案例(一)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"案例描述:学校正在做毕设项目,每名老师带领5个学生,总共有3名老师,需求如下:设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员,学生的成员有姓名、考试分数、创建数组存放3名老师,通过函数给每个老师及所带的学生赋值。最终打印出老师数据以及老师所带的学生数据。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include <string>\n",
|
||||
"#include <Ctime>\n",
|
||||
"\n",
|
||||
"//学生结构体定义\n",
|
||||
"struct Student\n",
|
||||
"{\n",
|
||||
" //姓名\n",
|
||||
" string sName;\n",
|
||||
" //学生数组\n",
|
||||
" int score;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"//老师结构体\n",
|
||||
"struct Teacher\n",
|
||||
"{\n",
|
||||
" //姓名\n",
|
||||
" string tName;\n",
|
||||
" //学生数组\n",
|
||||
" struct Student sArray[5];\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"//给老师和学生赋值的函数\n",
|
||||
"void allocateSpace(struct Teacher tArray[], int len) //接收数组的两种方式:一用指针,二用数组名 struct Teacher tArray[]\n",
|
||||
"{\n",
|
||||
" string nameSeed = \"ABCDE\";\n",
|
||||
" //给老师开始赋值\n",
|
||||
" for (int i = 0; i < len; i++)\n",
|
||||
" {\n",
|
||||
" tArray[i].tName = \"Teacher_\";\n",
|
||||
" tArray[i].tName += nameSeed[i];\n",
|
||||
"\n",
|
||||
" //通过循环给每名老师所带的学生赋值\n",
|
||||
" for (int j = 0; j < 5; j++)\n",
|
||||
" {\n",
|
||||
" tArray[i].sArray[j].sName = \"Student_\";\n",
|
||||
" tArray[i].sArray[j].sName += nameSeed[j];\n",
|
||||
"\n",
|
||||
" int random = rand() % 61 + 40; // 40 ~ 100\n",
|
||||
" tArray[i].sArray[j].score = random; //\n",
|
||||
"\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"//打印所有信息\n",
|
||||
"void printInfo(struct Teacher tArray[], int len)\n",
|
||||
"{\n",
|
||||
" for (int i = 0;i<len;i++)\n",
|
||||
" {\n",
|
||||
" cout << \"老师姓名:\" << tArray[i].tName << endl;\n",
|
||||
" \n",
|
||||
" for (int j = 0; j < 5; j++)\n",
|
||||
" {\n",
|
||||
" cout << \"\\t学生姓名:\" << tArray[i].sArray[j].sName \n",
|
||||
" << \" 考试分数:\" << tArray[i].sArray[j].score << endl;\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //随机数种子\n",
|
||||
" srand((unsigned int)time(NULL));\n",
|
||||
"\n",
|
||||
" //1、创建3名老师的数组\n",
|
||||
" struct Teacher tArray[3];\n",
|
||||
"\n",
|
||||
" //2、通过函数给3名老师的信息赋值,并给老师带的学生信息赋值\n",
|
||||
" int len = sizeof(tArray) / sizeof(tArray[0]);\n",
|
||||
" allocateSpace(tArray, len);\n",
|
||||
"\n",
|
||||
" //3、打印所有老师及所带的学生信息\n",
|
||||
" printInfo(tArray, len);\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
"老师姓名:Teacher_A\n",
|
||||
" 学生姓名:Student_A 考试分数:81\n",
|
||||
" 学生姓名:Student_B 考试分数:85\n",
|
||||
" 学生姓名:Student_C 考试分数:91\n",
|
||||
" 学生姓名:Student_D 考试分数:66\n",
|
||||
" 学生姓名:Student_E 考试分数:55\n",
|
||||
"老师姓名:Teacher_B\n",
|
||||
" 学生姓名:Student_A 考试分数:87\n",
|
||||
" 学生姓名:Student_B 考试分数:50\n",
|
||||
" 学生姓名:Student_C 考试分数:57\n",
|
||||
" 学生姓名:Student_D 考试分数:40\n",
|
||||
" 学生姓名:Student_E 考试分数:43\n",
|
||||
"老师姓名:Teacher_C\n",
|
||||
" 学生姓名:Student_A 考试分数:72\n",
|
||||
" 学生姓名:Student_B 考试分数:64\n",
|
||||
" 学生姓名:Student_C 考试分数:80\n",
|
||||
" 学生姓名:Student_D 考试分数:92\n",
|
||||
" 学生姓名:Student_E 考试分数:58\n",
|
||||
"请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.8 结构体案例(二)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"案例描述:设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。通过冒泡排序算法,将数组中英雄按照年龄进行升序排序,最终打印排序后的结果。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"五名英雄信息如下: \n",
|
||||
" - {\"刘备\",23,\"男\"} \n",
|
||||
" - {\"关羽\",22,\"男\"} \n",
|
||||
" - {\"张飞\",20,\"男\"} \n",
|
||||
" - {\"赵云\",21,\"女\"} \n",
|
||||
" - {\"貂蝉\",19,\"女\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//1、设计英雄结构体\n",
|
||||
"struct Hero\n",
|
||||
"{\n",
|
||||
" //姓名\n",
|
||||
" string name;\n",
|
||||
" //年龄\n",
|
||||
" int age;\n",
|
||||
" //性别\n",
|
||||
" string sex;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"//冒泡排序,实现年龄升序排列\n",
|
||||
"void bubbleSort(struct Hero heroArray[], int len)\n",
|
||||
"{\n",
|
||||
" for (int i = 0; i < len - 1; i++)\n",
|
||||
" {\n",
|
||||
" for (int j = 0; j < len - i - 1; j++)\n",
|
||||
" {\n",
|
||||
" //如果j下标的年龄大于j+1下标的元素的年龄,交换两个元素\n",
|
||||
" if (heroArray[j].age > heroArray[j + 1].age)\n",
|
||||
" {\n",
|
||||
" struct Hero temp = heroArray[j]; //创建一个临时结构体变量\n",
|
||||
" heroArray[j] = heroArray[j + 1];\n",
|
||||
" heroArray[j + 1] = temp;\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"void printHero(struct Hero heroArray[], int len)\n",
|
||||
"{\n",
|
||||
" for (int i = 0; i < len; i++)\n",
|
||||
" {\n",
|
||||
" cout << \"姓名:\" << heroArray[i].name << \" 年龄:\" << heroArray[i].age\n",
|
||||
" << \" 性别:\" << heroArray[i].sex << endl;\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
"\n",
|
||||
" //2、创建数组存放5名英雄\n",
|
||||
" struct Hero heroArray[5] =\n",
|
||||
" {\n",
|
||||
" {\"刘备\",23,\"男\"},\n",
|
||||
" {\"关羽\",22,\"男\"},\n",
|
||||
" {\"张飞\",20,\"男\"},\n",
|
||||
" {\"赵云\",21,\"女\"},\n",
|
||||
" {\"貂蝉\",19,\"女\"},\n",
|
||||
" };\n",
|
||||
"\n",
|
||||
" int len = sizeof(heroArray) / sizeof(heroArray[0]);\n",
|
||||
" cout << \"排序前的打印结果\" << endl;\n",
|
||||
" for (int i = 0; i < len; i++)\n",
|
||||
" {\n",
|
||||
" cout << \"姓名:\" << heroArray[i].name << \" 年龄:\" << heroArray[i].age\n",
|
||||
" << \" 性别:\" << heroArray[i].sex << endl;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //3、对数组进行排序,按照年龄进行升序排序\n",
|
||||
" bubbleSort(heroArray, len);\n",
|
||||
"\n",
|
||||
" //4、将排序后结果打印输出\n",
|
||||
" cout << \"排序后的打印结果\" << endl;\n",
|
||||
" printHero(heroArray,len);\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 排序前的打印结果 \n",
|
||||
" - 姓名:刘备 年龄:23 性别:男 \n",
|
||||
" - 姓名:关羽 年龄:22 性别:男 \n",
|
||||
" - 姓名:张飞 年龄:20 性别:男 \n",
|
||||
" - 姓名:赵云 年龄:21 性别:女 \n",
|
||||
" - 姓名:貂蝉 年龄:19 性别:女 \n",
|
||||
" - 排序后的打印结果 \n",
|
||||
" - 姓名:貂蝉 年龄:19 性别:女 \n",
|
||||
" - 姓名:张飞 年龄:20 性别:男 \n",
|
||||
" - 姓名:赵云 年龄:21 性别:女 \n",
|
||||
" - 姓名:关羽 年龄:22 性别:男 \n",
|
||||
" - 姓名:刘备 年龄:23 性别:男 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
674
docs/CPlusPlus-main/16_C++的结构体.md
Normal file
@ -0,0 +1,674 @@
|
||||
# C++的结构体
|
||||
|
||||
# 1. 结构体
|
||||
|
||||
① 结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。
|
||||
|
||||
② 语法:struct 结构体名 { 结构体成员列表 }
|
||||
|
||||
③ 通过结构体创建变量的方式有三种:
|
||||
|
||||
1. struct 结构体名 变量名
|
||||
2. struct 结构体名 变量名 = { 成员1值,成员2值 }
|
||||
3. 定义结构体时顺便创建变量
|
||||
|
||||
④ 结构体变量利用点.访问成员
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string>
|
||||
//自定义数据类型,一些类型的集合组成一个类型
|
||||
//语法 struct 类型名称 { 成员列表 }
|
||||
//结构体定义的时候,struct关键字不能省略
|
||||
//1、创建学生数据类型:学生包括(姓名,年龄,分数)
|
||||
struct Student
|
||||
{
|
||||
//成员列表
|
||||
|
||||
//姓名
|
||||
string name;
|
||||
//年龄
|
||||
int age;
|
||||
//分数
|
||||
int score;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
//2.1 struct Student s1 s1类似结构体的实例值,类似变量赋值:int a = 10 → 属性 变量 变量值
|
||||
//结构体创建的时候,struct 关键字可以省略;上面结构体定义的时候 struct 可以省略
|
||||
struct Student s1;
|
||||
//给s1属性赋值,通过点.访问结构体变量中的属性
|
||||
s1.name = "张三";
|
||||
s1.age = 18;
|
||||
s1.score = 100;
|
||||
|
||||
cout << "姓名:" << s1.name << "年龄:" << s1.age << "分数:" << s1.score << endl;
|
||||
|
||||
//2.2 struct Student s2 = { ... }
|
||||
struct Student s2 = { "李四",19,80 };
|
||||
cout << "姓名:" << s2.name << "年龄:" << s2.age << "分数:" << s2.score << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 姓名:张三年龄:18分数:100
|
||||
- 姓名:李四年龄:19分数:80
|
||||
- 请按任意键继续. . .
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string>
|
||||
//自定义数据类型,一些类型的集合组成一个类型
|
||||
struct Student
|
||||
{
|
||||
//成员列表
|
||||
|
||||
//姓名
|
||||
string name;
|
||||
//年龄
|
||||
int age;
|
||||
//分数
|
||||
int score;
|
||||
}s3; //2.3 创建结构体的时候,顺便创建个结构体变量
|
||||
|
||||
int main()
|
||||
{
|
||||
//2.3
|
||||
s3.name = "王五";
|
||||
s3.age = 20;
|
||||
s3.score = 60;
|
||||
|
||||
cout << "姓名:" << s3.name << "年龄:" << s3.age << "分数:" << s3.score << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 姓名:王五年龄:20分数:60
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.1 结构体定义和使用
|
||||
|
||||
① 作用:将自定义的结构体放入到数组中方便维护。
|
||||
|
||||
② 语法:struct 结构体名 数组名[元素个数] = { {},{},...,{} }
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string>
|
||||
//自定义数据类型,一些类型的集合组成一个类型
|
||||
struct Student
|
||||
{
|
||||
//成员列表
|
||||
|
||||
//姓名
|
||||
string name;
|
||||
//年龄
|
||||
int age;
|
||||
//分数
|
||||
int score;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
//2、创建结构体数组
|
||||
struct Student stuArray[3] =
|
||||
{
|
||||
{"张三",18,100},
|
||||
{"李四",28,99},
|
||||
{"王五",38,66}
|
||||
};
|
||||
|
||||
//3、给结构体数组中的元素赋值
|
||||
stuArray[2].name = "赵六";
|
||||
stuArray[2].age = 80;
|
||||
stuArray[2].score = 60;
|
||||
|
||||
//4、遍历结构体数组
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
cout << "姓名:" << stuArray[i].name << "年龄:" << stuArray[i].age << "分数:" << stuArray[i].score << endl;
|
||||
}
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 姓名:张三年龄:18分数:100
|
||||
- 姓名:李四年龄:28分数:99
|
||||
- 姓名:赵六年龄:80分数:60
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.2 结构体数组
|
||||
|
||||
① 作用:将自定义的结构体放入到数组中方便维护。
|
||||
|
||||
② 语法:struct 结构体名 数组名[元素个数] = { {},{},...,{} }
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string>
|
||||
//自定义数据类型,一些类型的集合组成一个类型
|
||||
struct Student
|
||||
{
|
||||
//成员列表
|
||||
|
||||
//姓名
|
||||
string name;
|
||||
//年龄
|
||||
int age;
|
||||
//分数
|
||||
int score;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
//2、创建结构体数组
|
||||
struct Student stuArray[3] =
|
||||
{
|
||||
{"张三",18,100},
|
||||
{"李四",28,99},
|
||||
{"王五",38,66}
|
||||
};
|
||||
|
||||
//3、给结构体数组中的元素赋值
|
||||
stuArray[2].name = "赵六";
|
||||
stuArray[2].age = 80;
|
||||
stuArray[2].score = 60;
|
||||
|
||||
//4、遍历结构体数组
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
cout << "姓名:" << stuArray[i].name << "年龄:" << stuArray[i].age << "分数:" << stuArray[i].score << endl;
|
||||
}
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 姓名:张三年龄:18分数:100
|
||||
- 姓名:李四年龄:28分数:99
|
||||
- 姓名:赵六年龄:80分数:60
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.3 结构体指针
|
||||
|
||||
① 作用:通过指针访问结构体中的成员。
|
||||
|
||||
② 利用操作符 · > 可以通过结构体指针访问结构体属性。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string>
|
||||
|
||||
//结构体指针
|
||||
|
||||
//定义学生结构体
|
||||
struct Student
|
||||
{
|
||||
string name; //姓名
|
||||
int age; //年龄
|
||||
int score; //分数
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// 1、创建学生结构体变量,这里的 struct 可以省略
|
||||
struct Student s = { "张三",18,100 };
|
||||
|
||||
//2、通过指针指向结构体变量
|
||||
struct Student* p = &s; //对s取地址, tudent * p 类似 int * p,这里的 struct 可以省略
|
||||
|
||||
//3、通过指针访问结构体变量中的数据
|
||||
//通过结构体指针 访问结构体中的属性,需要利用'->'
|
||||
cout << "姓名:" << p->name << "年龄:" << p->age << "分数:" << p->score << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 姓名:张三年龄:18分数:100
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.4 结构体嵌套结构体
|
||||
|
||||
① 结构体中的成员可以是另一个结构体。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string>
|
||||
|
||||
//因为老师的结构体里有学生的结构体,所以学生结构体要在老师结构体前面先定义
|
||||
//定义学生结构体
|
||||
struct student
|
||||
{
|
||||
string name; //姓名
|
||||
int age; //年龄
|
||||
int score; //分数
|
||||
};
|
||||
|
||||
//定义老师结构体
|
||||
struct teacher
|
||||
{
|
||||
int id; //教师编号
|
||||
string name; //教师姓名
|
||||
int age; //年龄
|
||||
struct student stu; //学生结构体
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
//结构体嵌套结构体
|
||||
//创建老师
|
||||
teacher t;
|
||||
t.id = 10000;
|
||||
t.name = "老王";
|
||||
t.age = 50;
|
||||
t.stu.name = "小王";
|
||||
t.stu.age = 20;
|
||||
t.stu.score = 60;
|
||||
|
||||
cout << "老师姓名:" << t.name << "老师编号:" << t.id << "老师年龄:" << t.age
|
||||
<< "老师辅导的学生姓名:" << t.stu.name << "学生年龄:" << t.stu.age
|
||||
<< "学生考试分数:" << t.stu.score << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 老师姓名:老王 老师编号:10000 老师年龄:50 老师辅导的学生姓名:小王 学生年龄:20 学生考试分数:60
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.5 结构体做函数参数
|
||||
|
||||
① 作用:将结构体作为参数向函数中传递,传递方式有两种。
|
||||
|
||||
② 传递方式有两种:
|
||||
|
||||
1. 值传递
|
||||
2. 地址传递
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string>
|
||||
|
||||
//定义学生结构体
|
||||
struct student
|
||||
{
|
||||
string name; //姓名
|
||||
int age; //年龄
|
||||
int score; //分数
|
||||
};
|
||||
|
||||
//定义老师结构体
|
||||
struct teacher
|
||||
{
|
||||
int id; //教师编号
|
||||
string name; //教师姓名
|
||||
int age; //年龄
|
||||
struct student stu; //学生结构体
|
||||
};
|
||||
|
||||
//打印学生信息的函数
|
||||
//1、值传递
|
||||
void printStudent1(struct student s)
|
||||
{
|
||||
cout << "子函数 值传递前 姓名:" << s.name << "年龄:" << s.age << "分数:" << s.score << endl;
|
||||
|
||||
s.age = 100;
|
||||
}
|
||||
|
||||
//2、地址传递
|
||||
void printStudent2(struct student* p)
|
||||
{
|
||||
cout << "子函数 地址传递前 姓名:" << p->name << "年龄:" << p->age << "分数:" << p->score << endl;
|
||||
|
||||
p->score = 90;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
//结构体做函数参数
|
||||
//将学生传入到一个参数中,打印学生身上的所有信息
|
||||
|
||||
//创建结构体变量
|
||||
struct student s;
|
||||
s.name = "张三";
|
||||
s.age = 20;
|
||||
s.score = 85;
|
||||
|
||||
cout << "main函数 传递前 姓名:" << s.name << "年龄:" << s.age << "分数:" << s.score << endl;
|
||||
|
||||
printStudent1(s);
|
||||
|
||||
cout << "子函数 值传递后 姓名:" << s.name << "年龄:" << s.age << "分数:" << s.score << endl;
|
||||
|
||||
printStudent2(&s);
|
||||
|
||||
cout << "子函数 地址传递后 姓名:" << s.name << "年龄:" << s.age << "分数:" << s.score << endl;
|
||||
|
||||
|
||||
cout << "main函数 传递后 姓名:" << s.name << "年龄:" << s.age << "分数:" << s.score << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- main函数 传递前 姓名:张三年龄:20分数:85
|
||||
- 子函数 值传递前 姓名:张三年龄:20分数:85
|
||||
- 子函数 值传递后 姓名:张三年龄:20分数:85
|
||||
- 子函数 地址传递前 姓名:张三年龄:20分数:85
|
||||
- 子函数 地址传递后 姓名:张三年龄:20分数:90
|
||||
- main函数 传递后 姓名:张三年龄:20分数:90
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.6 结构体中const使用
|
||||
|
||||
① 作用:const来防止误操作。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string>
|
||||
|
||||
//const 的使用场景
|
||||
|
||||
struct student
|
||||
{
|
||||
//姓名
|
||||
string name;
|
||||
//年龄
|
||||
int age;
|
||||
//分数
|
||||
int score;
|
||||
};
|
||||
|
||||
//将函数中形参设置为指针,用地址传递,而不是值传递,可以减少内存空间,而且不会复制新的副本
|
||||
//值传递需要复制新的副本,如果有成千上万个学生调用结构体,会复制成千上个副本
|
||||
void printStudents(const student* s)
|
||||
{
|
||||
s->age = 150; //报错,因为假如const之后,一旦有修改的操作就会报错,可以防止我们的误操作。
|
||||
cout << "姓名:" << s->name << "年龄:" << s->age << "分数:" << s->score << endl;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
//创建结构体变量
|
||||
struct student s = { "张三",15,70 };
|
||||
|
||||
//通过函数打印结构体变量信息
|
||||
printStudents(&s);
|
||||
|
||||
cout << "main中张三年龄为:" << s.age << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## 1.7 结构体案例(一)
|
||||
|
||||
案例描述:学校正在做毕设项目,每名老师带领5个学生,总共有3名老师,需求如下:设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员,学生的成员有姓名、考试分数、创建数组存放3名老师,通过函数给每个老师及所带的学生赋值。最终打印出老师数据以及老师所带的学生数据。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string>
|
||||
#include <Ctime>
|
||||
|
||||
//学生结构体定义
|
||||
struct Student
|
||||
{
|
||||
//姓名
|
||||
string sName;
|
||||
//学生数组
|
||||
int score;
|
||||
};
|
||||
|
||||
//老师结构体
|
||||
struct Teacher
|
||||
{
|
||||
//姓名
|
||||
string tName;
|
||||
//学生数组
|
||||
struct Student sArray[5];
|
||||
};
|
||||
|
||||
//给老师和学生赋值的函数
|
||||
void allocateSpace(struct Teacher tArray[], int len) //接收数组的两种方式:一用指针,二用数组名 struct Teacher tArray[]
|
||||
{
|
||||
string nameSeed = "ABCDE";
|
||||
//给老师开始赋值
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
tArray[i].tName = "Teacher_";
|
||||
tArray[i].tName += nameSeed[i];
|
||||
|
||||
//通过循环给每名老师所带的学生赋值
|
||||
for (int j = 0; j < 5; j++)
|
||||
{
|
||||
tArray[i].sArray[j].sName = "Student_";
|
||||
tArray[i].sArray[j].sName += nameSeed[j];
|
||||
|
||||
int random = rand() % 61 + 40; // 40 ~ 100
|
||||
tArray[i].sArray[j].score = random; //
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//打印所有信息
|
||||
void printInfo(struct Teacher tArray[], int len)
|
||||
{
|
||||
for (int i = 0;i<len;i++)
|
||||
{
|
||||
cout << "老师姓名:" << tArray[i].tName << endl;
|
||||
|
||||
for (int j = 0; j < 5; j++)
|
||||
{
|
||||
cout << "\t学生姓名:" << tArray[i].sArray[j].sName
|
||||
<< " 考试分数:" << tArray[i].sArray[j].score << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
//随机数种子
|
||||
srand((unsigned int)time(NULL));
|
||||
|
||||
//1、创建3名老师的数组
|
||||
struct Teacher tArray[3];
|
||||
|
||||
//2、通过函数给3名老师的信息赋值,并给老师带的学生信息赋值
|
||||
int len = sizeof(tArray) / sizeof(tArray[0]);
|
||||
allocateSpace(tArray, len);
|
||||
|
||||
//3、打印所有老师及所带的学生信息
|
||||
printInfo(tArray, len);
|
||||
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
运行结果:
|
||||
老师姓名:Teacher_A
|
||||
学生姓名:Student_A 考试分数:81
|
||||
学生姓名:Student_B 考试分数:85
|
||||
学生姓名:Student_C 考试分数:91
|
||||
学生姓名:Student_D 考试分数:66
|
||||
学生姓名:Student_E 考试分数:55
|
||||
老师姓名:Teacher_B
|
||||
学生姓名:Student_A 考试分数:87
|
||||
学生姓名:Student_B 考试分数:50
|
||||
学生姓名:Student_C 考试分数:57
|
||||
学生姓名:Student_D 考试分数:40
|
||||
学生姓名:Student_E 考试分数:43
|
||||
老师姓名:Teacher_C
|
||||
学生姓名:Student_A 考试分数:72
|
||||
学生姓名:Student_B 考试分数:64
|
||||
学生姓名:Student_C 考试分数:80
|
||||
学生姓名:Student_D 考试分数:92
|
||||
学生姓名:Student_E 考试分数:58
|
||||
请按任意键继续. . .
|
||||
```
|
||||
|
||||
## 1.8 结构体案例(二)
|
||||
|
||||
案例描述:设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。通过冒泡排序算法,将数组中英雄按照年龄进行升序排序,最终打印排序后的结果。
|
||||
|
||||
五名英雄信息如下:
|
||||
- {"刘备",23,"男"}
|
||||
- {"关羽",22,"男"}
|
||||
- {"张飞",20,"男"}
|
||||
- {"赵云",21,"女"}
|
||||
- {"貂蝉",19,"女"}
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//1、设计英雄结构体
|
||||
struct Hero
|
||||
{
|
||||
//姓名
|
||||
string name;
|
||||
//年龄
|
||||
int age;
|
||||
//性别
|
||||
string sex;
|
||||
};
|
||||
|
||||
//冒泡排序,实现年龄升序排列
|
||||
void bubbleSort(struct Hero heroArray[], int len)
|
||||
{
|
||||
for (int i = 0; i < len - 1; i++)
|
||||
{
|
||||
for (int j = 0; j < len - i - 1; j++)
|
||||
{
|
||||
//如果j下标的年龄大于j+1下标的元素的年龄,交换两个元素
|
||||
if (heroArray[j].age > heroArray[j + 1].age)
|
||||
{
|
||||
struct Hero temp = heroArray[j]; //创建一个临时结构体变量
|
||||
heroArray[j] = heroArray[j + 1];
|
||||
heroArray[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void printHero(struct Hero heroArray[], int len)
|
||||
{
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
cout << "姓名:" << heroArray[i].name << " 年龄:" << heroArray[i].age
|
||||
<< " 性别:" << heroArray[i].sex << endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
//2、创建数组存放5名英雄
|
||||
struct Hero heroArray[5] =
|
||||
{
|
||||
{"刘备",23,"男"},
|
||||
{"关羽",22,"男"},
|
||||
{"张飞",20,"男"},
|
||||
{"赵云",21,"女"},
|
||||
{"貂蝉",19,"女"},
|
||||
};
|
||||
|
||||
int len = sizeof(heroArray) / sizeof(heroArray[0]);
|
||||
cout << "排序前的打印结果" << endl;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
cout << "姓名:" << heroArray[i].name << " 年龄:" << heroArray[i].age
|
||||
<< " 性别:" << heroArray[i].sex << endl;
|
||||
}
|
||||
|
||||
//3、对数组进行排序,按照年龄进行升序排序
|
||||
bubbleSort(heroArray, len);
|
||||
|
||||
//4、将排序后结果打印输出
|
||||
cout << "排序后的打印结果" << endl;
|
||||
printHero(heroArray,len);
|
||||
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 排序前的打印结果
|
||||
- 姓名:刘备 年龄:23 性别:男
|
||||
- 姓名:关羽 年龄:22 性别:男
|
||||
- 姓名:张飞 年龄:20 性别:男
|
||||
- 姓名:赵云 年龄:21 性别:女
|
||||
- 姓名:貂蝉 年龄:19 性别:女
|
||||
- 排序后的打印结果
|
||||
- 姓名:貂蝉 年龄:19 性别:女
|
||||
- 姓名:张飞 年龄:20 性别:男
|
||||
- 姓名:赵云 年龄:21 性别:女
|
||||
- 姓名:关羽 年龄:22 性别:男
|
||||
- 姓名:刘备 年龄:23 性别:男
|
||||
- 请按任意键继续. . .
|
||||
429
docs/CPlusPlus-main/17_C++的内存模型.ipynb
Normal file
@ -0,0 +1,429 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的内存模型"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 内存分区"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① C++在程序执行时,将内存大方向划分为4个区域。\n",
|
||||
"\n",
|
||||
"1. 代码区:存放函数体的二进制代码,由操作系统进行管理的。\n",
|
||||
"2. 全局区:存放全局变量和静态变量以及常量。\n",
|
||||
"3. 栈区:由编译器自动分配释放,存放函数的参数值、局部变量等。\n",
|
||||
"4. 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收。\n",
|
||||
"\n",
|
||||
"② 内存四区的意义:不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域:代码区、全局区。\n",
|
||||
"\n",
|
||||
"② 所有的写的代码(注释、变量、语句等)都会放到代码区中。\n",
|
||||
"\n",
|
||||
"③ 栈区中的数据由编译器决定数据的生成和死亡。\n",
|
||||
"\n",
|
||||
"④ 堆区中的数据由程序员决定数据的生存和死亡。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 2. 内存四区"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2.1 代码区"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 代码区:\n",
|
||||
"\n",
|
||||
"1. 存放CPU执行的机器指令。\n",
|
||||
"2. 代码区是共享的,共享的目的是对于频繁被执行的程序,只需要内存中有一份代码即可。\n",
|
||||
"3. 代码区是只读的,使其只读的原因是防止程序员意外地修改了它的指令。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2.2 全局区"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 全局区:\n",
|
||||
"\n",
|
||||
"1. 全局变量和静态变量存放在此,局部常量不放在全局区。\n",
|
||||
"2. 全局区还包含了常量区,字符串常量和其他常量也存放在此。\n",
|
||||
"3. 该区域的数据在程序结束后由操作系统释放。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//全局变量\n",
|
||||
"int g_a = 10;\n",
|
||||
"int g_b = 20;\n",
|
||||
"\n",
|
||||
"//const修饰的全局常量\n",
|
||||
"const int c_g_a = 50;\n",
|
||||
"const int c_g_b = 60;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //全局区\n",
|
||||
"\n",
|
||||
" //全局变量、静态变量、常量\n",
|
||||
"\n",
|
||||
" //创建普通局部变量\n",
|
||||
" int a = 30;\n",
|
||||
" int b = 40;\n",
|
||||
"\n",
|
||||
" cout << \"局部变量a的地址为:\" << (int)&a << endl;\n",
|
||||
" cout << \"局部变量b的地址为:\" << (int)&b << endl;\n",
|
||||
"\n",
|
||||
" cout << \"全局变量g_a的地址为:\" << (int)&g_a << endl;\n",
|
||||
" cout << \"全局变量g_b的地址为:\" << (int)&g_b << endl;\n",
|
||||
"\n",
|
||||
" //静态变量 在普通变量前面加static,属于静态变量\n",
|
||||
" static int s_a = 10;\n",
|
||||
" static int s_b = 10;\n",
|
||||
"\n",
|
||||
" cout << \"静态变量s_a的地址为:\" << (int)&s_a << endl;\n",
|
||||
" cout << \"静态变量s_b的地址为:\" << (int)&s_b << endl;\n",
|
||||
"\n",
|
||||
" //常量\n",
|
||||
" //字符串常量\n",
|
||||
" cout << \"字符串常量的地址为:\" << (int)&\"hello world\" << endl;\n",
|
||||
"\n",
|
||||
" //const修饰的变量\n",
|
||||
" //const修饰的局部变量,const修饰的局部变量\n",
|
||||
" cout << \"全局常量c_g_a的地址为:\" << (int)&c_g_a << endl;\n",
|
||||
" cout << \"全局常量c_g_a的地址为:\" << (int)&c_g_b << endl;\n",
|
||||
"\n",
|
||||
" const int c_l_a = 10; // c-const g-global l-local;\n",
|
||||
" const int c_l_b = 10;\n",
|
||||
" cout << \"局域常量c_l_a的地址为:\" << (int)&c_l_a << endl;\n",
|
||||
" cout << \"局域常量c_l_b的地址为:\" << (int)&c_l_a << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 局部变量a的地址为:14023100 \n",
|
||||
" - 局部变量b的地址为:14023088 \n",
|
||||
" - 全局变量g_a的地址为:4964352 \n",
|
||||
" - 全局变量g_b的地址为:4964356 \n",
|
||||
" - 静态变量s_a的地址为:4964360 \n",
|
||||
" - 静态变量s_b的地址为:4964364 \n",
|
||||
" - 字符串常量的地址为:4955128 \n",
|
||||
" - 全局常量c_g_a的地址为:4954928 \n",
|
||||
" - 全局常量c_g_a的地址为:4954932 \n",
|
||||
" - 局域常量c_l_a的地址为:14023076 \n",
|
||||
" - 局域常量c_l_b的地址为:14023076 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2.3 栈区"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 栈区\n",
|
||||
"\n",
|
||||
"1. 由编译器自动分配释放,存放函数的参数值、局部变量等。\n",
|
||||
"2. 不要返回局部变量的地址,栈区开辟的数据由编译器自动释放。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//栈区数据注意事项:不要返回局部变量的地址\n",
|
||||
"//栈区的数据由编译器管理开辟和释放\n",
|
||||
"\n",
|
||||
"int* func(int b) //返回的是一个地址 int*;形参的数据也会放在栈区\n",
|
||||
"{\n",
|
||||
" int a = 10; //局部变量存放的数据10存放在栈区,栈区的数据在函数执行完后自动释放\n",
|
||||
" return &a; //返回局部变量的地址,即数据10的的地址\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //接收func函数的返回值\n",
|
||||
" int* p = func(1); //用指针接收栈区上的数据10的地址,由于栈区上数据10已经被释放,所以对地址解引用会获得乱码的值。\n",
|
||||
"\n",
|
||||
" cout << *p << endl; //第一次可以 打印正确的数字,是因为编译器做了保留\n",
|
||||
" cout << *p << endl; //第二次这个数据就不在保留了。\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 10 \n",
|
||||
" - 1905325 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2.4 堆区"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 堆区:\n",
|
||||
"\n",
|
||||
"1. 由程序员分配释放,若程序员不释放,程序结束时由操作系统回收。\n",
|
||||
"2. 在C++中主要利用new在堆区开辟内存。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int* func() //返回的是一个地址 int*;形参的数据也会放在栈区\n",
|
||||
"{\n",
|
||||
" //利用new关键字,可以将数据开辟到堆区\n",
|
||||
" //指针本质也是变量,这里的指针是局部变量,局部变量的数据放在栈上,即指针保存的数据是放在堆区\n",
|
||||
" int * p = new int(10); //new关键字会返回一个地址,因此用栈上的指针来接收堆上数据的地址。\n",
|
||||
" return p;\n",
|
||||
"}\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //在堆区开辟数据\n",
|
||||
" int* p = func(); //堆区的地址返回给 *p 了,栈区数据是否,堆区数据没释放\n",
|
||||
"\n",
|
||||
" cout << *p << endl;\n",
|
||||
" cout << *p << endl;\n",
|
||||
" cout << *p << endl;\n",
|
||||
" cout << *p << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 10 \n",
|
||||
" - 10 \n",
|
||||
" - 10 \n",
|
||||
" - 10 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 3. new操作符"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① C++中利用new操作符在堆区开辟数据。\n",
|
||||
"\n",
|
||||
"② 堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符 delete。\n",
|
||||
"\n",
|
||||
"③ 语法:new 数据类型\n",
|
||||
"\n",
|
||||
"④ 利用new创建的数据,会返回该数据对应的类型的指针。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//1、new的基本语法\n",
|
||||
"\n",
|
||||
"int* func() //返回的是一个地址 int*;形参的数据也会放在栈区\n",
|
||||
"{\n",
|
||||
" //在堆区创建整型数据\n",
|
||||
" //new返回是该数据类型的指针\n",
|
||||
" int* p = new int(10);\n",
|
||||
" return p;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" int* p = func();\n",
|
||||
" cout << *p << endl;\n",
|
||||
" cout << *p << endl;\n",
|
||||
" cout << *p << endl;\n",
|
||||
" //堆区的数据,由程序员管理开辟,程序员管理释放\n",
|
||||
" //如果想释放堆区数据,利用关键字 delete\n",
|
||||
" delete p;\n",
|
||||
"\n",
|
||||
" // cout << *p << endl; //报错,内存已经被释放,再次访问就是非法操作,会报错\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"//2、在堆区利用new开辟数据\n",
|
||||
"void test02()\n",
|
||||
"{\n",
|
||||
" //创建10整型数据的数组,在堆区\n",
|
||||
" int* arr = new int[10];//10代表数组有10个元素\n",
|
||||
"\n",
|
||||
" for (int i = 0; i < 10; i++)\n",
|
||||
" {\n",
|
||||
" arr[i] = i + 100; //给10个元素赋值 100~109\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" for (int i = 0; i < 10; i++)\n",
|
||||
" {\n",
|
||||
" cout << arr[i] << endl; \n",
|
||||
" }\n",
|
||||
" //释放堆区数据\n",
|
||||
" //释放数组的时候,要加[]才可以\n",
|
||||
" delete[] arr;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" test01();\n",
|
||||
" test02();\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 10 \n",
|
||||
" - 10 \n",
|
||||
" - 10 \n",
|
||||
" - 100 \n",
|
||||
" - 101 \n",
|
||||
" - 102 \n",
|
||||
" - 103 \n",
|
||||
" - 104 \n",
|
||||
" - 105 \n",
|
||||
" - 106 \n",
|
||||
" - 107 \n",
|
||||
" - 108 \n",
|
||||
" - 109 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
279
docs/CPlusPlus-main/17_C++的内存模型.md
Normal file
@ -0,0 +1,279 @@
|
||||
# C++的内存模型
|
||||
|
||||
# 1. 内存分区
|
||||
|
||||
① C++在程序执行时,将内存大方向划分为4个区域。
|
||||
|
||||
1. 代码区:存放函数体的二进制代码,由操作系统进行管理的。
|
||||
2. 全局区:存放全局变量和静态变量以及常量。
|
||||
3. 栈区:由编译器自动分配释放,存放函数的参数值、局部变量等。
|
||||
4. 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收。
|
||||
|
||||
② 内存四区的意义:不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程。
|
||||
|
||||
① 在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域:代码区、全局区。
|
||||
|
||||
② 所有的写的代码(注释、变量、语句等)都会放到代码区中。
|
||||
|
||||
③ 栈区中的数据由编译器决定数据的生成和死亡。
|
||||
|
||||
④ 堆区中的数据由程序员决定数据的生存和死亡。
|
||||
|
||||
# 2. 内存四区
|
||||
|
||||
## 2.1 代码区
|
||||
|
||||
① 代码区:
|
||||
|
||||
1. 存放CPU执行的机器指令。
|
||||
2. 代码区是共享的,共享的目的是对于频繁被执行的程序,只需要内存中有一份代码即可。
|
||||
3. 代码区是只读的,使其只读的原因是防止程序员意外地修改了它的指令。
|
||||
|
||||
## 2.2 全局区
|
||||
|
||||
① 全局区:
|
||||
|
||||
1. 全局变量和静态变量存放在此,局部常量不放在全局区。
|
||||
2. 全局区还包含了常量区,字符串常量和其他常量也存放在此。
|
||||
3. 该区域的数据在程序结束后由操作系统释放。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//全局变量
|
||||
int g_a = 10;
|
||||
int g_b = 20;
|
||||
|
||||
//const修饰的全局常量
|
||||
const int c_g_a = 50;
|
||||
const int c_g_b = 60;
|
||||
|
||||
int main()
|
||||
{
|
||||
//全局区
|
||||
|
||||
//全局变量、静态变量、常量
|
||||
|
||||
//创建普通局部变量
|
||||
int a = 30;
|
||||
int b = 40;
|
||||
|
||||
cout << "局部变量a的地址为:" << (int)&a << endl;
|
||||
cout << "局部变量b的地址为:" << (int)&b << endl;
|
||||
|
||||
cout << "全局变量g_a的地址为:" << (int)&g_a << endl;
|
||||
cout << "全局变量g_b的地址为:" << (int)&g_b << endl;
|
||||
|
||||
//静态变量 在普通变量前面加static,属于静态变量
|
||||
static int s_a = 10;
|
||||
static int s_b = 10;
|
||||
|
||||
cout << "静态变量s_a的地址为:" << (int)&s_a << endl;
|
||||
cout << "静态变量s_b的地址为:" << (int)&s_b << endl;
|
||||
|
||||
//常量
|
||||
//字符串常量
|
||||
cout << "字符串常量的地址为:" << (int)&"hello world" << endl;
|
||||
|
||||
//const修饰的变量
|
||||
//const修饰的局部变量,const修饰的局部变量
|
||||
cout << "全局常量c_g_a的地址为:" << (int)&c_g_a << endl;
|
||||
cout << "全局常量c_g_a的地址为:" << (int)&c_g_b << endl;
|
||||
|
||||
const int c_l_a = 10; // c-const g-global l-local;
|
||||
const int c_l_b = 10;
|
||||
cout << "局域常量c_l_a的地址为:" << (int)&c_l_a << endl;
|
||||
cout << "局域常量c_l_b的地址为:" << (int)&c_l_a << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 局部变量a的地址为:14023100
|
||||
- 局部变量b的地址为:14023088
|
||||
- 全局变量g_a的地址为:4964352
|
||||
- 全局变量g_b的地址为:4964356
|
||||
- 静态变量s_a的地址为:4964360
|
||||
- 静态变量s_b的地址为:4964364
|
||||
- 字符串常量的地址为:4955128
|
||||
- 全局常量c_g_a的地址为:4954928
|
||||
- 全局常量c_g_a的地址为:4954932
|
||||
- 局域常量c_l_a的地址为:14023076
|
||||
- 局域常量c_l_b的地址为:14023076
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 2.3 栈区
|
||||
|
||||
① 栈区
|
||||
|
||||
1. 由编译器自动分配释放,存放函数的参数值、局部变量等。
|
||||
2. 不要返回局部变量的地址,栈区开辟的数据由编译器自动释放。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//栈区数据注意事项:不要返回局部变量的地址
|
||||
//栈区的数据由编译器管理开辟和释放
|
||||
|
||||
int* func(int b) //返回的是一个地址 int*;形参的数据也会放在栈区
|
||||
{
|
||||
int a = 10; //局部变量存放的数据10存放在栈区,栈区的数据在函数执行完后自动释放
|
||||
return &a; //返回局部变量的地址,即数据10的的地址
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
//接收func函数的返回值
|
||||
int* p = func(1); //用指针接收栈区上的数据10的地址,由于栈区上数据10已经被释放,所以对地址解引用会获得乱码的值。
|
||||
|
||||
cout << *p << endl; //第一次可以 打印正确的数字,是因为编译器做了保留
|
||||
cout << *p << endl; //第二次这个数据就不在保留了。
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 10
|
||||
- 1905325
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 2.4 堆区
|
||||
|
||||
① 堆区:
|
||||
|
||||
1. 由程序员分配释放,若程序员不释放,程序结束时由操作系统回收。
|
||||
2. 在C++中主要利用new在堆区开辟内存。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int* func() //返回的是一个地址 int*;形参的数据也会放在栈区
|
||||
{
|
||||
//利用new关键字,可以将数据开辟到堆区
|
||||
//指针本质也是变量,这里的指针是局部变量,局部变量的数据放在栈上,即指针保存的数据是放在堆区
|
||||
int * p = new int(10); //new关键字会返回一个地址,因此用栈上的指针来接收堆上数据的地址。
|
||||
return p;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
//在堆区开辟数据
|
||||
int* p = func(); //堆区的地址返回给 *p 了,栈区数据是否,堆区数据没释放
|
||||
|
||||
cout << *p << endl;
|
||||
cout << *p << endl;
|
||||
cout << *p << endl;
|
||||
cout << *p << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 10
|
||||
- 10
|
||||
- 10
|
||||
- 10
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 3. new操作符
|
||||
|
||||
① C++中利用new操作符在堆区开辟数据。
|
||||
|
||||
② 堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符 delete。
|
||||
|
||||
③ 语法:new 数据类型
|
||||
|
||||
④ 利用new创建的数据,会返回该数据对应的类型的指针。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//1、new的基本语法
|
||||
|
||||
int* func() //返回的是一个地址 int*;形参的数据也会放在栈区
|
||||
{
|
||||
//在堆区创建整型数据
|
||||
//new返回是该数据类型的指针
|
||||
int* p = new int(10);
|
||||
return p;
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
int* p = func();
|
||||
cout << *p << endl;
|
||||
cout << *p << endl;
|
||||
cout << *p << endl;
|
||||
//堆区的数据,由程序员管理开辟,程序员管理释放
|
||||
//如果想释放堆区数据,利用关键字 delete
|
||||
delete p;
|
||||
|
||||
// cout << *p << endl; //报错,内存已经被释放,再次访问就是非法操作,会报错
|
||||
}
|
||||
|
||||
//2、在堆区利用new开辟数据
|
||||
void test02()
|
||||
{
|
||||
//创建10整型数据的数组,在堆区
|
||||
int* arr = new int[10];//10代表数组有10个元素
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
arr[i] = i + 100; //给10个元素赋值 100~109
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
cout << arr[i] << endl;
|
||||
}
|
||||
//释放堆区数据
|
||||
//释放数组的时候,要加[]才可以
|
||||
delete[] arr;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 10
|
||||
- 10
|
||||
- 10
|
||||
- 100
|
||||
- 101
|
||||
- 102
|
||||
- 103
|
||||
- 104
|
||||
- 105
|
||||
- 106
|
||||
- 107
|
||||
- 108
|
||||
- 109
|
||||
- 请按任意键继续. . .
|
||||
466
docs/CPlusPlus-main/18_C++的引用.ipynb
Normal file
@ -0,0 +1,466 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的引用"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 引用"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.1 引用基本语法"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 作用:给变量起别名。\n",
|
||||
"\n",
|
||||
"② 语法:数据类型 &别名 = 原名"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //引用基本语法\n",
|
||||
" //数据类型 &别名 = 原名\n",
|
||||
"\n",
|
||||
" int a = 10;\n",
|
||||
" //创建引用\n",
|
||||
" int& b = a;\n",
|
||||
"\n",
|
||||
" b = 100;\n",
|
||||
"\n",
|
||||
" cout << \"a= \" << a << endl;\n",
|
||||
" cout << \"b= \" << a << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - a= 100 \n",
|
||||
" - b= 100 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.2 引用注意事项"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 引用必须初始化。\n",
|
||||
"\n",
|
||||
"② 引用在初始化后,不可以改变。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //1、引用必须初始化\n",
|
||||
" int a = 10;\n",
|
||||
" int &b = a; // int &b; 是错误的,必须要初始化\n",
|
||||
"\n",
|
||||
" //2、引用在初始化后,不可以改变\n",
|
||||
" int c = 20;\n",
|
||||
" b = c; // 赋值操作,而不是更改引用。把 c = 20 的数据20给了 b 指向的内存的数据,而 a、b 的指向的内存是一样的。\n",
|
||||
" // 这里并不是 b 指向 c 的内存。\n",
|
||||
"\n",
|
||||
" cout << \"a = \" << a << endl; //a内存中数据变了\n",
|
||||
" cout << \"b = \" << b << endl;\n",
|
||||
" cout << \"c = \" << c << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - a = 20 \n",
|
||||
" - b = 20 \n",
|
||||
" - c = 20 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.3 引用做函数参数"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 函数传参时,可以利用引用的技术让形参修饰实参。\n",
|
||||
"\n",
|
||||
"② 可以简化指针修改实参。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//1、值传递\n",
|
||||
"void mySwap01(int a,int b)\n",
|
||||
"{\n",
|
||||
" int temp = a;\n",
|
||||
" a = b;\n",
|
||||
" b = temp;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"//2、地址传递\n",
|
||||
"void mySwap02(int * a, int * b)\n",
|
||||
"{\n",
|
||||
" int temp = *a;\n",
|
||||
" *a = *b;\n",
|
||||
" *b = temp;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"//2、引用传递\n",
|
||||
"//这里面的&a的实参为a(恰巧为a,恰巧一样)的别名,对&a中的a操作修改,就是对实参a修改\n",
|
||||
"void mySwap03(int &a, int &b) \n",
|
||||
"{\n",
|
||||
" int temp = a;\n",
|
||||
" a = b;\n",
|
||||
" b = temp;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" int a = 10;\n",
|
||||
" int b = 20;\n",
|
||||
"\n",
|
||||
" mySwap01(a, b); //值传递,形参不会修饰实参\n",
|
||||
" \n",
|
||||
" cout << \"a = \" << a << endl;\n",
|
||||
" cout << \"b = \" << b << endl;\n",
|
||||
"\n",
|
||||
" mySwap02(&a, &b); //地址传递,形参会修饰实参\n",
|
||||
"\n",
|
||||
" cout << \"a = \" << a << endl;\n",
|
||||
" cout << \"b = \" << b << endl;\n",
|
||||
"\n",
|
||||
" mySwap03(a, b); //引用传递,形参会修饰实参\n",
|
||||
"\n",
|
||||
" cout << \"a = \" << a << endl;\n",
|
||||
" cout << \"b = \" << b << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - a = 10 \n",
|
||||
" - b = 20 \n",
|
||||
" - a = 20 \n",
|
||||
" - b = 10 \n",
|
||||
" - a = 10 \n",
|
||||
" - b = 20 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.4 引用做函数返回值"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 引用是可以作为函数的返回值存在的。\n",
|
||||
"\n",
|
||||
"② 不要返回局部变量引用。\n",
|
||||
"\n",
|
||||
"③ 函数调用可以作为左值。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//引用做函数的返回值\n",
|
||||
"//1、不要返回局部变量的引用\n",
|
||||
"int& test01()\n",
|
||||
"{\n",
|
||||
" int a = 10; //局部变量存放在四区中的栈区\n",
|
||||
" return a;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"//2、函数的调用可以作为左值\n",
|
||||
"int& test02()\n",
|
||||
"{\n",
|
||||
" static int a = 10; //加上关键字static,变成静态变量,存放在全局区,全局区上的数据在程序结束后释放掉\n",
|
||||
" return a; //函数的返回值是a的一个引用\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" /*\n",
|
||||
" int& ref = test01();\n",
|
||||
" cout << \"ref = \" << ref << endl; //第一次结果正确,是因为编译器做了保留\n",
|
||||
" cout << \"ref = \" << ref << endl; //第一次结果正确,是因为栈区a的内存已经释放\n",
|
||||
" */\n",
|
||||
"\n",
|
||||
" \n",
|
||||
" int& ref = test02(); //由于返回的是a的引用,所以要用引用来接收,这里用ref来接收,ref为原名a的别名\n",
|
||||
" cout << \"ref = \" << ref << endl; \n",
|
||||
" cout << \"ref = \" << ref << endl; \n",
|
||||
" cout << \"ref = \" << ref << endl; \n",
|
||||
"\n",
|
||||
" test02() = 1000; //对a的引用进行操作,相当于原名a赋值赋值为1000\n",
|
||||
" cout << \"ref = \" << ref << endl; //通过原名a的别名ref访问1000\n",
|
||||
" cout << \"ref = \" << ref << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - ref = 10 \n",
|
||||
" - ref = 10 \n",
|
||||
" - ref = 10 \n",
|
||||
" - ref = 1000 \n",
|
||||
" - ref = 1000 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.5 引用本质"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 引用的本质在C++内部实现是一个指针常量。\n",
|
||||
"\n",
|
||||
"② C++推荐引用计数,因为语法方便,引用本质是指针常量,但是所有的指针操作编译器都帮我们做了。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//发现是引用,转换为 int* const ref = &a;\n",
|
||||
"void func(int& ref)\n",
|
||||
"{\n",
|
||||
" ref = 100; //ref是引用,转换为 * ref = 100;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" int a = 10;\n",
|
||||
"\n",
|
||||
" //自动转换为 int * const ref = &a; 指针常量是指针不可改,引用不可更改别名。\n",
|
||||
" //虽然指针常量指向的地址不可以更改,但是地址中的值可以更改。\n",
|
||||
" int& ref = a;\n",
|
||||
"\n",
|
||||
" ref = 20; //内部发现ref是引用,自动帮我们转换为 *ref = 20; 解引用找到相应的数据改为20\n",
|
||||
"\n",
|
||||
" cout << \"a:\" << a << endl;\n",
|
||||
" cout << \"ref:\" << ref << endl;\n",
|
||||
"\n",
|
||||
" func(a);\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - a:20 \n",
|
||||
" - ref:20 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.6 常量引用"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 作用:常量引用主要用来修饰形参,防止误操作。\n",
|
||||
"\n",
|
||||
"② 在函数形参列表中,可以加const修饰形参,防止形参改变实参。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"void showValue(const int& val)\n",
|
||||
"{\n",
|
||||
" // val = 1000; 报错,不能修改了\n",
|
||||
" cout << \"val = \" << val << endl;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //常量引用\n",
|
||||
" //使用场景:用来修饰形参,防止误操作\n",
|
||||
"\n",
|
||||
" /*\n",
|
||||
" int a = 10;\n",
|
||||
" int& ref = 10; //报错,引用必须引一块合法的内存空间\n",
|
||||
" */\n",
|
||||
"\n",
|
||||
" //加上const之后,编译器代码修改为 int temp = 10; const in & ref = temp \n",
|
||||
" const int& ref = 10;\n",
|
||||
" //ref = 20; //加入const之后变为只读,不可以修改\n",
|
||||
"\n",
|
||||
" int a = 100;\n",
|
||||
" showValue(a);\n",
|
||||
" cout << \"a = \" << a << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
" \n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - val = 100 \n",
|
||||
" - a = 100 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
303
docs/CPlusPlus-main/18_C++的引用.md
Normal file
@ -0,0 +1,303 @@
|
||||
# C++的引用
|
||||
|
||||
# 1. 引用
|
||||
|
||||
## 1.1 引用基本语法
|
||||
|
||||
① 作用:给变量起别名。
|
||||
|
||||
② 语法:数据类型 &别名 = 原名
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//引用基本语法
|
||||
//数据类型 &别名 = 原名
|
||||
|
||||
int a = 10;
|
||||
//创建引用
|
||||
int& b = a;
|
||||
|
||||
b = 100;
|
||||
|
||||
cout << "a= " << a << endl;
|
||||
cout << "b= " << a << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- a= 100
|
||||
- b= 100
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.2 引用注意事项
|
||||
|
||||
① 引用必须初始化。
|
||||
|
||||
② 引用在初始化后,不可以改变。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
//1、引用必须初始化
|
||||
int a = 10;
|
||||
int &b = a; // int &b; 是错误的,必须要初始化
|
||||
|
||||
//2、引用在初始化后,不可以改变
|
||||
int c = 20;
|
||||
b = c; // 赋值操作,而不是更改引用。把 c = 20 的数据20给了 b 指向的内存的数据,而 a、b 的指向的内存是一样的。
|
||||
// 这里并不是 b 指向 c 的内存。
|
||||
|
||||
cout << "a = " << a << endl; //a内存中数据变了
|
||||
cout << "b = " << b << endl;
|
||||
cout << "c = " << c << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- a = 20
|
||||
- b = 20
|
||||
- c = 20
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.3 引用做函数参数
|
||||
|
||||
① 函数传参时,可以利用引用的技术让形参修饰实参。
|
||||
|
||||
② 可以简化指针修改实参。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//1、值传递
|
||||
void mySwap01(int a,int b)
|
||||
{
|
||||
int temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
|
||||
//2、地址传递
|
||||
void mySwap02(int * a, int * b)
|
||||
{
|
||||
int temp = *a;
|
||||
*a = *b;
|
||||
*b = temp;
|
||||
}
|
||||
|
||||
//2、引用传递
|
||||
//这里面的&a的实参为a(恰巧为a,恰巧一样)的别名,对&a中的a操作修改,就是对实参a修改
|
||||
void mySwap03(int &a, int &b)
|
||||
{
|
||||
int temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
|
||||
mySwap01(a, b); //值传递,形参不会修饰实参
|
||||
|
||||
cout << "a = " << a << endl;
|
||||
cout << "b = " << b << endl;
|
||||
|
||||
mySwap02(&a, &b); //地址传递,形参会修饰实参
|
||||
|
||||
cout << "a = " << a << endl;
|
||||
cout << "b = " << b << endl;
|
||||
|
||||
mySwap03(a, b); //引用传递,形参会修饰实参
|
||||
|
||||
cout << "a = " << a << endl;
|
||||
cout << "b = " << b << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- a = 10
|
||||
- b = 20
|
||||
- a = 20
|
||||
- b = 10
|
||||
- a = 10
|
||||
- b = 20
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.4 引用做函数返回值
|
||||
|
||||
① 引用是可以作为函数的返回值存在的。
|
||||
|
||||
② 不要返回局部变量引用。
|
||||
|
||||
③ 函数调用可以作为左值。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//引用做函数的返回值
|
||||
//1、不要返回局部变量的引用
|
||||
int& test01()
|
||||
{
|
||||
int a = 10; //局部变量存放在四区中的栈区
|
||||
return a;
|
||||
}
|
||||
|
||||
//2、函数的调用可以作为左值
|
||||
int& test02()
|
||||
{
|
||||
static int a = 10; //加上关键字static,变成静态变量,存放在全局区,全局区上的数据在程序结束后释放掉
|
||||
return a; //函数的返回值是a的一个引用
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
/*
|
||||
int& ref = test01();
|
||||
cout << "ref = " << ref << endl; //第一次结果正确,是因为编译器做了保留
|
||||
cout << "ref = " << ref << endl; //第一次结果正确,是因为栈区a的内存已经释放
|
||||
*/
|
||||
|
||||
|
||||
int& ref = test02(); //由于返回的是a的引用,所以要用引用来接收,这里用ref来接收,ref为原名a的别名
|
||||
cout << "ref = " << ref << endl;
|
||||
cout << "ref = " << ref << endl;
|
||||
cout << "ref = " << ref << endl;
|
||||
|
||||
test02() = 1000; //对a的引用进行操作,相当于原名a赋值赋值为1000
|
||||
cout << "ref = " << ref << endl; //通过原名a的别名ref访问1000
|
||||
cout << "ref = " << ref << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- ref = 10
|
||||
- ref = 10
|
||||
- ref = 10
|
||||
- ref = 1000
|
||||
- ref = 1000
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.5 引用本质
|
||||
|
||||
① 引用的本质在C++内部实现是一个指针常量。
|
||||
|
||||
② C++推荐引用计数,因为语法方便,引用本质是指针常量,但是所有的指针操作编译器都帮我们做了。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//发现是引用,转换为 int* const ref = &a;
|
||||
void func(int& ref)
|
||||
{
|
||||
ref = 100; //ref是引用,转换为 * ref = 100;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int a = 10;
|
||||
|
||||
//自动转换为 int * const ref = &a; 指针常量是指针不可改,引用不可更改别名。
|
||||
//虽然指针常量指向的地址不可以更改,但是地址中的值可以更改。
|
||||
int& ref = a;
|
||||
|
||||
ref = 20; //内部发现ref是引用,自动帮我们转换为 *ref = 20; 解引用找到相应的数据改为20
|
||||
|
||||
cout << "a:" << a << endl;
|
||||
cout << "ref:" << ref << endl;
|
||||
|
||||
func(a);
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- a:20
|
||||
- ref:20
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.6 常量引用
|
||||
|
||||
① 作用:常量引用主要用来修饰形参,防止误操作。
|
||||
|
||||
② 在函数形参列表中,可以加const修饰形参,防止形参改变实参。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
void showValue(const int& val)
|
||||
{
|
||||
// val = 1000; 报错,不能修改了
|
||||
cout << "val = " << val << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
//常量引用
|
||||
//使用场景:用来修饰形参,防止误操作
|
||||
|
||||
/*
|
||||
int a = 10;
|
||||
int& ref = 10; //报错,引用必须引一块合法的内存空间
|
||||
*/
|
||||
|
||||
//加上const之后,编译器代码修改为 int temp = 10; const in & ref = temp
|
||||
const int& ref = 10;
|
||||
//ref = 20; //加入const之后变为只读,不可以修改
|
||||
|
||||
int a = 100;
|
||||
showValue(a);
|
||||
cout << "a = " << a << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- val = 100
|
||||
- a = 100
|
||||
- 请按任意键继续. . .
|
||||
67
docs/CPlusPlus-main/19_C++的面向对象.ipynb
Normal file
@ -0,0 +1,67 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的面向对象"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 面向对象三大特性"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① C++面向对象的三大特性为:封装、继承、多态。\n",
|
||||
"\n",
|
||||
"② C++认为万事万物皆为对象,对象上有其属性和行为。\n",
|
||||
"\n",
|
||||
"③ 例如:\n",
|
||||
"\n",
|
||||
"1. 人可以作为对象,属性有姓名、年龄、身高、体重......行为有走、跑、跳、吃饭、唱歌......\n",
|
||||
"2. 车也可以作为对象,属性有轮胎、方向盘、车灯......行为有载人、放音乐、放空调......\n",
|
||||
"3. 具有相同新值的对象,可以抽象为类,人属于人类,车属于车类。"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
13
docs/CPlusPlus-main/19_C++的面向对象.md
Normal file
@ -0,0 +1,13 @@
|
||||
# C++的面向对象
|
||||
|
||||
# 1. 面向对象三大特性
|
||||
|
||||
① C++面向对象的三大特性为:封装、继承、多态。
|
||||
|
||||
② C++认为万事万物皆为对象,对象上有其属性和行为。
|
||||
|
||||
③ 例如:
|
||||
|
||||
1. 人可以作为对象,属性有姓名、年龄、身高、体重......行为有走、跑、跳、吃饭、唱歌......
|
||||
2. 车也可以作为对象,属性有轮胎、方向盘、车灯......行为有载人、放音乐、放空调......
|
||||
3. 具有相同新值的对象,可以抽象为类,人属于人类,车属于车类。
|
||||
716
docs/CPlusPlus-main/20_C++的类中封装.ipynb
Normal file
@ -0,0 +1,716 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的封装"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 封装"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.1 封装属性和行为"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 封装是C++面向对象三大特性之一。\n",
|
||||
"\n",
|
||||
"② 封装的意义一:\n",
|
||||
"\n",
|
||||
"1. 将属性和行为作为一个整体,表现生活中的事物。\n",
|
||||
"2. 将属性和行为加以权限控制。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"const double PI = 3.14;\n",
|
||||
"\n",
|
||||
"//设计一个圆类,求圆的周长\n",
|
||||
"//圆求周长的公式: 2 * PI * 半径\n",
|
||||
"\n",
|
||||
"//class 代表设计一个类,类后面紧跟着的就是类名称\n",
|
||||
"class Circle\n",
|
||||
"{\n",
|
||||
" //访问权限\n",
|
||||
" //公共权限\n",
|
||||
" public: //是冒号,不是分号\n",
|
||||
"\n",
|
||||
" //属性\n",
|
||||
" //半径\n",
|
||||
" int m_r;\n",
|
||||
"\n",
|
||||
" //行为\n",
|
||||
" //获取圆的周长\n",
|
||||
" double calculateZC()\n",
|
||||
" {\n",
|
||||
" return 2 * PI * m_r;\n",
|
||||
" }\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //通过圆类 创建具体的圆(对象)\n",
|
||||
" //实例化 (通过一个类 创建一个对象的过程)\n",
|
||||
" Circle c1;\n",
|
||||
" //给圆对象 的属性进行赋值\n",
|
||||
" c1.m_r = 10;\n",
|
||||
"\n",
|
||||
" // 2 * PI * 10 = 62.8\n",
|
||||
" cout << \"圆的周长为:\" << c1.calculateZC() << endl;\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
" \n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 圆的周长为:62.8"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.2 封装权限"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 类在设计时,可以把属性和行为放在不同的权限下,加以控制。\n",
|
||||
"\n",
|
||||
"② 封装的意义二:\n",
|
||||
"\n",
|
||||
"1. public 公共权限\n",
|
||||
"2. protected 保护权限\n",
|
||||
"3. private 私有权限"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//访问权限\n",
|
||||
"//三种\n",
|
||||
"//公共权限 public 类内可以访问成员 类外可以访问成员\n",
|
||||
"//保护权限 protected 类内可以访问成员 类外不可以访问成员 子类可以访问父类中的保护内容\n",
|
||||
"//私有权限 private 类内可以访问权限 类外不可以访问成员 子类不可以访问父类中的私有内容\n",
|
||||
"\n",
|
||||
"class Person\n",
|
||||
"{\n",
|
||||
"//公共权限\n",
|
||||
"public: \n",
|
||||
" string m_Name; //姓名\n",
|
||||
"\n",
|
||||
"protected:\n",
|
||||
" string m_Car; //汽车\n",
|
||||
"\n",
|
||||
"private:\n",
|
||||
" int m_Password; //银行卡密码\n",
|
||||
"\n",
|
||||
"public:\n",
|
||||
" void func()\n",
|
||||
" {\n",
|
||||
" m_Name = \"李四\";\n",
|
||||
" m_Car = \"奔驰\"; //保护权限内容,在类外访问不到\n",
|
||||
" m_Password = 123;\n",
|
||||
" }\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //实例化具体对象\n",
|
||||
" Person p1;\n",
|
||||
" p1.m_Name = \"李四\";\n",
|
||||
" p1.m_Car = \"奔驰\"; //保护权限内容,在类外访问不到\n",
|
||||
" p1.m_Password = 123; //私有权限内容,在类外访问不到\n",
|
||||
"\n",
|
||||
" p1.func(); //公共权限内容,在类可以访问\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.3 struct 和 class 区别"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 在C++中struct和class唯一的区别就在于默认的访问权限不同。\n",
|
||||
"\n",
|
||||
"② 区别:\n",
|
||||
"\n",
|
||||
"1. struct 默认权限为公共。\n",
|
||||
"2. class 默认权限为私有。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//访问权限\n",
|
||||
"//三种\n",
|
||||
"//公共权限 public 类内可以访问成员 类外可以访问成员\n",
|
||||
"//保护权限 protected 类内可以访问成员 类外不可以访问成员 子类可以访问父类中的保护内容\n",
|
||||
"//私有权限 private 类内可以访问权限 类外不可以访问成员 子类不可以访问父类中的私有内容\n",
|
||||
"\n",
|
||||
"class C1\n",
|
||||
"{\n",
|
||||
" int m_A; // 默认权限是私有\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"struct C2\n",
|
||||
"{\n",
|
||||
" int m_A; //默认权限 是公共\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //struct 和 class 区别\n",
|
||||
" //struct 默认权限是 公共 public\n",
|
||||
" //class 默认权限是 私有 private\n",
|
||||
" C1 c1;\n",
|
||||
" c1.m_A = 100; //私有权限,不能访问\n",
|
||||
"\n",
|
||||
" C2 c2;\n",
|
||||
" c2.m_A = 100; //公共权限,可以访问\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
" \n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.4 成员属性设置为私有"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 优点1:将所有成员属性设置为私有,可以自己控制读写权限。\n",
|
||||
"\n",
|
||||
"② 优点2:可以通过写权限,检测数据的有效性。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include <string>\n",
|
||||
"\n",
|
||||
"//成员属性设置为私有\n",
|
||||
"//1、可以自己控制读写权限\n",
|
||||
"//2、对于写可以检测数据的有效性\n",
|
||||
"\n",
|
||||
"class Person\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" //设置姓名\n",
|
||||
" void setName(string name)\n",
|
||||
" {\n",
|
||||
" m_Name = name;\n",
|
||||
" }\n",
|
||||
" //获取姓名\n",
|
||||
" string getName()\n",
|
||||
" {\n",
|
||||
" return m_Name;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //获取年龄\n",
|
||||
" int getAge()\n",
|
||||
" {\n",
|
||||
" m_Age = 0; //初始化为0岁\n",
|
||||
" return m_Age;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" void setLover(string lover)\n",
|
||||
" {\n",
|
||||
" m_Lover = lover;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"private:\n",
|
||||
" //姓名 可读可写\n",
|
||||
" string m_Name;\n",
|
||||
" //年龄 只读\n",
|
||||
" int m_Age;\n",
|
||||
" //情人 只写\n",
|
||||
" string m_Lover;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" Person p;\n",
|
||||
" p.setName(\"张三\");\n",
|
||||
"\n",
|
||||
" cout << \"姓名为:\" << p.getName() << endl;\n",
|
||||
"\n",
|
||||
" cout << \"年龄为:\" << p.getName() << endl;\n",
|
||||
"\n",
|
||||
" //p.m_Age = 18; //私有权限,不可以改\n",
|
||||
" p.getAge();\n",
|
||||
" cout << \"姓名为:\" << p.getAge() << endl;\n",
|
||||
"\n",
|
||||
" p.setLover(\"小李\");\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 姓名为:张三 \n",
|
||||
" - 年龄为:0 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include <string>\n",
|
||||
"\n",
|
||||
"//成员属性设置为私有\n",
|
||||
"//1、可以自己控制读写权限\n",
|
||||
"//2、对于写可以检测数据的有效性\n",
|
||||
"\n",
|
||||
"class Person\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" //设置姓名\n",
|
||||
" void setName(string name)\n",
|
||||
" {\n",
|
||||
" m_Name = name;\n",
|
||||
" }\n",
|
||||
" //获取姓名\n",
|
||||
" string getName()\n",
|
||||
" {\n",
|
||||
" return m_Name;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //获取年龄 可读可写 \n",
|
||||
" int getAge()\n",
|
||||
" {\n",
|
||||
" return m_Age;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //设置年龄 如果想修改(年龄的范围必须是0~150之间)\n",
|
||||
" void setAge(int age)\n",
|
||||
" {\n",
|
||||
" if (age < 0 || age>150)\n",
|
||||
" {\n",
|
||||
" m_Age = 0; //强制改为0\n",
|
||||
" cout << \"你这个老妖精!\" << endl;\n",
|
||||
" return; //强制退出\n",
|
||||
" }\n",
|
||||
" m_Age = age;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" void setLover(string lover)\n",
|
||||
" {\n",
|
||||
" m_Lover = lover;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"private:\n",
|
||||
" //姓名 可读可写\n",
|
||||
" string m_Name;\n",
|
||||
" //年龄 只读\n",
|
||||
" int m_Age;\n",
|
||||
" //情人 只写\n",
|
||||
" string m_Lover;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" Person p;\n",
|
||||
" p.setName(\"张三\");\n",
|
||||
"\n",
|
||||
" cout << \"姓名为:\" << p.getName() << endl;\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" //p.m_Age = 18; //私有权限,不可以类外改\n",
|
||||
" p.setAge(1000); \n",
|
||||
" cout << \"年龄为:\" << p.getAge() << endl;\n",
|
||||
"\n",
|
||||
" //设置情人为苍井女士\n",
|
||||
" p.setLover(\"小李\"); //有这个函数可以设置\n",
|
||||
" //cout << \"情人为:\" << p.getLover() << endl; //没有这个函数,不能获得\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 姓名为:张三 \n",
|
||||
" - 你这个老妖精! \n",
|
||||
" - 年龄为:0 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.5 设计学生类"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"案例描述:设计一个学生类,属性有姓名和学号,可以给姓名和学号赋值,可以显示学生的姓名和学号。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include<string>\n",
|
||||
"\n",
|
||||
"//设计学生类\n",
|
||||
"class Student\n",
|
||||
"{\n",
|
||||
"public: //公共权限\n",
|
||||
"\n",
|
||||
" //类中的属性和行为 我们统一称为成员\n",
|
||||
" // 属性 成员属性 成员变量\n",
|
||||
" // 行为 成员函数 成员方法\n",
|
||||
" \n",
|
||||
" //属性\n",
|
||||
" string m_Name; //姓名\n",
|
||||
" int m_Id; //学号\n",
|
||||
"\n",
|
||||
" //行为\n",
|
||||
" //显示姓名和学号\n",
|
||||
" void showStudent()\n",
|
||||
" {\n",
|
||||
" cout << \"姓名:\" << m_Name << \" 学号:\" << m_Id << endl;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //给姓名赋值的行为\n",
|
||||
" void setName(string name)\n",
|
||||
" {\n",
|
||||
" m_Name = name;\n",
|
||||
" }\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //创建一个具体学生 实例化对象\n",
|
||||
" Student s1;\n",
|
||||
" //给s1对象 进行属性赋值操作\n",
|
||||
" s1.m_Name = \"张三\";\n",
|
||||
" s1.m_Id = 1;\n",
|
||||
"\n",
|
||||
" s1.showStudent();\n",
|
||||
"\n",
|
||||
" Student s2;\n",
|
||||
" s2.m_Name = \"李四\";\n",
|
||||
" s2.m_Id = 2;\n",
|
||||
" s2.showStudent();\n",
|
||||
"\n",
|
||||
" Student s3;\n",
|
||||
" s3.setName(\"王五\");\n",
|
||||
" s3.m_Id = 3;\n",
|
||||
" s3.showStudent();\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 姓名:张三 学号:1 \n",
|
||||
" - 姓名:李四 学号:2 \n",
|
||||
" - 姓名:王五 学号:3 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1.6 设计立方体类"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"案例描述:设计立方体类(Cube),求出立方体的面积和体积,分别用全局函数和成员函数判断两个立方体是否相等。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//立方体类设计\n",
|
||||
"//1、创建立方体类\n",
|
||||
"//2、设计属性\n",
|
||||
"//3、获取立方体面积和体积\n",
|
||||
"//4、分别利用全局函数和成员函数 判断两个立方体是否相等\n",
|
||||
"\n",
|
||||
"class Cube\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" //设置长\n",
|
||||
" void setL(int l)\n",
|
||||
" {\n",
|
||||
" m_L = l;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //获取长\n",
|
||||
" int getL()\n",
|
||||
" {\n",
|
||||
" return m_L;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //设置宽\n",
|
||||
" void setW(int w)\n",
|
||||
" {\n",
|
||||
" m_W = w;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //获取宽\n",
|
||||
" int getW()\n",
|
||||
" {\n",
|
||||
" return m_W;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //设置高\n",
|
||||
" void setH(int h)\n",
|
||||
" {\n",
|
||||
" m_H = h;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //获取高\n",
|
||||
" int getH()\n",
|
||||
" {\n",
|
||||
" return m_H;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //获取立方体面积\n",
|
||||
" int calculateS()\n",
|
||||
" {\n",
|
||||
" return 2 * m_L * m_W + 2 * m_W * m_H + 2 * m_L * m_H;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //获取立方体体积\n",
|
||||
" int calculateV()\n",
|
||||
" {\n",
|
||||
" return m_L * m_W * m_H;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //利用成员函数判断两个立方体是否相等\n",
|
||||
" bool isSameByClass(Cube c) //成员函数只需要传入一个类为参数\n",
|
||||
" {\n",
|
||||
" if (m_L == c.getL() && m_W == c.getW() && m_H == c.getH()) //类内可以访问成员函数:m_L、m_W、m_H\n",
|
||||
" {\n",
|
||||
" return true;\n",
|
||||
" }\n",
|
||||
" else\n",
|
||||
" {\n",
|
||||
" return false;\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"private:\n",
|
||||
" int m_L; //长\n",
|
||||
" int m_W; //宽\n",
|
||||
" int m_H; //高\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"//利用全局函数判断,两个立方体是否相等\n",
|
||||
"bool isSame(Cube c1, Cube c2) //值传递会拷贝一份数据,通过引用传递用原始数据,不会拷贝数据\n",
|
||||
"{\n",
|
||||
" if (c1.getL() == c2.getL() && c1.getW() == c2.getW()\n",
|
||||
" && c1.getH() == c2.getH())\n",
|
||||
" {\n",
|
||||
" return true;\n",
|
||||
" }\n",
|
||||
" else\n",
|
||||
" {\n",
|
||||
" return false;\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //创建立方体对象\n",
|
||||
" Cube c1;\n",
|
||||
" c1.setL(10);\n",
|
||||
" c1.setW(10);\n",
|
||||
" c1.setH(10);\n",
|
||||
"\n",
|
||||
" cout << \"c1的面积为:\" << c1.calculateS() << endl; \n",
|
||||
" cout << \"c1的体积为:\" << c1.calculateV() << endl; \n",
|
||||
"\n",
|
||||
" Cube c2;\n",
|
||||
" c2.setL(10);\n",
|
||||
" c2.setW(10);\n",
|
||||
" c2.setH(11);\n",
|
||||
"\n",
|
||||
" bool ret = isSame(c1, c2);\n",
|
||||
" if (ret)\n",
|
||||
" {\n",
|
||||
" cout << \"利用全局函数判断:c1和c2是相等的\" << endl;\n",
|
||||
" }\n",
|
||||
" else\n",
|
||||
" {\n",
|
||||
" cout << \"利用全局函数判断:c1和c2是不相等的\" << endl;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" //利用成员函数判断\n",
|
||||
" ret = c1.isSameByClass(c2);\n",
|
||||
" if (ret)\n",
|
||||
" {\n",
|
||||
" cout << \"利用成员函数判断:c1和c2是相等的\" << endl;\n",
|
||||
" }\n",
|
||||
" else\n",
|
||||
" {\n",
|
||||
" cout << \"利用成员函数判断:c1和c2是不相等的\" << endl;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - c1的面积为:600 \n",
|
||||
" - c1的体积为:1000 \n",
|
||||
" - 利用全局函数判断:c1和c2是不相等的 \n",
|
||||
" - 利用成员函数判断:c1和c2是不相等的 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
554
docs/CPlusPlus-main/20_C++的类中封装.md
Normal file
@ -0,0 +1,554 @@
|
||||
# C++的封装
|
||||
|
||||
# 1. 封装
|
||||
|
||||
## 1.1 封装属性和行为
|
||||
|
||||
① 封装是C++面向对象三大特性之一。
|
||||
|
||||
② 封装的意义一:
|
||||
|
||||
1. 将属性和行为作为一个整体,表现生活中的事物。
|
||||
2. 将属性和行为加以权限控制。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
const double PI = 3.14;
|
||||
|
||||
//设计一个圆类,求圆的周长
|
||||
//圆求周长的公式: 2 * PI * 半径
|
||||
|
||||
//class 代表设计一个类,类后面紧跟着的就是类名称
|
||||
class Circle
|
||||
{
|
||||
//访问权限
|
||||
//公共权限
|
||||
public: //是冒号,不是分号
|
||||
|
||||
//属性
|
||||
//半径
|
||||
int m_r;
|
||||
|
||||
//行为
|
||||
//获取圆的周长
|
||||
double calculateZC()
|
||||
{
|
||||
return 2 * PI * m_r;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
//通过圆类 创建具体的圆(对象)
|
||||
//实例化 (通过一个类 创建一个对象的过程)
|
||||
Circle c1;
|
||||
//给圆对象 的属性进行赋值
|
||||
c1.m_r = 10;
|
||||
|
||||
// 2 * PI * 10 = 62.8
|
||||
cout << "圆的周长为:" << c1.calculateZC() << endl;
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 圆的周长为:62.8
|
||||
|
||||
## 1.2 封装权限
|
||||
|
||||
① 类在设计时,可以把属性和行为放在不同的权限下,加以控制。
|
||||
|
||||
② 封装的意义二:
|
||||
|
||||
1. public 公共权限
|
||||
2. protected 保护权限
|
||||
3. private 私有权限
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//访问权限
|
||||
//三种
|
||||
//公共权限 public 类内可以访问成员 类外可以访问成员
|
||||
//保护权限 protected 类内可以访问成员 类外不可以访问成员 子类可以访问父类中的保护内容
|
||||
//私有权限 private 类内可以访问权限 类外不可以访问成员 子类不可以访问父类中的私有内容
|
||||
|
||||
class Person
|
||||
{
|
||||
//公共权限
|
||||
public:
|
||||
string m_Name; //姓名
|
||||
|
||||
protected:
|
||||
string m_Car; //汽车
|
||||
|
||||
private:
|
||||
int m_Password; //银行卡密码
|
||||
|
||||
public:
|
||||
void func()
|
||||
{
|
||||
m_Name = "李四";
|
||||
m_Car = "奔驰"; //保护权限内容,在类外访问不到
|
||||
m_Password = 123;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
//实例化具体对象
|
||||
Person p1;
|
||||
p1.m_Name = "李四";
|
||||
p1.m_Car = "奔驰"; //保护权限内容,在类外访问不到
|
||||
p1.m_Password = 123; //私有权限内容,在类外访问不到
|
||||
|
||||
p1.func(); //公共权限内容,在类可以访问
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## 1.3 struct 和 class 区别
|
||||
|
||||
① 在C++中struct和class唯一的区别就在于默认的访问权限不同。
|
||||
|
||||
② 区别:
|
||||
|
||||
1. struct 默认权限为公共。
|
||||
2. class 默认权限为私有。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//访问权限
|
||||
//三种
|
||||
//公共权限 public 类内可以访问成员 类外可以访问成员
|
||||
//保护权限 protected 类内可以访问成员 类外不可以访问成员 子类可以访问父类中的保护内容
|
||||
//私有权限 private 类内可以访问权限 类外不可以访问成员 子类不可以访问父类中的私有内容
|
||||
|
||||
class C1
|
||||
{
|
||||
int m_A; // 默认权限是私有
|
||||
};
|
||||
|
||||
struct C2
|
||||
{
|
||||
int m_A; //默认权限 是公共
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
//struct 和 class 区别
|
||||
//struct 默认权限是 公共 public
|
||||
//class 默认权限是 私有 private
|
||||
C1 c1;
|
||||
c1.m_A = 100; //私有权限,不能访问
|
||||
|
||||
C2 c2;
|
||||
c2.m_A = 100; //公共权限,可以访问
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## 1.4 成员属性设置为私有
|
||||
|
||||
① 优点1:将所有成员属性设置为私有,可以自己控制读写权限。
|
||||
|
||||
② 优点2:可以通过写权限,检测数据的有效性。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string>
|
||||
|
||||
//成员属性设置为私有
|
||||
//1、可以自己控制读写权限
|
||||
//2、对于写可以检测数据的有效性
|
||||
|
||||
class Person
|
||||
{
|
||||
public:
|
||||
//设置姓名
|
||||
void setName(string name)
|
||||
{
|
||||
m_Name = name;
|
||||
}
|
||||
//获取姓名
|
||||
string getName()
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
|
||||
//获取年龄
|
||||
int getAge()
|
||||
{
|
||||
m_Age = 0; //初始化为0岁
|
||||
return m_Age;
|
||||
}
|
||||
|
||||
void setLover(string lover)
|
||||
{
|
||||
m_Lover = lover;
|
||||
}
|
||||
|
||||
private:
|
||||
//姓名 可读可写
|
||||
string m_Name;
|
||||
//年龄 只读
|
||||
int m_Age;
|
||||
//情人 只写
|
||||
string m_Lover;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Person p;
|
||||
p.setName("张三");
|
||||
|
||||
cout << "姓名为:" << p.getName() << endl;
|
||||
|
||||
cout << "年龄为:" << p.getName() << endl;
|
||||
|
||||
//p.m_Age = 18; //私有权限,不可以改
|
||||
p.getAge();
|
||||
cout << "姓名为:" << p.getAge() << endl;
|
||||
|
||||
p.setLover("小李");
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 姓名为:张三
|
||||
- 年龄为:0
|
||||
- 请按任意键继续. . .
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string>
|
||||
|
||||
//成员属性设置为私有
|
||||
//1、可以自己控制读写权限
|
||||
//2、对于写可以检测数据的有效性
|
||||
|
||||
class Person
|
||||
{
|
||||
public:
|
||||
//设置姓名
|
||||
void setName(string name)
|
||||
{
|
||||
m_Name = name;
|
||||
}
|
||||
//获取姓名
|
||||
string getName()
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
|
||||
//获取年龄 可读可写
|
||||
int getAge()
|
||||
{
|
||||
return m_Age;
|
||||
}
|
||||
|
||||
//设置年龄 如果想修改(年龄的范围必须是0~150之间)
|
||||
void setAge(int age)
|
||||
{
|
||||
if (age < 0 || age>150)
|
||||
{
|
||||
m_Age = 0; //强制改为0
|
||||
cout << "你这个老妖精!" << endl;
|
||||
return; //强制退出
|
||||
}
|
||||
m_Age = age;
|
||||
}
|
||||
|
||||
void setLover(string lover)
|
||||
{
|
||||
m_Lover = lover;
|
||||
}
|
||||
|
||||
private:
|
||||
//姓名 可读可写
|
||||
string m_Name;
|
||||
//年龄 只读
|
||||
int m_Age;
|
||||
//情人 只写
|
||||
string m_Lover;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Person p;
|
||||
p.setName("张三");
|
||||
|
||||
cout << "姓名为:" << p.getName() << endl;
|
||||
|
||||
|
||||
//p.m_Age = 18; //私有权限,不可以类外改
|
||||
p.setAge(1000);
|
||||
cout << "年龄为:" << p.getAge() << endl;
|
||||
|
||||
//设置情人为苍井女士
|
||||
p.setLover("小李"); //有这个函数可以设置
|
||||
//cout << "情人为:" << p.getLover() << endl; //没有这个函数,不能获得
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 姓名为:张三
|
||||
- 你这个老妖精!
|
||||
- 年龄为:0
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.5 设计学生类
|
||||
|
||||
案例描述:设计一个学生类,属性有姓名和学号,可以给姓名和学号赋值,可以显示学生的姓名和学号。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<string>
|
||||
|
||||
//设计学生类
|
||||
class Student
|
||||
{
|
||||
public: //公共权限
|
||||
|
||||
//类中的属性和行为 我们统一称为成员
|
||||
// 属性 成员属性 成员变量
|
||||
// 行为 成员函数 成员方法
|
||||
|
||||
//属性
|
||||
string m_Name; //姓名
|
||||
int m_Id; //学号
|
||||
|
||||
//行为
|
||||
//显示姓名和学号
|
||||
void showStudent()
|
||||
{
|
||||
cout << "姓名:" << m_Name << " 学号:" << m_Id << endl;
|
||||
}
|
||||
|
||||
//给姓名赋值的行为
|
||||
void setName(string name)
|
||||
{
|
||||
m_Name = name;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
//创建一个具体学生 实例化对象
|
||||
Student s1;
|
||||
//给s1对象 进行属性赋值操作
|
||||
s1.m_Name = "张三";
|
||||
s1.m_Id = 1;
|
||||
|
||||
s1.showStudent();
|
||||
|
||||
Student s2;
|
||||
s2.m_Name = "李四";
|
||||
s2.m_Id = 2;
|
||||
s2.showStudent();
|
||||
|
||||
Student s3;
|
||||
s3.setName("王五");
|
||||
s3.m_Id = 3;
|
||||
s3.showStudent();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 姓名:张三 学号:1
|
||||
- 姓名:李四 学号:2
|
||||
- 姓名:王五 学号:3
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.6 设计立方体类
|
||||
|
||||
案例描述:设计立方体类(Cube),求出立方体的面积和体积,分别用全局函数和成员函数判断两个立方体是否相等。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//立方体类设计
|
||||
//1、创建立方体类
|
||||
//2、设计属性
|
||||
//3、获取立方体面积和体积
|
||||
//4、分别利用全局函数和成员函数 判断两个立方体是否相等
|
||||
|
||||
class Cube
|
||||
{
|
||||
public:
|
||||
//设置长
|
||||
void setL(int l)
|
||||
{
|
||||
m_L = l;
|
||||
}
|
||||
|
||||
//获取长
|
||||
int getL()
|
||||
{
|
||||
return m_L;
|
||||
}
|
||||
|
||||
//设置宽
|
||||
void setW(int w)
|
||||
{
|
||||
m_W = w;
|
||||
}
|
||||
|
||||
//获取宽
|
||||
int getW()
|
||||
{
|
||||
return m_W;
|
||||
}
|
||||
|
||||
//设置高
|
||||
void setH(int h)
|
||||
{
|
||||
m_H = h;
|
||||
}
|
||||
|
||||
//获取高
|
||||
int getH()
|
||||
{
|
||||
return m_H;
|
||||
}
|
||||
|
||||
//获取立方体面积
|
||||
int calculateS()
|
||||
{
|
||||
return 2 * m_L * m_W + 2 * m_W * m_H + 2 * m_L * m_H;
|
||||
}
|
||||
|
||||
//获取立方体体积
|
||||
int calculateV()
|
||||
{
|
||||
return m_L * m_W * m_H;
|
||||
}
|
||||
|
||||
//利用成员函数判断两个立方体是否相等
|
||||
bool isSameByClass(Cube c) //成员函数只需要传入一个类为参数
|
||||
{
|
||||
if (m_L == c.getL() && m_W == c.getW() && m_H == c.getH()) //类内可以访问成员函数:m_L、m_W、m_H
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
int m_L; //长
|
||||
int m_W; //宽
|
||||
int m_H; //高
|
||||
};
|
||||
|
||||
//利用全局函数判断,两个立方体是否相等
|
||||
bool isSame(Cube c1, Cube c2) //值传递会拷贝一份数据,通过引用传递用原始数据,不会拷贝数据
|
||||
{
|
||||
if (c1.getL() == c2.getL() && c1.getW() == c2.getW()
|
||||
&& c1.getH() == c2.getH())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
//创建立方体对象
|
||||
Cube c1;
|
||||
c1.setL(10);
|
||||
c1.setW(10);
|
||||
c1.setH(10);
|
||||
|
||||
cout << "c1的面积为:" << c1.calculateS() << endl;
|
||||
cout << "c1的体积为:" << c1.calculateV() << endl;
|
||||
|
||||
Cube c2;
|
||||
c2.setL(10);
|
||||
c2.setW(10);
|
||||
c2.setH(11);
|
||||
|
||||
bool ret = isSame(c1, c2);
|
||||
if (ret)
|
||||
{
|
||||
cout << "利用全局函数判断:c1和c2是相等的" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "利用全局函数判断:c1和c2是不相等的" << endl;
|
||||
}
|
||||
|
||||
|
||||
//利用成员函数判断
|
||||
ret = c1.isSameByClass(c2);
|
||||
if (ret)
|
||||
{
|
||||
cout << "利用成员函数判断:c1和c2是相等的" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "利用成员函数判断:c1和c2是不相等的" << endl;
|
||||
}
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- c1的面积为:600
|
||||
- c1的体积为:1000
|
||||
- 利用全局函数判断:c1和c2是不相等的
|
||||
- 利用成员函数判断:c1和c2是不相等的
|
||||
- 请按任意键继续. . .
|
||||
426
docs/CPlusPlus-main/21_C++的调用其他类.ipynb
Normal file
@ -0,0 +1,426 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的调用其他类"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 类中有其他的类"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//点和圆关系案例\n",
|
||||
"\n",
|
||||
"//点类\n",
|
||||
"class Point\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" //设置x\n",
|
||||
" void setX(int x)\n",
|
||||
" {\n",
|
||||
" m_X = x;\n",
|
||||
" }\n",
|
||||
" //获取x\n",
|
||||
" int getX()\n",
|
||||
" {\n",
|
||||
" return m_X;\n",
|
||||
" }\n",
|
||||
" //设置y\n",
|
||||
" void setY(int y)\n",
|
||||
" {\n",
|
||||
" m_Y = y;\n",
|
||||
" }\n",
|
||||
" //获取y\n",
|
||||
" int getY()\n",
|
||||
" {\n",
|
||||
" return m_Y;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"private:\n",
|
||||
" int m_X;\n",
|
||||
" int m_Y;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"//圆类\n",
|
||||
"class Circle\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" //设置半径\n",
|
||||
" void setR(int r)\n",
|
||||
" {\n",
|
||||
" m_R = r;\n",
|
||||
" }\n",
|
||||
" //获取半径\n",
|
||||
" int getR()\n",
|
||||
" {\n",
|
||||
" return m_R;\n",
|
||||
" }\n",
|
||||
" //设置圆心\n",
|
||||
" void setCenter(Point center)\n",
|
||||
" {\n",
|
||||
" m_Center = center;\n",
|
||||
" }\n",
|
||||
" //获取圆心\n",
|
||||
" Point getCenter()\n",
|
||||
" {\n",
|
||||
" return m_Center;\n",
|
||||
" }\n",
|
||||
"private:\n",
|
||||
" int m_R; //半径\n",
|
||||
" Point m_Center; //圆心 //在类中可以让另一个类 作为本类中的成员\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"//判断点和圆关系\n",
|
||||
"void isInCircle(Circle& c, Point& p)\n",
|
||||
"{\n",
|
||||
" //计算两点之间距离 平方\n",
|
||||
" int distance =\n",
|
||||
" (c.getCenter().getX() - p.getX()) * (c.getCenter().getX() - p.getX()) +\n",
|
||||
" (c.getCenter().getY() - p.getY()) * (c.getCenter().getY() - p.getY()); //c.getCenter()返回的是圆心点center类\n",
|
||||
" //可以调用圆心点center类中的方法\n",
|
||||
"\n",
|
||||
" //计算半径的平方\n",
|
||||
" int rDistance = c.getR() * c.getR();\n",
|
||||
"\n",
|
||||
" //判断关系\n",
|
||||
" if (distance == rDistance)\n",
|
||||
" {\n",
|
||||
" cout << \"点在圆上\" << endl;\n",
|
||||
" }\n",
|
||||
" else if (distance > rDistance)\n",
|
||||
" {\n",
|
||||
" cout << \"点在圆外\" << endl;\n",
|
||||
" }\n",
|
||||
" else\n",
|
||||
" {\n",
|
||||
" cout << \"点在圆内\" << endl;\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //创建圆\n",
|
||||
" Circle c;\n",
|
||||
" c.setR(10);\n",
|
||||
" Point center;\n",
|
||||
" center.setX(10); //设置点的横坐标\n",
|
||||
" center.setY(0); //设置点的纵坐标\n",
|
||||
" c.setCenter(center); //设置点类传入圆类\n",
|
||||
"\n",
|
||||
" //创建点\n",
|
||||
" Point p;\n",
|
||||
" p.setX(10);\n",
|
||||
" p.setY(10);\n",
|
||||
"\n",
|
||||
" //判断关系\n",
|
||||
" isInCircle(c, p);\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 点在圆上 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 2. 导入其他文件的类"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2.1 point.h头文件"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"//这是point.h头文件\n",
|
||||
"\n",
|
||||
"#pragma once //防止头文件重复包含,防止头文件冲突\n",
|
||||
"#include <iostream> //标准输入输出\n",
|
||||
"using namespace std; //标准命名空间\n",
|
||||
"\n",
|
||||
"//只要函数声明、变量声明\n",
|
||||
"//成员函数只需要声明就好了,末尾有分号。\n",
|
||||
"class Point\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" //设置x\n",
|
||||
" void setX(int x);\n",
|
||||
"\n",
|
||||
" //获取x\n",
|
||||
" int getX();\n",
|
||||
"\n",
|
||||
" //设置y\n",
|
||||
" void setY(int y);\n",
|
||||
"\n",
|
||||
" //获取y\n",
|
||||
" int getY();\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"private:\n",
|
||||
" int m_X;\n",
|
||||
" int m_Y;\n",
|
||||
"};"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2.2 point.cpp源文件"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"//这是point.cpp源文件\n",
|
||||
"#include \"point.h\"\n",
|
||||
"\n",
|
||||
"//定义函数时,要加上作用域,\"双冒号::\"表示Point作用域下的函数\n",
|
||||
"void Point::setX(int x)\n",
|
||||
"{\n",
|
||||
" m_X = x;\n",
|
||||
"}\n",
|
||||
"//获取x\n",
|
||||
"int Point::getX()\n",
|
||||
"{\n",
|
||||
" return m_X;\n",
|
||||
"}\n",
|
||||
"//设置y\n",
|
||||
"void Point::setY(int y)\n",
|
||||
"{\n",
|
||||
" m_Y = y;\n",
|
||||
"}\n",
|
||||
"//获取y\n",
|
||||
"int Point::getY()\n",
|
||||
"{\n",
|
||||
" return m_Y;\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2.3 circle.h头文件"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#pragma once \n",
|
||||
"#include <iostream> //标准输出流\n",
|
||||
"using namespace std; //标准命名空间\n",
|
||||
"#include \"Point.h\" //一个类中用到另一个类,把另一个类包含的头文件包含进来\n",
|
||||
"\n",
|
||||
"//圆类\n",
|
||||
"class Circle\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" //设置半径\n",
|
||||
" void setR(int r);\n",
|
||||
"\n",
|
||||
" //获取半径\n",
|
||||
" int getR();\n",
|
||||
"\n",
|
||||
" //设置圆心\n",
|
||||
" void setCenter(Point center);\n",
|
||||
"\n",
|
||||
" //获取圆心\n",
|
||||
" Point getCenter();\n",
|
||||
"\n",
|
||||
"private:\n",
|
||||
" int m_R; //半径\n",
|
||||
" Point m_Center; //圆心 //在类中可以让另一个类 作为本类中的成员\n",
|
||||
"};"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2.4 circle.cpp头文件"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"//这是circle.cpp头文件\n",
|
||||
"\n",
|
||||
"#include \"circle.h\"\n",
|
||||
"\n",
|
||||
"//设置半径\n",
|
||||
"void Circle::setR(int r)\n",
|
||||
"{\n",
|
||||
" m_R = r;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"//获取半径\n",
|
||||
"int Circle::getR()\n",
|
||||
"{\n",
|
||||
" return m_R;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"//设置圆心\n",
|
||||
"void Circle::setCenter(Point center)\n",
|
||||
"{\n",
|
||||
" m_Center = center;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"//获取圆心\n",
|
||||
"Point Circle::getCenter()\n",
|
||||
"{\n",
|
||||
" return m_Center;\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2.5 main.cpp文件"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"//这个是主文件 .cpp文件\n",
|
||||
"\n",
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include \"circle.h\" //想用点类,就要包含点类的头文件\n",
|
||||
"#include \"point.h\" //想用圆类,就要包含点类的头文件\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"//判断点和圆关系\n",
|
||||
"void isInCircle(Circle& c, Point& p)\n",
|
||||
"{\n",
|
||||
" //计算两点之间距离 平方\n",
|
||||
" int distance =\n",
|
||||
" (c.getCenter().getX() - p.getX()) * (c.getCenter().getX() - p.getX()) +\n",
|
||||
" (c.getCenter().getY() - p.getY()) * (c.getCenter().getY() - p.getY()); //c.getCenter()返回的是圆心点center类\n",
|
||||
" //可以调用圆心点center类中的方法\n",
|
||||
"\n",
|
||||
" //计算半径的平方\n",
|
||||
" int rDistance = c.getR() * c.getR();\n",
|
||||
"\n",
|
||||
" //判断关系\n",
|
||||
" if (distance == rDistance)\n",
|
||||
" {\n",
|
||||
" cout << \"点在圆上\" << endl;\n",
|
||||
" }\n",
|
||||
" else if (distance > rDistance)\n",
|
||||
" {\n",
|
||||
" cout << \"点在圆外\" << endl;\n",
|
||||
" }\n",
|
||||
" else\n",
|
||||
" {\n",
|
||||
" cout << \"点在圆内\" << endl;\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" //创建圆\n",
|
||||
" Circle c;\n",
|
||||
" c.setR(10);\n",
|
||||
" Point center;\n",
|
||||
" center.setX(10); //设置点的横坐标\n",
|
||||
" center.setY(0); //设置点的纵坐标\n",
|
||||
" c.setCenter(center); //设置点类传入圆类\n",
|
||||
"\n",
|
||||
" //创建点\n",
|
||||
" Point p;\n",
|
||||
" p.setX(10);\n",
|
||||
" p.setY(10);\n",
|
||||
" \n",
|
||||
" //判断关系\n",
|
||||
" isInCircle(c, p);\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
318
docs/CPlusPlus-main/21_C++的调用其他类.md
Normal file
@ -0,0 +1,318 @@
|
||||
# C++的调用其他类
|
||||
|
||||
# 1. 类中有其他的类
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//点和圆关系案例
|
||||
|
||||
//点类
|
||||
class Point
|
||||
{
|
||||
public:
|
||||
//设置x
|
||||
void setX(int x)
|
||||
{
|
||||
m_X = x;
|
||||
}
|
||||
//获取x
|
||||
int getX()
|
||||
{
|
||||
return m_X;
|
||||
}
|
||||
//设置y
|
||||
void setY(int y)
|
||||
{
|
||||
m_Y = y;
|
||||
}
|
||||
//获取y
|
||||
int getY()
|
||||
{
|
||||
return m_Y;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_X;
|
||||
int m_Y;
|
||||
};
|
||||
|
||||
//圆类
|
||||
class Circle
|
||||
{
|
||||
public:
|
||||
//设置半径
|
||||
void setR(int r)
|
||||
{
|
||||
m_R = r;
|
||||
}
|
||||
//获取半径
|
||||
int getR()
|
||||
{
|
||||
return m_R;
|
||||
}
|
||||
//设置圆心
|
||||
void setCenter(Point center)
|
||||
{
|
||||
m_Center = center;
|
||||
}
|
||||
//获取圆心
|
||||
Point getCenter()
|
||||
{
|
||||
return m_Center;
|
||||
}
|
||||
private:
|
||||
int m_R; //半径
|
||||
Point m_Center; //圆心 //在类中可以让另一个类 作为本类中的成员
|
||||
};
|
||||
|
||||
//判断点和圆关系
|
||||
void isInCircle(Circle& c, Point& p)
|
||||
{
|
||||
//计算两点之间距离 平方
|
||||
int distance =
|
||||
(c.getCenter().getX() - p.getX()) * (c.getCenter().getX() - p.getX()) +
|
||||
(c.getCenter().getY() - p.getY()) * (c.getCenter().getY() - p.getY()); //c.getCenter()返回的是圆心点center类
|
||||
//可以调用圆心点center类中的方法
|
||||
|
||||
//计算半径的平方
|
||||
int rDistance = c.getR() * c.getR();
|
||||
|
||||
//判断关系
|
||||
if (distance == rDistance)
|
||||
{
|
||||
cout << "点在圆上" << endl;
|
||||
}
|
||||
else if (distance > rDistance)
|
||||
{
|
||||
cout << "点在圆外" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "点在圆内" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
//创建圆
|
||||
Circle c;
|
||||
c.setR(10);
|
||||
Point center;
|
||||
center.setX(10); //设置点的横坐标
|
||||
center.setY(0); //设置点的纵坐标
|
||||
c.setCenter(center); //设置点类传入圆类
|
||||
|
||||
//创建点
|
||||
Point p;
|
||||
p.setX(10);
|
||||
p.setY(10);
|
||||
|
||||
//判断关系
|
||||
isInCircle(c, p);
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 点在圆上
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 2. 导入其他文件的类
|
||||
|
||||
## 2.1 point.h头文件
|
||||
|
||||
|
||||
```python
|
||||
//这是point.h头文件
|
||||
|
||||
#pragma once //防止头文件重复包含,防止头文件冲突
|
||||
#include <iostream> //标准输入输出
|
||||
using namespace std; //标准命名空间
|
||||
|
||||
//只要函数声明、变量声明
|
||||
//成员函数只需要声明就好了,末尾有分号。
|
||||
class Point
|
||||
{
|
||||
public:
|
||||
//设置x
|
||||
void setX(int x);
|
||||
|
||||
//获取x
|
||||
int getX();
|
||||
|
||||
//设置y
|
||||
void setY(int y);
|
||||
|
||||
//获取y
|
||||
int getY();
|
||||
|
||||
|
||||
private:
|
||||
int m_X;
|
||||
int m_Y;
|
||||
};
|
||||
```
|
||||
|
||||
## 2.2 point.cpp源文件
|
||||
|
||||
|
||||
```python
|
||||
//这是point.cpp源文件
|
||||
#include "point.h"
|
||||
|
||||
//定义函数时,要加上作用域,"双冒号::"表示Point作用域下的函数
|
||||
void Point::setX(int x)
|
||||
{
|
||||
m_X = x;
|
||||
}
|
||||
//获取x
|
||||
int Point::getX()
|
||||
{
|
||||
return m_X;
|
||||
}
|
||||
//设置y
|
||||
void Point::setY(int y)
|
||||
{
|
||||
m_Y = y;
|
||||
}
|
||||
//获取y
|
||||
int Point::getY()
|
||||
{
|
||||
return m_Y;
|
||||
}
|
||||
```
|
||||
|
||||
## 2.3 circle.h头文件
|
||||
|
||||
|
||||
```python
|
||||
#pragma once
|
||||
#include <iostream> //标准输出流
|
||||
using namespace std; //标准命名空间
|
||||
#include "Point.h" //一个类中用到另一个类,把另一个类包含的头文件包含进来
|
||||
|
||||
//圆类
|
||||
class Circle
|
||||
{
|
||||
public:
|
||||
//设置半径
|
||||
void setR(int r);
|
||||
|
||||
//获取半径
|
||||
int getR();
|
||||
|
||||
//设置圆心
|
||||
void setCenter(Point center);
|
||||
|
||||
//获取圆心
|
||||
Point getCenter();
|
||||
|
||||
private:
|
||||
int m_R; //半径
|
||||
Point m_Center; //圆心 //在类中可以让另一个类 作为本类中的成员
|
||||
};
|
||||
```
|
||||
|
||||
## 2.4 circle.cpp头文件
|
||||
|
||||
|
||||
```python
|
||||
//这是circle.cpp头文件
|
||||
|
||||
#include "circle.h"
|
||||
|
||||
//设置半径
|
||||
void Circle::setR(int r)
|
||||
{
|
||||
m_R = r;
|
||||
}
|
||||
|
||||
//获取半径
|
||||
int Circle::getR()
|
||||
{
|
||||
return m_R;
|
||||
}
|
||||
|
||||
//设置圆心
|
||||
void Circle::setCenter(Point center)
|
||||
{
|
||||
m_Center = center;
|
||||
}
|
||||
|
||||
//获取圆心
|
||||
Point Circle::getCenter()
|
||||
{
|
||||
return m_Center;
|
||||
}
|
||||
```
|
||||
|
||||
## 2.5 main.cpp文件
|
||||
|
||||
|
||||
```python
|
||||
//这个是主文件 .cpp文件
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include "circle.h" //想用点类,就要包含点类的头文件
|
||||
#include "point.h" //想用圆类,就要包含点类的头文件
|
||||
|
||||
|
||||
//判断点和圆关系
|
||||
void isInCircle(Circle& c, Point& p)
|
||||
{
|
||||
//计算两点之间距离 平方
|
||||
int distance =
|
||||
(c.getCenter().getX() - p.getX()) * (c.getCenter().getX() - p.getX()) +
|
||||
(c.getCenter().getY() - p.getY()) * (c.getCenter().getY() - p.getY()); //c.getCenter()返回的是圆心点center类
|
||||
//可以调用圆心点center类中的方法
|
||||
|
||||
//计算半径的平方
|
||||
int rDistance = c.getR() * c.getR();
|
||||
|
||||
//判断关系
|
||||
if (distance == rDistance)
|
||||
{
|
||||
cout << "点在圆上" << endl;
|
||||
}
|
||||
else if (distance > rDistance)
|
||||
{
|
||||
cout << "点在圆外" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "点在圆内" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
//创建圆
|
||||
Circle c;
|
||||
c.setR(10);
|
||||
Point center;
|
||||
center.setX(10); //设置点的横坐标
|
||||
center.setY(0); //设置点的纵坐标
|
||||
c.setCenter(center); //设置点类传入圆类
|
||||
|
||||
//创建点
|
||||
Point p;
|
||||
p.setX(10);
|
||||
p.setY(10);
|
||||
|
||||
//判断关系
|
||||
isInCircle(c, p);
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
1736
docs/CPlusPlus-main/22_C++的类中特性.ipynb
Normal file
1319
docs/CPlusPlus-main/22_C++的类中特性.md
Normal file
BIN
docs/CPlusPlus-main/22_C++的类中特性_files/image.png
Normal file
|
After Width: | Height: | Size: 367 KiB |
334
docs/CPlusPlus-main/23_C++的类中友元.ipynb
Normal file
@ -0,0 +1,334 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的友元"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 友元简介"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 生活中你的家有客厅(Public),有你的卧室(Private),客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的好闺蜜进去。\n",
|
||||
"\n",
|
||||
"② 在程序里,有些私有属性,也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术。\n",
|
||||
"\n",
|
||||
"③ 友元的目的就是让一个函数或者类访问另一个类中私有成员。\n",
|
||||
"\n",
|
||||
"④ 友元的关键字为 friend。\n",
|
||||
"\n",
|
||||
"⑤ 友元的三种实现:\n",
|
||||
"\n",
|
||||
"1. 全局函数做友元。\n",
|
||||
"2. 类做友元。\n",
|
||||
"3. 成员函数做友元。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//建筑物类\n",
|
||||
"class Buiding\n",
|
||||
"{\n",
|
||||
" //goodfriend全局函数是Buiding类好朋友,可以访问Buiding中私有成员\n",
|
||||
" friend void goodfriend(Buiding* buiding);\n",
|
||||
"\n",
|
||||
"public:\n",
|
||||
" Buiding() //构造函数 赋初值\n",
|
||||
" {\n",
|
||||
" m_SittingRoom = \"客厅\";\n",
|
||||
" m_BedRoom = \"卧室\";\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"public:\n",
|
||||
" string m_SittingRoom; //客厅\n",
|
||||
"\n",
|
||||
"private:\n",
|
||||
" string m_BedRoom;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"//全局函数\n",
|
||||
"void goodfriend(Buiding *buiding)\n",
|
||||
"{\n",
|
||||
" cout << \"好基友全局函数 正在访问:\" << buiding->m_SittingRoom << endl;\n",
|
||||
" cout << \"好基友全局函数 正在访问:\" << buiding->m_BedRoom << endl;\n",
|
||||
"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" Buiding building;\n",
|
||||
" goodfriend(&building);\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" test01();\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 好基友全局函数 正在访问:客厅 \n",
|
||||
" - 好基友全局函数 正在访问:卧室 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 2. 友元类"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//类做友元\n",
|
||||
"class Building; //声明\n",
|
||||
"\n",
|
||||
"class GoodGay\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" GoodGay();\n",
|
||||
"\n",
|
||||
" void visit(); //参观函数 访问Building中的属性\n",
|
||||
"\n",
|
||||
" Building* building;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"class Building\n",
|
||||
"{\n",
|
||||
" //GoodGay类是本类的好朋友,可以访问本类的私有成员\n",
|
||||
" friend class GoodGay;\n",
|
||||
"\n",
|
||||
"public:\n",
|
||||
" Building();\n",
|
||||
"\n",
|
||||
"public:\n",
|
||||
" string m_SittingRoom; //客厅\n",
|
||||
"private:\n",
|
||||
" string m_BedRoom; //卧室\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"//类外写成员函数,写类名的作用域\n",
|
||||
"\n",
|
||||
"//Building构造函数\n",
|
||||
"Building::Building()\n",
|
||||
"{\n",
|
||||
" m_SittingRoom = \"客厅\";\n",
|
||||
" m_BedRoom = \"卧室\";\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"//GoodGay构造函数\n",
|
||||
"GoodGay::GoodGay()\n",
|
||||
"{\n",
|
||||
" //创建建筑物对象\n",
|
||||
" building = new Building; //这里会调用Building的构造函数\n",
|
||||
" //new是创建什么样的数据类型,就返回什么样的数据类型的指针 \n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"void GoodGay::visit()\n",
|
||||
"{\n",
|
||||
" cout << \"好基友类正在访问:\" << building->m_SittingRoom << endl;\n",
|
||||
"\n",
|
||||
" cout << \"好基友类正在访问:\" << building->m_BedRoom << endl;\n",
|
||||
"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" GoodGay gg; //创建一个GoodGay的对象,会调用GoodGay构造函数,会创建一个building,然后调用building构造函数 \n",
|
||||
" gg.visit();\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" test01();\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 好基友类正在访问:客厅 \n",
|
||||
" - 好基友类正在访问:卧室 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 3. 成员函数做友元"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"class Building;\n",
|
||||
"class GoodGay\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" GoodGay();\n",
|
||||
"\n",
|
||||
" void visit(); //让visit函数可以访问Building中私有成员\n",
|
||||
" void visit2(); //让visit2函数不可以访问Buildinng中私有成员\n",
|
||||
"\n",
|
||||
" Building* building;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"class Building\n",
|
||||
"{\n",
|
||||
" //告诉编译器,GoodGay类下的visit成员函数作为本类的好朋友,可以访问私有成员 \n",
|
||||
" friend void GoodGay::visit();\n",
|
||||
"\n",
|
||||
"public:\n",
|
||||
" Building();\n",
|
||||
"\n",
|
||||
"public:\n",
|
||||
" string m_SittingRoom; //客厅\n",
|
||||
"\n",
|
||||
"private:\n",
|
||||
" string m_BedRoom; //卧室\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"// 类外实现构造函数\n",
|
||||
"Building::Building()\n",
|
||||
"{\n",
|
||||
" m_SittingRoom = \"客厅\";\n",
|
||||
" m_BedRoom = \"卧室\";\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"GoodGay::GoodGay()\n",
|
||||
"{\n",
|
||||
" building = new Building;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"// 类外实现成员函数\n",
|
||||
"void GoodGay::visit()\n",
|
||||
"{\n",
|
||||
" cout << \"visit 函数正在访问\" << building->m_SittingRoom << endl;\n",
|
||||
" cout << \"visit 函数正在访问\" << building->m_BedRoom << endl;\n",
|
||||
"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"void GoodGay::visit2()\n",
|
||||
"{\n",
|
||||
" cout << \"visit2 函数正在访问\" << building->m_SittingRoom << endl;\n",
|
||||
" //cout << \"visit 函数正在访问\" << building->m_BedRoom << endl;\n",
|
||||
"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" GoodGay gg;\n",
|
||||
" gg.visit();\n",
|
||||
" gg.visit2();\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" test01();\n",
|
||||
" \n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - visit 函数正在访问客厅 \n",
|
||||
" - visit 函数正在访问卧室 \n",
|
||||
" - visit2 函数正在访问客厅 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {
|
||||
"height": "calc(100% - 180px)",
|
||||
"left": "10px",
|
||||
"top": "150px",
|
||||
"width": "341.333px"
|
||||
},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
238
docs/CPlusPlus-main/23_C++的类中友元.md
Normal file
@ -0,0 +1,238 @@
|
||||
# C++的友元
|
||||
|
||||
# 1. 友元简介
|
||||
|
||||
① 生活中你的家有客厅(Public),有你的卧室(Private),客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的好闺蜜进去。
|
||||
|
||||
② 在程序里,有些私有属性,也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术。
|
||||
|
||||
③ 友元的目的就是让一个函数或者类访问另一个类中私有成员。
|
||||
|
||||
④ 友元的关键字为 friend。
|
||||
|
||||
⑤ 友元的三种实现:
|
||||
|
||||
1. 全局函数做友元。
|
||||
2. 类做友元。
|
||||
3. 成员函数做友元。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//建筑物类
|
||||
class Buiding
|
||||
{
|
||||
//goodfriend全局函数是Buiding类好朋友,可以访问Buiding中私有成员
|
||||
friend void goodfriend(Buiding* buiding);
|
||||
|
||||
public:
|
||||
Buiding() //构造函数 赋初值
|
||||
{
|
||||
m_SittingRoom = "客厅";
|
||||
m_BedRoom = "卧室";
|
||||
}
|
||||
|
||||
public:
|
||||
string m_SittingRoom; //客厅
|
||||
|
||||
private:
|
||||
string m_BedRoom;
|
||||
};
|
||||
|
||||
//全局函数
|
||||
void goodfriend(Buiding *buiding)
|
||||
{
|
||||
cout << "好基友全局函数 正在访问:" << buiding->m_SittingRoom << endl;
|
||||
cout << "好基友全局函数 正在访问:" << buiding->m_BedRoom << endl;
|
||||
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
Buiding building;
|
||||
goodfriend(&building);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 好基友全局函数 正在访问:客厅
|
||||
- 好基友全局函数 正在访问:卧室
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 2. 友元类
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//类做友元
|
||||
class Building; //声明
|
||||
|
||||
class GoodGay
|
||||
{
|
||||
public:
|
||||
GoodGay();
|
||||
|
||||
void visit(); //参观函数 访问Building中的属性
|
||||
|
||||
Building* building;
|
||||
};
|
||||
|
||||
class Building
|
||||
{
|
||||
//GoodGay类是本类的好朋友,可以访问本类的私有成员
|
||||
friend class GoodGay;
|
||||
|
||||
public:
|
||||
Building();
|
||||
|
||||
public:
|
||||
string m_SittingRoom; //客厅
|
||||
private:
|
||||
string m_BedRoom; //卧室
|
||||
};
|
||||
|
||||
//类外写成员函数,写类名的作用域
|
||||
|
||||
//Building构造函数
|
||||
Building::Building()
|
||||
{
|
||||
m_SittingRoom = "客厅";
|
||||
m_BedRoom = "卧室";
|
||||
}
|
||||
|
||||
//GoodGay构造函数
|
||||
GoodGay::GoodGay()
|
||||
{
|
||||
//创建建筑物对象
|
||||
building = new Building; //这里会调用Building的构造函数
|
||||
//new是创建什么样的数据类型,就返回什么样的数据类型的指针
|
||||
}
|
||||
|
||||
void GoodGay::visit()
|
||||
{
|
||||
cout << "好基友类正在访问:" << building->m_SittingRoom << endl;
|
||||
|
||||
cout << "好基友类正在访问:" << building->m_BedRoom << endl;
|
||||
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
GoodGay gg; //创建一个GoodGay的对象,会调用GoodGay构造函数,会创建一个building,然后调用building构造函数
|
||||
gg.visit();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 好基友类正在访问:客厅
|
||||
- 好基友类正在访问:卧室
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 3. 成员函数做友元
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
class Building;
|
||||
class GoodGay
|
||||
{
|
||||
public:
|
||||
GoodGay();
|
||||
|
||||
void visit(); //让visit函数可以访问Building中私有成员
|
||||
void visit2(); //让visit2函数不可以访问Buildinng中私有成员
|
||||
|
||||
Building* building;
|
||||
};
|
||||
|
||||
class Building
|
||||
{
|
||||
//告诉编译器,GoodGay类下的visit成员函数作为本类的好朋友,可以访问私有成员
|
||||
friend void GoodGay::visit();
|
||||
|
||||
public:
|
||||
Building();
|
||||
|
||||
public:
|
||||
string m_SittingRoom; //客厅
|
||||
|
||||
private:
|
||||
string m_BedRoom; //卧室
|
||||
};
|
||||
|
||||
// 类外实现构造函数
|
||||
Building::Building()
|
||||
{
|
||||
m_SittingRoom = "客厅";
|
||||
m_BedRoom = "卧室";
|
||||
}
|
||||
|
||||
GoodGay::GoodGay()
|
||||
{
|
||||
building = new Building;
|
||||
}
|
||||
|
||||
// 类外实现成员函数
|
||||
void GoodGay::visit()
|
||||
{
|
||||
cout << "visit 函数正在访问" << building->m_SittingRoom << endl;
|
||||
cout << "visit 函数正在访问" << building->m_BedRoom << endl;
|
||||
|
||||
}
|
||||
|
||||
void GoodGay::visit2()
|
||||
{
|
||||
cout << "visit2 函数正在访问" << building->m_SittingRoom << endl;
|
||||
//cout << "visit 函数正在访问" << building->m_BedRoom << endl;
|
||||
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
GoodGay gg;
|
||||
gg.visit();
|
||||
gg.visit2();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- visit 函数正在访问客厅
|
||||
- visit 函数正在访问卧室
|
||||
- visit2 函数正在访问客厅
|
||||
- 请按任意键继续. . .
|
||||
720
docs/CPlusPlus-main/24_C++的类中运算符重载.ipynb
Normal file
@ -0,0 +1,720 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++ 运算符重载"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 运算符重载简介"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 运算符重载:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。\n",
|
||||
"\n",
|
||||
"② 对于内置的数据类型的表达式的运算符是不可能改变的。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 2. 加号运算符重载"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 加号运算符作用:实现两个自定义数据类型相加的运算。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//加号运算符重载\n",
|
||||
"class Person\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
"\n",
|
||||
" //1、成员函数重载+号\n",
|
||||
" Person operator+(Person& p)\n",
|
||||
" {\n",
|
||||
" Person temp;\n",
|
||||
" temp.m_A = this->m_A + p.m_A;\n",
|
||||
" temp.m_B = this->m_B + p.m_B;\n",
|
||||
" return temp;\n",
|
||||
" }\n",
|
||||
" int m_A;\n",
|
||||
" int m_B;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"/*\n",
|
||||
"//全局函数重载+号\n",
|
||||
"Person operator+(Person &p1, Person &p2)\n",
|
||||
"{\n",
|
||||
" Person temp;\n",
|
||||
" temp.m_A = p1.m_A + p2.m_A;\n",
|
||||
" temp.m_B = p1.m_B + p2.m_B;\n",
|
||||
" return temp;\n",
|
||||
"}\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"//函数重载的版本\n",
|
||||
"Person operator+(Person& p1, int num)\n",
|
||||
"{\n",
|
||||
" Person temp;\n",
|
||||
" temp.m_A = p1.m_A + num;\n",
|
||||
" temp.m_B = p1.m_B + num;\n",
|
||||
" return temp;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" Person p1;\n",
|
||||
" p1.m_A = 10;\n",
|
||||
" p1.m_B = 10;\n",
|
||||
" Person p2;\n",
|
||||
" p2.m_A = 10;\n",
|
||||
" p2.m_B = 10;\n",
|
||||
"\n",
|
||||
" //成员函数重载本质调用 \n",
|
||||
" //Person p3 = p1.operator+(p2);\n",
|
||||
" \n",
|
||||
" //全局函数重载本质调用 \n",
|
||||
" //Person p3 = operator+(p1,p2);\n",
|
||||
" \n",
|
||||
" Person p3 = p1 + p2; //重载本质被简化后的形式\n",
|
||||
"\n",
|
||||
" //运算符重载,也可以发生函数重载\n",
|
||||
"\n",
|
||||
" Person p4 = p1 + 10; //Person + int\n",
|
||||
"\n",
|
||||
" cout << \"p3.m_A:\" << p3.m_A << endl;\n",
|
||||
" cout << \"p3.m_B:\" << p3.m_B << endl;\n",
|
||||
"\n",
|
||||
" cout << \"p4.m_A:\" << p4.m_A << endl;\n",
|
||||
" cout << \"p4.m_B:\" << p4.m_B << endl;\n",
|
||||
"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" test01();\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - p3.m_A:20 \n",
|
||||
" - p3.m_B:20 \n",
|
||||
" - p4.m_A:20 \n",
|
||||
" - p4.m_B:20 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 3. 左移运算符重载"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 左移运算符重载:可以输出自定义数据类型。\n",
|
||||
"\n",
|
||||
"② 重载左移运算符配合友元可以实现自定义数据类型。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//左移运算符\n",
|
||||
"class Person\n",
|
||||
"{\n",
|
||||
"\n",
|
||||
" friend ostream& operator<<(ostream& out, Person& p);\t\n",
|
||||
"\n",
|
||||
"public:\n",
|
||||
" Person(int a, int b)\n",
|
||||
" {\n",
|
||||
" m_A = a;\n",
|
||||
" m_B = b;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" /*\n",
|
||||
" //利用成员函数重载 左移运算符 p.operator<<(cout) 简化版本 p << cout\n",
|
||||
" //成员函数不能利用重载<<运算符,因为无法实现cout在左侧\n",
|
||||
" //当不知道返回值是什么类型的时候,可以先写个void,以后再改\n",
|
||||
" void operator<<(Person& p)\n",
|
||||
" {\n",
|
||||
" \n",
|
||||
" }\n",
|
||||
" */\n",
|
||||
" \n",
|
||||
"private:\n",
|
||||
" int m_A;\n",
|
||||
" int m_B;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"//只能利用全局函数重载左移运算符\n",
|
||||
"//如果返回类型为void,那么就无法无限追加,也没有办法在后面添加换行符\n",
|
||||
"ostream & operator<<(ostream &cout, Person &p) //本质 operator << (cout , p) , 简化 cout << p\n",
|
||||
" //cout是别名,这里可以取out、kn...\n",
|
||||
" //cout为ostream输出流数据类型 \n",
|
||||
"{\n",
|
||||
" cout << \"m_A= \" << p.m_A << \" m_B=\" << p.m_B;\n",
|
||||
" return cout;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" Person p(10,10);\n",
|
||||
"\n",
|
||||
" cout << p << \" hello world\" << endl;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" test01();\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - m_A= 10 m_B=10 hello world \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 4. 递增运算符"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 递增运算符重载:通过重载递增运算符,实现自己的整型数据。\n",
|
||||
"\n",
|
||||
"② 前置递增返回的是引用,后置递增返回的是值。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//重载递增运算符\n",
|
||||
"\n",
|
||||
"class MyInteger\n",
|
||||
"{\n",
|
||||
" friend ostream& operator<<(ostream& cout, MyInteger myint);\n",
|
||||
"\n",
|
||||
"public:\n",
|
||||
" MyInteger()\n",
|
||||
" {\n",
|
||||
" m_Num = 0;\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
" //重载前置++运算符,返回引用是为了一直对一个数据进行递增操作,而返回值并不是一直对一个数据进行递增操作 \n",
|
||||
" MyInteger& operator++()\n",
|
||||
" {\n",
|
||||
" //先进行++运算\n",
|
||||
" m_Num++;\n",
|
||||
"\n",
|
||||
" //再将自身做一个返回\n",
|
||||
" return *this; //把自身做一个返回\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //重载后置++运算符 int代表占位参数,可以用于区分前置和后置递增\n",
|
||||
" //后置递增不能返回引用,因为temp是局部变量,如果返回temp,当程序运行完后变量就释放了,再调用temp就是非法操作了 \n",
|
||||
" MyInteger operator++(int)\n",
|
||||
" {\n",
|
||||
" //先记录当时结果\n",
|
||||
" MyInteger temp = *this;\n",
|
||||
" //后 递增\n",
|
||||
" m_Num++;\n",
|
||||
" //最后将记录结果做返回\n",
|
||||
" return temp;\n",
|
||||
" }\n",
|
||||
"private:\n",
|
||||
" int m_Num;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"//只能利用全局函数重载左移运算符\n",
|
||||
"ostream & operator<<(ostream &cout, MyInteger myint) //本质 operator << (cout , p) , 简化 cout << p\n",
|
||||
" //cout是别名,这里可以取out、kn...\n",
|
||||
" //cout为ostream输出流数据类型 \n",
|
||||
"{\n",
|
||||
" cout << myint.m_Num;\n",
|
||||
"\n",
|
||||
" return cout;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" MyInteger myint;\n",
|
||||
"\n",
|
||||
" cout << ++(++myint) << endl;\n",
|
||||
" cout << myint << endl;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"void test02()\n",
|
||||
"{\n",
|
||||
" MyInteger myint;\n",
|
||||
"\n",
|
||||
" cout << myint++ << endl;\n",
|
||||
" cout << myint << endl;\n",
|
||||
"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" test01();\n",
|
||||
" test02();\n",
|
||||
"\n",
|
||||
" /*\n",
|
||||
" int a = 0;\n",
|
||||
" cout << ++(++a) << endl; //运行结果为2\n",
|
||||
" cout << a << endl; //运行结果为2,表示一直对一个数据进行递增\n",
|
||||
" */\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 2 \n",
|
||||
" - 2 \n",
|
||||
" - 0 \n",
|
||||
" - 1 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 5. 赋值运算符"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① C++编译器至少给一个类添加4个函数:\n",
|
||||
"\n",
|
||||
"1. 默认构造函数(无参,函数体为空)\n",
|
||||
"2. 默认析构函数(无参,函数体为空)\n",
|
||||
"3. 默认拷贝构造函数,对属性进行值拷贝\n",
|
||||
"4. 赋值运算符operator=,对属性进行值拷贝\n",
|
||||
"5. 如果类中有属性指向堆区,做赋值操作时也会出现浅拷贝问题。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"//重载赋值运算符\n",
|
||||
"\n",
|
||||
"class Person\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" Person(int age)\n",
|
||||
" {\n",
|
||||
" m_Age = new int(age);\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
" ~Person()\n",
|
||||
" {\n",
|
||||
" if (m_Age != NULL)\n",
|
||||
" {\n",
|
||||
" delete m_Age;\n",
|
||||
" m_Age = NULL;\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //重载 赋值运算符\n",
|
||||
" //如果返回的是值,而不是引用,是创建一个拷贝函数,返回的是一个副本,而不是自身\n",
|
||||
" Person& operator=(Person& p)\n",
|
||||
" {\n",
|
||||
" //编译器默认是提供浅拷贝\n",
|
||||
" //m_Age = p.m_Age;\n",
|
||||
"\n",
|
||||
" //浅拷贝带来的问题是,当创建数据在堆区时,析构代码导致内存重复释放,报错\n",
|
||||
"\n",
|
||||
" //应该先判断是否有属性在堆区,如果有先释放干净,然后再深拷贝\n",
|
||||
" if (m_Age != NULL)\n",
|
||||
" {\n",
|
||||
" delete m_Age;\n",
|
||||
" m_Age = NULL;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //深拷贝\n",
|
||||
" m_Age = new int(*p.m_Age);\n",
|
||||
"\n",
|
||||
" //返回对象本身\n",
|
||||
" return *this;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" int *m_Age;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" Person p1(18);\n",
|
||||
"\n",
|
||||
" Person p2(20);\n",
|
||||
"\n",
|
||||
" Person p3(23);\n",
|
||||
"\n",
|
||||
" p3 = p2 = p1; //赋值操作\n",
|
||||
"\n",
|
||||
" cout << \"p1的年龄为:\" << *p1.m_Age << endl;\n",
|
||||
"\n",
|
||||
" cout << \"p2的年龄为:\" << *p2.m_Age << endl;\n",
|
||||
"\n",
|
||||
" cout << \"p3的年龄为:\" << *p3.m_Age << endl;\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" test01();\n",
|
||||
"\n",
|
||||
" /*\n",
|
||||
" \n",
|
||||
" int a = 10;\n",
|
||||
" int b = 20;\n",
|
||||
" int c = 30;\n",
|
||||
" \n",
|
||||
" c = b = a;\n",
|
||||
"\n",
|
||||
" cout << \"a= \" << a << endl;\n",
|
||||
" cout << \"b= \" << b << endl;\n",
|
||||
" cout << \"c= \" << c << endl;\n",
|
||||
" */\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - p1的年龄为:18 \n",
|
||||
" - p2的年龄为:18 \n",
|
||||
" - p3的年龄为:18 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 6. 关系重载运算符"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include<string>\n",
|
||||
"\n",
|
||||
"//重载关系运算符\n",
|
||||
"\n",
|
||||
"class Person\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" Person(string name, int age)\n",
|
||||
" {\n",
|
||||
" m_Name = name;\n",
|
||||
" m_Age = age;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //重载 == 号\n",
|
||||
" bool operator==(Person& p)\n",
|
||||
" {\n",
|
||||
" if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)\n",
|
||||
" {\n",
|
||||
" return true;\n",
|
||||
" }\n",
|
||||
" return false;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" bool operator!=(Person& p)\n",
|
||||
" {\n",
|
||||
" if (this->m_Name != p.m_Name && this->m_Age != p.m_Age)\n",
|
||||
" {\n",
|
||||
" return true;\n",
|
||||
" }\n",
|
||||
" return false;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" string m_Name;\n",
|
||||
" int m_Age;\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" Person p1(\"Tom\", 17);\n",
|
||||
"\n",
|
||||
" Person p2(\"Jerry\", 18);\n",
|
||||
"\n",
|
||||
" if (p1 == p2)\n",
|
||||
" {\n",
|
||||
" cout << \"p1和p2是相等的!\" << endl;\n",
|
||||
" }\n",
|
||||
" else\n",
|
||||
" {\n",
|
||||
" cout << \"p1和p2是不相等的!\" << endl;\n",
|
||||
"\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" if (p1 != p2)\n",
|
||||
" {\n",
|
||||
" cout << \"p1和p2是不相等的!\" << endl;\n",
|
||||
" }\n",
|
||||
" else\n",
|
||||
" {\n",
|
||||
" cout << \"p1和p2是相等的!\" << endl;\n",
|
||||
"\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" test01();\n",
|
||||
" \n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - p1和p2是不相等的! \n",
|
||||
" - p1和p2是不相等的! \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 7. 函数调用运算符重载"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 函数调用运算符()也可以重载。\n",
|
||||
"\n",
|
||||
"② 由于重载后使用的方式非常像函数的调用,因此称为仿函数。\n",
|
||||
"\n",
|
||||
"③ 仿函数没有固定写法,非常灵活。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include <iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include<string>\n",
|
||||
"\n",
|
||||
"//函数调用运算符重载\n",
|
||||
"\n",
|
||||
"//打印输出类\n",
|
||||
"class MyPrint\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
"\n",
|
||||
" //重载函数调用运算符\n",
|
||||
" void operator()(string test)\n",
|
||||
" {\n",
|
||||
" cout << test << endl;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"//正常函数\n",
|
||||
"void MyPrint02(string test)\n",
|
||||
"{\n",
|
||||
" cout << test << endl;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" MyPrint myPrint;\n",
|
||||
"\n",
|
||||
" myPrint(\"hello world\");\n",
|
||||
"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"//仿函数非常灵活,没有固定的写法\n",
|
||||
"//加法类\n",
|
||||
"class MyAdd\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" int operator()(int num1, int num2)\n",
|
||||
" {\n",
|
||||
" return num1 + num2;\n",
|
||||
" }\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"void test02()\n",
|
||||
"{\n",
|
||||
" MyAdd myadd;\n",
|
||||
" int ret = myadd(100,100);\n",
|
||||
" cout << \"ret = \" << ret << endl;\n",
|
||||
"\n",
|
||||
" //匿名函数对象\n",
|
||||
" cout << MyAdd()(100, 100) << endl;\n",
|
||||
"\n",
|
||||
" // MyAdd()为创建一个匿名对象,匿名对象的特点为当前行执行完立即释放\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main()\n",
|
||||
"{\n",
|
||||
" test01();\n",
|
||||
"\n",
|
||||
" MyPrint02(\"hello world\"); //由于使用起来非常类似于函数调用,因此称为仿函数\n",
|
||||
"\n",
|
||||
" test02();\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - hello world \n",
|
||||
" - hello world \n",
|
||||
" - ret = 200 \n",
|
||||
" - 200 \n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
557
docs/CPlusPlus-main/24_C++的类中运算符重载.md
Normal file
@ -0,0 +1,557 @@
|
||||
# C++ 运算符重载
|
||||
|
||||
# 1. 运算符重载简介
|
||||
|
||||
① 运算符重载:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
|
||||
|
||||
② 对于内置的数据类型的表达式的运算符是不可能改变的。
|
||||
|
||||
# 2. 加号运算符重载
|
||||
|
||||
① 加号运算符作用:实现两个自定义数据类型相加的运算。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//加号运算符重载
|
||||
class Person
|
||||
{
|
||||
public:
|
||||
|
||||
//1、成员函数重载+号
|
||||
Person operator+(Person& p)
|
||||
{
|
||||
Person temp;
|
||||
temp.m_A = this->m_A + p.m_A;
|
||||
temp.m_B = this->m_B + p.m_B;
|
||||
return temp;
|
||||
}
|
||||
int m_A;
|
||||
int m_B;
|
||||
};
|
||||
|
||||
/*
|
||||
//全局函数重载+号
|
||||
Person operator+(Person &p1, Person &p2)
|
||||
{
|
||||
Person temp;
|
||||
temp.m_A = p1.m_A + p2.m_A;
|
||||
temp.m_B = p1.m_B + p2.m_B;
|
||||
return temp;
|
||||
}
|
||||
*/
|
||||
|
||||
//函数重载的版本
|
||||
Person operator+(Person& p1, int num)
|
||||
{
|
||||
Person temp;
|
||||
temp.m_A = p1.m_A + num;
|
||||
temp.m_B = p1.m_B + num;
|
||||
return temp;
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
Person p1;
|
||||
p1.m_A = 10;
|
||||
p1.m_B = 10;
|
||||
Person p2;
|
||||
p2.m_A = 10;
|
||||
p2.m_B = 10;
|
||||
|
||||
//成员函数重载本质调用
|
||||
//Person p3 = p1.operator+(p2);
|
||||
|
||||
//全局函数重载本质调用
|
||||
//Person p3 = operator+(p1,p2);
|
||||
|
||||
Person p3 = p1 + p2; //重载本质被简化后的形式
|
||||
|
||||
//运算符重载,也可以发生函数重载
|
||||
|
||||
Person p4 = p1 + 10; //Person + int
|
||||
|
||||
cout << "p3.m_A:" << p3.m_A << endl;
|
||||
cout << "p3.m_B:" << p3.m_B << endl;
|
||||
|
||||
cout << "p4.m_A:" << p4.m_A << endl;
|
||||
cout << "p4.m_B:" << p4.m_B << endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- p3.m_A:20
|
||||
- p3.m_B:20
|
||||
- p4.m_A:20
|
||||
- p4.m_B:20
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 3. 左移运算符重载
|
||||
|
||||
① 左移运算符重载:可以输出自定义数据类型。
|
||||
|
||||
② 重载左移运算符配合友元可以实现自定义数据类型。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//左移运算符
|
||||
class Person
|
||||
{
|
||||
|
||||
friend ostream& operator<<(ostream& out, Person& p);
|
||||
|
||||
public:
|
||||
Person(int a, int b)
|
||||
{
|
||||
m_A = a;
|
||||
m_B = b;
|
||||
}
|
||||
|
||||
/*
|
||||
//利用成员函数重载 左移运算符 p.operator<<(cout) 简化版本 p << cout
|
||||
//成员函数不能利用重载<<运算符,因为无法实现cout在左侧
|
||||
//当不知道返回值是什么类型的时候,可以先写个void,以后再改
|
||||
void operator<<(Person& p)
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
private:
|
||||
int m_A;
|
||||
int m_B;
|
||||
};
|
||||
|
||||
//只能利用全局函数重载左移运算符
|
||||
//如果返回类型为void,那么就无法无限追加,也没有办法在后面添加换行符
|
||||
ostream & operator<<(ostream &cout, Person &p) //本质 operator << (cout , p) , 简化 cout << p
|
||||
//cout是别名,这里可以取out、kn...
|
||||
//cout为ostream输出流数据类型
|
||||
{
|
||||
cout << "m_A= " << p.m_A << " m_B=" << p.m_B;
|
||||
return cout;
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
Person p(10,10);
|
||||
|
||||
cout << p << " hello world" << endl;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- m_A= 10 m_B=10 hello world
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 4. 递增运算符
|
||||
|
||||
① 递增运算符重载:通过重载递增运算符,实现自己的整型数据。
|
||||
|
||||
② 前置递增返回的是引用,后置递增返回的是值。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//重载递增运算符
|
||||
|
||||
class MyInteger
|
||||
{
|
||||
friend ostream& operator<<(ostream& cout, MyInteger myint);
|
||||
|
||||
public:
|
||||
MyInteger()
|
||||
{
|
||||
m_Num = 0;
|
||||
}
|
||||
|
||||
//重载前置++运算符,返回引用是为了一直对一个数据进行递增操作,而返回值并不是一直对一个数据进行递增操作
|
||||
MyInteger& operator++()
|
||||
{
|
||||
//先进行++运算
|
||||
m_Num++;
|
||||
|
||||
//再将自身做一个返回
|
||||
return *this; //把自身做一个返回
|
||||
}
|
||||
|
||||
//重载后置++运算符 int代表占位参数,可以用于区分前置和后置递增
|
||||
//后置递增不能返回引用,因为temp是局部变量,如果返回temp,当程序运行完后变量就释放了,再调用temp就是非法操作了
|
||||
MyInteger operator++(int)
|
||||
{
|
||||
//先记录当时结果
|
||||
MyInteger temp = *this;
|
||||
//后 递增
|
||||
m_Num++;
|
||||
//最后将记录结果做返回
|
||||
return temp;
|
||||
}
|
||||
private:
|
||||
int m_Num;
|
||||
};
|
||||
|
||||
//只能利用全局函数重载左移运算符
|
||||
ostream & operator<<(ostream &cout, MyInteger myint) //本质 operator << (cout , p) , 简化 cout << p
|
||||
//cout是别名,这里可以取out、kn...
|
||||
//cout为ostream输出流数据类型
|
||||
{
|
||||
cout << myint.m_Num;
|
||||
|
||||
return cout;
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
MyInteger myint;
|
||||
|
||||
cout << ++(++myint) << endl;
|
||||
cout << myint << endl;
|
||||
}
|
||||
|
||||
void test02()
|
||||
{
|
||||
MyInteger myint;
|
||||
|
||||
cout << myint++ << endl;
|
||||
cout << myint << endl;
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
|
||||
/*
|
||||
int a = 0;
|
||||
cout << ++(++a) << endl; //运行结果为2
|
||||
cout << a << endl; //运行结果为2,表示一直对一个数据进行递增
|
||||
*/
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 2
|
||||
- 2
|
||||
- 0
|
||||
- 1
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 5. 赋值运算符
|
||||
|
||||
① C++编译器至少给一个类添加4个函数:
|
||||
|
||||
1. 默认构造函数(无参,函数体为空)
|
||||
2. 默认析构函数(无参,函数体为空)
|
||||
3. 默认拷贝构造函数,对属性进行值拷贝
|
||||
4. 赋值运算符operator=,对属性进行值拷贝
|
||||
5. 如果类中有属性指向堆区,做赋值操作时也会出现浅拷贝问题。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//重载赋值运算符
|
||||
|
||||
class Person
|
||||
{
|
||||
public:
|
||||
Person(int age)
|
||||
{
|
||||
m_Age = new int(age);
|
||||
}
|
||||
|
||||
~Person()
|
||||
{
|
||||
if (m_Age != NULL)
|
||||
{
|
||||
delete m_Age;
|
||||
m_Age = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//重载 赋值运算符
|
||||
//如果返回的是值,而不是引用,是创建一个拷贝函数,返回的是一个副本,而不是自身
|
||||
Person& operator=(Person& p)
|
||||
{
|
||||
//编译器默认是提供浅拷贝
|
||||
//m_Age = p.m_Age;
|
||||
|
||||
//浅拷贝带来的问题是,当创建数据在堆区时,析构代码导致内存重复释放,报错
|
||||
|
||||
//应该先判断是否有属性在堆区,如果有先释放干净,然后再深拷贝
|
||||
if (m_Age != NULL)
|
||||
{
|
||||
delete m_Age;
|
||||
m_Age = NULL;
|
||||
}
|
||||
|
||||
//深拷贝
|
||||
m_Age = new int(*p.m_Age);
|
||||
|
||||
//返回对象本身
|
||||
return *this;
|
||||
}
|
||||
|
||||
int *m_Age;
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
Person p1(18);
|
||||
|
||||
Person p2(20);
|
||||
|
||||
Person p3(23);
|
||||
|
||||
p3 = p2 = p1; //赋值操作
|
||||
|
||||
cout << "p1的年龄为:" << *p1.m_Age << endl;
|
||||
|
||||
cout << "p2的年龄为:" << *p2.m_Age << endl;
|
||||
|
||||
cout << "p3的年龄为:" << *p3.m_Age << endl;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
/*
|
||||
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
int c = 30;
|
||||
|
||||
c = b = a;
|
||||
|
||||
cout << "a= " << a << endl;
|
||||
cout << "b= " << b << endl;
|
||||
cout << "c= " << c << endl;
|
||||
*/
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- p1的年龄为:18
|
||||
- p2的年龄为:18
|
||||
- p3的年龄为:18
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 6. 关系重载运算符
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<string>
|
||||
|
||||
//重载关系运算符
|
||||
|
||||
class Person
|
||||
{
|
||||
public:
|
||||
Person(string name, int age)
|
||||
{
|
||||
m_Name = name;
|
||||
m_Age = age;
|
||||
}
|
||||
|
||||
//重载 == 号
|
||||
bool operator==(Person& p)
|
||||
{
|
||||
if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator!=(Person& p)
|
||||
{
|
||||
if (this->m_Name != p.m_Name && this->m_Age != p.m_Age)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
string m_Name;
|
||||
int m_Age;
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
Person p1("Tom", 17);
|
||||
|
||||
Person p2("Jerry", 18);
|
||||
|
||||
if (p1 == p2)
|
||||
{
|
||||
cout << "p1和p2是相等的!" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "p1和p2是不相等的!" << endl;
|
||||
|
||||
}
|
||||
|
||||
if (p1 != p2)
|
||||
{
|
||||
cout << "p1和p2是不相等的!" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "p1和p2是相等的!" << endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- p1和p2是不相等的!
|
||||
- p1和p2是不相等的!
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 7. 函数调用运算符重载
|
||||
|
||||
① 函数调用运算符()也可以重载。
|
||||
|
||||
② 由于重载后使用的方式非常像函数的调用,因此称为仿函数。
|
||||
|
||||
③ 仿函数没有固定写法,非常灵活。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<string>
|
||||
|
||||
//函数调用运算符重载
|
||||
|
||||
//打印输出类
|
||||
class MyPrint
|
||||
{
|
||||
public:
|
||||
|
||||
//重载函数调用运算符
|
||||
void operator()(string test)
|
||||
{
|
||||
cout << test << endl;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//正常函数
|
||||
void MyPrint02(string test)
|
||||
{
|
||||
cout << test << endl;
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
MyPrint myPrint;
|
||||
|
||||
myPrint("hello world");
|
||||
|
||||
}
|
||||
|
||||
//仿函数非常灵活,没有固定的写法
|
||||
//加法类
|
||||
class MyAdd
|
||||
{
|
||||
public:
|
||||
int operator()(int num1, int num2)
|
||||
{
|
||||
return num1 + num2;
|
||||
}
|
||||
};
|
||||
|
||||
void test02()
|
||||
{
|
||||
MyAdd myadd;
|
||||
int ret = myadd(100,100);
|
||||
cout << "ret = " << ret << endl;
|
||||
|
||||
//匿名函数对象
|
||||
cout << MyAdd()(100, 100) << endl;
|
||||
|
||||
// MyAdd()为创建一个匿名对象,匿名对象的特点为当前行执行完立即释放
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
MyPrint02("hello world"); //由于使用起来非常类似于函数调用,因此称为仿函数
|
||||
|
||||
test02();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- hello world
|
||||
- hello world
|
||||
- ret = 200
|
||||
- 200
|
||||
- 请按任意键继续. . .
|
||||
1287
docs/CPlusPlus-main/25_C++的类中继承.ipynb
Normal file
943
docs/CPlusPlus-main/25_C++的类中继承.md
Normal file
@ -0,0 +1,943 @@
|
||||
# C++的继承
|
||||
|
||||
# 1. 继承简介
|
||||
|
||||
① 继承是面向对象的三大特性之一。
|
||||
|
||||
② 定义类时,下级别的成员除了拥有上一级的共性,还有自己的特性。这个时候,就可以考虑利用继承技术,减少重复代码。
|
||||
|
||||

|
||||
|
||||
## 1.1 普通实现
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<string>
|
||||
|
||||
//打印输出类
|
||||
class Java
|
||||
{
|
||||
public:
|
||||
void header()
|
||||
{
|
||||
cout << "首页、公开课、登陆、注册...(公共头部)" << endl;
|
||||
}
|
||||
void footer()
|
||||
{
|
||||
cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
|
||||
}
|
||||
void left()
|
||||
{
|
||||
cout << "Java、Python、C++....(公共分类列表)" << endl;
|
||||
}
|
||||
void content()
|
||||
{
|
||||
cout << "Java学科视频" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class Python
|
||||
{
|
||||
public:
|
||||
void header()
|
||||
{
|
||||
cout << "首页、公开课、登陆、注册...(公共头部)" << endl;
|
||||
}
|
||||
void footer()
|
||||
{
|
||||
cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
|
||||
}
|
||||
void left()
|
||||
{
|
||||
cout << "Java、Python、C++....(公共分类列表)" << endl;
|
||||
}
|
||||
void content()
|
||||
{
|
||||
cout << "Python学科视频" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class CPP
|
||||
{
|
||||
public:
|
||||
void header()
|
||||
{
|
||||
cout << "首页、公开课、登陆、注册...(公共头部)" << endl;
|
||||
}
|
||||
void footer()
|
||||
{
|
||||
cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
|
||||
}
|
||||
void left()
|
||||
{
|
||||
cout << "Java、Python、C++....(公共分类列表)" << endl;
|
||||
}
|
||||
void content()
|
||||
{
|
||||
cout << "C++学科视频" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
cout << "Java下载视频页面如下:" << endl;
|
||||
Java ja;
|
||||
ja.header();
|
||||
ja.footer();
|
||||
ja.left();
|
||||
ja.content();
|
||||
|
||||
cout << "........................" << endl;
|
||||
cout << "Python下载视频页面如下:" << endl;
|
||||
Python py;
|
||||
py.header();
|
||||
py.footer();
|
||||
py.left();
|
||||
py.content();
|
||||
|
||||
cout << "........................" << endl;
|
||||
cout << "C++下载视频页面如下:" << endl;
|
||||
CPP cpp;
|
||||
cpp.header();
|
||||
cpp.footer();
|
||||
cpp.left();
|
||||
cpp.content();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- Java下载视频页面如下:
|
||||
- 首页、公开课、登陆、注册...(公共头部)
|
||||
- 帮助中心、交流合作、站内地图...(公共底部)
|
||||
- Java、Python、C++....(公共分类列表)
|
||||
- Java学科视频
|
||||
- ........................
|
||||
- Python下载视频页面如下:
|
||||
- 首页、公开课、登陆、注册...(公共头部)
|
||||
- 帮助中心、交流合作、站内地图...(公共底部)
|
||||
- Java、Python、C++....(公共分类列表)
|
||||
- Python学科视频
|
||||
- ........................
|
||||
- C++下载视频页面如下:
|
||||
- 首页、公开课、登陆、注册...(公共头部)
|
||||
- 帮助中心、交流合作、站内地图...(公共底部)
|
||||
- Java、Python、C++....(公共分类列表)
|
||||
- C++学科视频
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 1.2 继承实现
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<string>
|
||||
|
||||
//打印输出类
|
||||
class BasePage
|
||||
{
|
||||
public:
|
||||
void header()
|
||||
{
|
||||
cout << "首页、公开课、登陆、注册...(公共头部)" << endl;
|
||||
}
|
||||
void footer()
|
||||
{
|
||||
cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
|
||||
}
|
||||
void left()
|
||||
{
|
||||
cout << "Java、Python、C++....(公共分类列表)" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
// 继承的好处:减少重复代码
|
||||
// 语法:class 子类:继承方式 父类
|
||||
// 子类 也称为 派生类
|
||||
// 父类 也称为 基类
|
||||
|
||||
//Java页面
|
||||
class Java:public BasePage //继承了BasePage,把BasePage里面的内容全部拿到手了
|
||||
{
|
||||
public:
|
||||
void content()
|
||||
{
|
||||
cout << "Java学科视频" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
//Python页面
|
||||
class Python :public BasePage //继承了BasePage,把BasePage里面的内容全部拿到手了
|
||||
{
|
||||
public:
|
||||
void content()
|
||||
{
|
||||
cout << "Python学科视频" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
//C++页面
|
||||
class CPP :public BasePage //继承了BasePage,把BasePage里面的内容全部拿到手了
|
||||
{
|
||||
public:
|
||||
void content()
|
||||
{
|
||||
cout << "CPP学科视频" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
cout << "Java下载视频页面如下:" << endl;
|
||||
Java ja;
|
||||
ja.header();
|
||||
ja.footer();
|
||||
ja.left();
|
||||
ja.content();
|
||||
|
||||
cout << "........................" << endl;
|
||||
cout << "Python下载视频页面如下:" << endl;
|
||||
Python py;
|
||||
py.header();
|
||||
py.footer();
|
||||
py.left();
|
||||
py.content();
|
||||
|
||||
cout << "........................" << endl;
|
||||
cout << "C++下载视频页面如下:" << endl;
|
||||
CPP cpp;
|
||||
cpp.header();
|
||||
cpp.footer();
|
||||
cpp.left();
|
||||
cpp.content();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- Java下载视频页面如下:
|
||||
- 首页、公开课、登陆、注册...(公共头部)
|
||||
- 帮助中心、交流合作、站内地图...(公共底部)
|
||||
- Java、Python、C++....(公共分类列表)
|
||||
- Java学科视频
|
||||
- ........................
|
||||
- Python下载视频页面如下:
|
||||
- 首页、公开课、登陆、注册...(公共头部)
|
||||
- 帮助中心、交流合作、站内地图...(公共底部)
|
||||
- Java、Python、C++....(公共分类列表)
|
||||
- Python学科视频
|
||||
- ........................
|
||||
- C++下载视频页面如下:
|
||||
- 首页、公开课、登陆、注册...(公共头部)
|
||||
- 帮助中心、交流合作、站内地图...(公共底部)
|
||||
- Java、Python、C++....(公共分类列表)
|
||||
- CPP学科视频
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 2. 三种继承改变权限
|
||||
|
||||
① 继承的语法:class 子类:继承方式 父类
|
||||
|
||||
② 继承方式一共有三种:
|
||||
|
||||
1. 公共继承
|
||||
2. 保护继承
|
||||
3. 私有继承
|
||||
|
||||
③ 不同的继承方式,父类中的变量被继承后,权限相应的得到了改变,如下图所示。
|
||||
|
||||

|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<string>
|
||||
|
||||
//打印输出类
|
||||
class Base1
|
||||
{
|
||||
public:
|
||||
int m_A;
|
||||
protected:
|
||||
int m_B;
|
||||
private:
|
||||
int m_C;
|
||||
};
|
||||
|
||||
//公共继承
|
||||
class Son1:public Base1
|
||||
{
|
||||
public:
|
||||
void func()
|
||||
{
|
||||
m_A = 10; //父类中的公共权限成员 到子类中依然是公共权限
|
||||
m_B = 10; //父类中的保护权限成员 到子类中依然是保护权限
|
||||
//m_C = 10; //父类中的私有权限成员 子类访问不到
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
Son1 s1;
|
||||
s1.m_A = 100; //公共权限,类内能访问,类外也能访问
|
||||
//s1.m_B = 100; //保护权限,类内能访问,类外不能访问
|
||||
}
|
||||
|
||||
//保护继承
|
||||
class Son2:protected Base1
|
||||
{
|
||||
public:
|
||||
void func()
|
||||
{
|
||||
m_A = 10; //父类中的公共权限成员 到子类中变为保护权限
|
||||
m_B = 10; //父类中的保护权限成员 到子类中依然是保护权限
|
||||
//m_C = 10; //父类中的私有权限成员 子类访问不到
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void test02()
|
||||
{
|
||||
Son2 s2;
|
||||
//s2.m_A = 100; //保护权限,类内能访问,类外不能访问
|
||||
//s2.m_B = 100; //保护权限,类内能访问,类外不能访问
|
||||
}
|
||||
|
||||
//私有继承
|
||||
class Son3:private Base1
|
||||
{
|
||||
public:
|
||||
void func()
|
||||
{
|
||||
m_A = 10; //父类中的公共权限成员 到子类中变为私有权限
|
||||
m_B = 10; //父类中的保护权限成员 到子类中变为私有权限
|
||||
//m_C = 10; //父类中的私有权限成员 子类访问不到
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
void test03()
|
||||
{
|
||||
Son3 s3;
|
||||
//s3.m_A = 100; //私有权限,类内能访问,类外不能访问
|
||||
//s3.m_B = 100; //私有权限,类内能访问,类外不能访问
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 3. 继承对象内存
|
||||
|
||||
## 3.1 查询继承对象所占内存
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<string>
|
||||
|
||||
//继承中的对象模型
|
||||
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
int m_A;
|
||||
protected:
|
||||
int m_B;
|
||||
private:
|
||||
int m_C;
|
||||
};
|
||||
|
||||
|
||||
//公共继承
|
||||
class Son:public Base
|
||||
{
|
||||
int m_D;
|
||||
};
|
||||
|
||||
//利用开发人员命令提示工具查看对象模型
|
||||
//跳转盘符→F:
|
||||
//跳转文件路径→cd 具体路径下
|
||||
//查看命令
|
||||
//cl /d1 reportSingleClassLayout查看的类名 "文件名"
|
||||
|
||||
void test01()
|
||||
{
|
||||
//父类中所有非静态成员属性都会被子类继承下去
|
||||
//父类中私有成员属性 是被编译器给隐藏了,因此是访问不到,但是确实被继承下去了
|
||||
cout << "size of Son =" << sizeof(Son) << endl; //16个字节,父类3个int一个12个字节,字节1个int4个字节
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- size of Son =16
|
||||
- 按任意键继续. . .
|
||||
|
||||
## 3.2 VS自带开发工具查询
|
||||
|
||||
① 首先打开visio studio的开发人员命令工具,如下图所示。
|
||||
|
||||

|
||||
|
||||
② 查询visio studio的项目所在地址。
|
||||
|
||||
③ "输入跳转盘符,例如,C:"->"输入项目所在地的地址"->"输入dir(查询项目中文件信息)"
|
||||
|
||||

|
||||
|
||||
② 输入:cl(空格)/d1 reportSingleClassLayout查看的类名 "文件名",可以查看类所占内存空间大小。
|
||||
|
||||

|
||||
|
||||
# 4. 继承构造和析构顺序
|
||||
|
||||
① 继承中,先调用父类构造函数,再调用子类构造函数,析构顺序与构造顺序相反,先调用子类析构函数,再调用父类析构函数。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<string>
|
||||
|
||||
//继承中的构造和析构顺序
|
||||
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
Base()
|
||||
{
|
||||
cout << "Base构造函数!" << endl;
|
||||
}
|
||||
|
||||
~Base()
|
||||
{
|
||||
cout << "Base析构函数!" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
class Son:public Base
|
||||
{
|
||||
public:
|
||||
Son()
|
||||
{
|
||||
cout << "Son构造函数!" << endl;
|
||||
}
|
||||
|
||||
~Son()
|
||||
{
|
||||
cout << "Son析构函数!" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void test01()
|
||||
{
|
||||
//Base b; //创建父类对象只有父类的构造函数、析构函数
|
||||
|
||||
//继承中的构造和析构顺序如下:
|
||||
//先构造父类、再构造子类,析构的顺序与构造的顺序相反
|
||||
Son s;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- Base构造函数!
|
||||
- Son构造函数!
|
||||
- Son析构函数!
|
||||
- Base析构函数!
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 5. 同名成员处理
|
||||
|
||||
① 子类对象可以直接访问到子类中同名成员。
|
||||
|
||||
② 子类对象加作用域可以访问到父类同名成员。
|
||||
|
||||
③ 当子类与父类拥有同名的成员函数,子类会隐藏父类中所有同名成员函数(有参、无参),加作用域才可以访问到父类中同名函数。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<string>
|
||||
|
||||
|
||||
//继承中同名成员处理
|
||||
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
Base()
|
||||
{
|
||||
m_A = 100;
|
||||
}
|
||||
int m_A;
|
||||
|
||||
void func()
|
||||
{
|
||||
cout << "Base - func()调用" << endl;
|
||||
}
|
||||
|
||||
void func(int a)
|
||||
{
|
||||
cout << "Base - func(int a)调用" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class Son:public Base
|
||||
{
|
||||
public:
|
||||
Son()
|
||||
{
|
||||
m_A = 200;
|
||||
}
|
||||
|
||||
void func()
|
||||
{
|
||||
cout << "Son - func()调用" << endl;
|
||||
}
|
||||
|
||||
int m_A;
|
||||
};
|
||||
|
||||
//同名成员属性处理方式
|
||||
void test01()
|
||||
{
|
||||
Son s;
|
||||
cout << "Son 下 m_A=" << s.m_A << endl;
|
||||
//如果通过子类对象访问到父类中同名成员,需要加作用域
|
||||
cout << "Base 下 m_A=" << s.Base::m_A << endl;
|
||||
|
||||
}
|
||||
|
||||
//同名成员函数处理方式
|
||||
void test02()
|
||||
{
|
||||
Son s;
|
||||
s.func(); //直接调用 调用时子类中的同名成员
|
||||
|
||||
//调用父类中同名成员函数
|
||||
s.Base::func();
|
||||
|
||||
//如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏掉父类中所有同名成员函数
|
||||
//如果想访问到父类中被隐藏的同名成员函数,需要加作用域
|
||||
s.Base::func(100);
|
||||
}
|
||||
|
||||
//同名成员函数处理
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- Son 下 m_A=200
|
||||
- Base 下 m_A=100
|
||||
- Son - func()调用
|
||||
- Base - func()调用
|
||||
- Base - func(int a)调用
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 6. 同名静态成员处理
|
||||
|
||||
① 静态成员和非静态成员出现同名,处理方式一致:
|
||||
|
||||
1. 访问子类同名成员,直接访问
|
||||
2. 访问父类同名成员,需要加作用域
|
||||
|
||||
② 加上static关键字后,成员发生变化,成员变成静态成员。
|
||||
|
||||
③ 静态成员变量特点:
|
||||
1. 所有对象都共享同一份数据。
|
||||
2. 编译阶段就分配内存。
|
||||
3. 类内声明,类外初始化。
|
||||
|
||||
④ 静态成员函数特点:
|
||||
1. 只能访问静态成员变量,不能访问非静态成员变量。
|
||||
2. 所有对象都共享同一份函数实例。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//继承中同名静态成员处理方式
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
|
||||
static int m_A; //静态成员类内声明,类外初始化
|
||||
|
||||
static void func()
|
||||
{
|
||||
cout << "Base - static func()" << endl;
|
||||
}
|
||||
|
||||
static void func(int a)
|
||||
{
|
||||
cout << "Base - static func(int a)" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int Base::m_A=100;
|
||||
|
||||
class Son:public Base
|
||||
{
|
||||
public:
|
||||
|
||||
static int m_A;
|
||||
|
||||
static void func()
|
||||
{
|
||||
cout << "Son - static void func()" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int Son::m_A = 200;
|
||||
|
||||
//同名静态成员属性
|
||||
void test01()
|
||||
{
|
||||
//1、通过对象访问
|
||||
Son s;
|
||||
cout << "Son 下 m_A = " << s.m_A << endl;
|
||||
cout << "Base 下 m_A = " << s.Base::m_A << endl;
|
||||
|
||||
//2、通过类名访问
|
||||
cout << "Son 下 m_A = "<< Son::m_A << endl;
|
||||
//第一个::代表通过类名方式访问 第二个::代表访问父类作用域
|
||||
cout << "Base 下 m_A= "<< Son::Base::m_A << endl;
|
||||
}
|
||||
|
||||
void test02()
|
||||
{
|
||||
//1、通过对象访问
|
||||
Son s;
|
||||
s.func();
|
||||
s.Base::func();
|
||||
|
||||
//2、通过类名访问
|
||||
Son::func();
|
||||
Son::Base::func();
|
||||
|
||||
//子类出现和父类同名静态成员函数,也会隐藏掉父类中所有同名成员函数
|
||||
//如何想访问父类中被隐藏同名成员,需要加作用域
|
||||
Son::Base::func(100);
|
||||
}
|
||||
|
||||
//同名成员函数处理
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- Son 下 m_A = 200
|
||||
- Base 下 m_A = 100
|
||||
- Son 下 m_A = 200
|
||||
- Base 下 m_A= 100
|
||||
- Son - static void func()
|
||||
- Base - static func()
|
||||
- Son - static void func()
|
||||
- Base - static func()
|
||||
- Base - static func(int a)
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 7. 多继承语法
|
||||
|
||||
① C++运行一个类继承多个类。
|
||||
|
||||
② 语法:class 子类:继承方式 父类1,继承方式 父类2,.....
|
||||
|
||||
③ 多继承可能会引发父类中有同名成员出现,需要加作用域区分。
|
||||
|
||||
④ C++实际开发中不建议用多继承。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
class Base1
|
||||
{
|
||||
public:
|
||||
|
||||
Base1()
|
||||
{
|
||||
m_A = 100;
|
||||
}
|
||||
|
||||
int m_A;
|
||||
|
||||
};
|
||||
|
||||
class Base2
|
||||
{
|
||||
public:
|
||||
|
||||
Base2()
|
||||
{
|
||||
m_A = 200;
|
||||
}
|
||||
|
||||
int m_A;
|
||||
|
||||
};
|
||||
|
||||
//子类 需要继承Base1和Base2
|
||||
//语法:class 子类:继承方式 父类1,继承方式 父类2,.....
|
||||
class Son:public Base1,public Base2
|
||||
{
|
||||
public:
|
||||
|
||||
Son()
|
||||
{
|
||||
m_C = 300;
|
||||
m_D = 400;
|
||||
}
|
||||
|
||||
int m_C;
|
||||
int m_D;
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
Son s;
|
||||
|
||||
cout << "sizeof(Son):" << sizeof(s) << endl;
|
||||
//当父类中出现同名成员,需要加作用域区分
|
||||
cout << "Base1::m_A = " << s.Base1::m_A << endl;
|
||||
cout << "Base2::m_A = " << s.Base2::m_A << endl;
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- sizeof(Son):16
|
||||
- Base1::m_A = 100
|
||||
- Base2::m_A = 200
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 8. 菱形继承
|
||||
|
||||
## 8.1 菱形继承简介
|
||||
|
||||
① 菱形继承概念:
|
||||
|
||||
1. 两个派生类继承同一个基类
|
||||
2. 又有某个类同时继承两个派生类
|
||||
3. 这种继承被称为菱形继承
|
||||
|
||||
② 羊继承了动物的数据,驼同样继承了动物的数据,当草泥马使用数据是,就会产生二义性。
|
||||
|
||||
③ 草泥马继承自动物的数据继承了两份,其实我们应当清楚,这份数据我们只需要一份就可以。
|
||||
|
||||
④ 菱形继承带来的主要问题是子类继承两份相同的数据,导致资源浪费以及毫无意义。
|
||||
|
||||
⑤ 利用虚继承可以解决菱形继承问题。
|
||||
|
||||

|
||||
|
||||
## 8.2 菱形继承普通方式
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//动物类
|
||||
class Animal
|
||||
{
|
||||
public:
|
||||
int m_Age;
|
||||
};
|
||||
|
||||
//羊类
|
||||
class Sheep:public Animal{};
|
||||
|
||||
//驼类
|
||||
class Tuo:public Animal{};
|
||||
|
||||
//羊驼类
|
||||
class SheepTuo:public Sheep,public Tuo{};
|
||||
|
||||
void test01()
|
||||
{
|
||||
SheepTuo st;
|
||||
|
||||
st.Sheep::m_Age = 18;
|
||||
st.Tuo::m_Age = 28;
|
||||
|
||||
//当出现菱形继承,两个父类拥有相同数据,需要加以作用域区分
|
||||
cout << "st.Sheep::m_Age="<< st.Sheep::m_Age << endl;
|
||||
cout << "st.Tuo::m_Age=" << st.Tuo::m_Age << endl;
|
||||
|
||||
//这份数据我们知道 只有一份就可以,菱形继承导致数据有两份,资源浪费
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- st.Sheep::m_Age=18
|
||||
- st.Tuo::m_Age=28
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 8.3 菱形继承虚继承
|
||||
|
||||
### 8.3.1 菱形继承虚继承方式
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//动物类
|
||||
class Animal
|
||||
{
|
||||
public:
|
||||
int m_Age;
|
||||
};
|
||||
|
||||
//利用虚继承 解决菱形继承的问题
|
||||
//继承之前 加上关键字 virtual 变成 虚继承
|
||||
//虚继承后,Animal类 称为 虚基类
|
||||
|
||||
//羊类
|
||||
class Sheep:virtual public Animal{};
|
||||
|
||||
//驼类
|
||||
class Tuo:virtual public Animal{};
|
||||
|
||||
//羊驼类
|
||||
class SheepTuo:public Sheep,public Tuo{};
|
||||
|
||||
void test01()
|
||||
{
|
||||
SheepTuo st;
|
||||
|
||||
st.Sheep::m_Age = 18;
|
||||
st.Tuo::m_Age = 28;
|
||||
|
||||
//当出现菱形继承,两个父类拥有相同数据,需要加以作用域区分
|
||||
cout << "st.Sheep::m_Age="<< st.Sheep::m_Age << endl;
|
||||
cout << "st.Tuo::m_Age=" << st.Tuo::m_Age << endl;
|
||||
|
||||
//虚继承,多产生一种输出方式(因为上面两个是同一份数据,所以可以不加作用域来区分了)
|
||||
cout << "st.m_Age=" << st.m_Age << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- st.Sheep::m_Age=28
|
||||
- st.Tuo::m_Age=28
|
||||
- st.m_Age=28
|
||||
- 请按任意键继续. . .
|
||||
|
||||
### 8.3.2 菱形继承虚继承VS查询
|
||||
|
||||
① Sheep类和Tuo类继承的都是vbptr,vbptr为虚基类继承指针。
|
||||
1. v - virtual
|
||||
2. b - base
|
||||
3. ptr = pointer
|
||||
|
||||
② 菱形继承并不是继承两份数据,而是继承两份指针,这两个指针会分别指向虚基类表,虚基类表中会记录偏移量,加上这个偏移量,会指向这个唯一的数据。
|
||||
|
||||

|
||||
BIN
docs/CPlusPlus-main/25_C++的类中继承_files/image.png
Normal file
|
After Width: | Height: | Size: 305 KiB |
1217
docs/CPlusPlus-main/26_C++的类中多态.ipynb
Normal file
952
docs/CPlusPlus-main/26_C++的类中多态.md
Normal file
@ -0,0 +1,952 @@
|
||||
# C++的多态
|
||||
|
||||
# 1. 多态简介
|
||||
|
||||
① 多态是C++面向对象三大特性之一。
|
||||
|
||||
② 多态分为两类:
|
||||
|
||||
1. 静态多态:函数重载和运算符重载属于静态多态,复用函数名。
|
||||
2. 动态多态:派生类和虚函数实现运行时多态。
|
||||
|
||||
③ 静态多态和动态多态区别:
|
||||
|
||||
1. 静态多态的函数地址早绑定,编译阶段确定函数地址。
|
||||
2. 动态多态的函数地址晚绑定,运行阶段确定函数地址。
|
||||
|
||||
④ 多态满足条件:
|
||||
|
||||
1. 有继承关系
|
||||
2. 子类重写父类中的虚函数
|
||||
|
||||
⑤ 多态使用条件:
|
||||
|
||||
1. 父类指针或引用指向子类对象
|
||||
|
||||
⑥ 重写:函数返回值类型、函数名、参数列表都完全一致称为重写。
|
||||
|
||||
# 2. 多态地址绑定
|
||||
|
||||
## 2.1 地址早绑定
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//多态
|
||||
|
||||
//动物类
|
||||
class Animal
|
||||
{
|
||||
public:
|
||||
void speak()
|
||||
{
|
||||
cout << "动物在说话" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
//猫类
|
||||
class Cat:public Animal
|
||||
{
|
||||
public:
|
||||
void speak()
|
||||
{
|
||||
cout << "小猫在说话" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
//执行说话的函数
|
||||
//地址早绑定 在编译阶段确定函数地址
|
||||
//如果想执行让猫说话,那么这个函数就不能提前绑定,需要在运行阶段进行绑定,地址晚绑定
|
||||
void doSpeak(Animal &animal) // Animal & animal = cat
|
||||
{
|
||||
animal.speak();
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
Cat cat;
|
||||
doSpeak(cat);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 动物在说话
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 2.2 地址晚绑定虚函数
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//多态
|
||||
|
||||
//动物类
|
||||
class Animal
|
||||
{
|
||||
public:
|
||||
virtual void speak()
|
||||
{
|
||||
cout << "动物在说话" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
//猫类
|
||||
class Cat:public Animal
|
||||
{
|
||||
public:
|
||||
//重写 函数返回值类型、函数名、参数列表都完全相同才叫重写
|
||||
void speak() //子类virtual可写可不写,也可以写 virtual void speak()
|
||||
{
|
||||
cout << "小猫在说话" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
//狗类
|
||||
class Dog:public Animal
|
||||
{
|
||||
public:
|
||||
virtual void speak()
|
||||
{
|
||||
cout << "小狗在说话" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
//执行说话的函数
|
||||
//地址早绑定 在编译阶段确定函数地址
|
||||
//如果想执行让猫说话,那么这个函数就不能提前绑定,需要在运行阶段进行绑定,地址晚绑定
|
||||
|
||||
//动态多态满足条件
|
||||
//1、有继承关系
|
||||
//2、子类重写父类的虚函数
|
||||
|
||||
//动态多态使用
|
||||
//父类的引用或指针指向子类对象
|
||||
|
||||
void doSpeak(Animal &animal) // Animal & animal = cat
|
||||
{
|
||||
animal.speak();
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
Cat cat;
|
||||
doSpeak(cat);
|
||||
|
||||
Dog dog;
|
||||
doSpeak(dog);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 小猫在说话
|
||||
- 小狗在说话
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 3. 多态的原理剖析
|
||||
|
||||
① 当没有发生重写时,子类中的虚函数表内部为父类的虚函数地址。
|
||||
|
||||

|
||||
|
||||
② 当子类重写父类的虚函数,子类中的虚函数表内部会替换成子类的虚函数地址。
|
||||
|
||||

|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//多态
|
||||
|
||||
//动物类
|
||||
class Animal
|
||||
{
|
||||
public: //如果是虚函数,那么类里面存了一个指针,类占4个字节
|
||||
virtual void speak() //如果是非静态成员函数void speak(),那么函数不在类上,空类占1个字节空间
|
||||
{
|
||||
cout << "动物在说话" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
//猫类
|
||||
class Cat:public Animal
|
||||
{
|
||||
public:
|
||||
|
||||
void speak()
|
||||
{
|
||||
cout << "小猫在说话" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
//狗类
|
||||
class Dog:public Animal
|
||||
{
|
||||
public:
|
||||
virtual void speak()
|
||||
{
|
||||
cout << "小狗在说话" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
//执行说话的函数
|
||||
//地址早绑定 在编译阶段确定函数地址
|
||||
//如果想执行让猫说话,那么这个函数就不能提前绑定,需要在运行阶段进行绑定,地址晚绑定
|
||||
|
||||
//动态多态满足条件
|
||||
//1、有继承关系
|
||||
//2、子类重写父类的虚函数
|
||||
|
||||
//动态多态使用
|
||||
//父类的引用或指针指向子类对象
|
||||
|
||||
void doSpeak(Animal &animal) // Animal & animal = cat
|
||||
{
|
||||
animal.speak();
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
Cat cat;
|
||||
doSpeak(cat);
|
||||
|
||||
Dog dog;
|
||||
doSpeak(dog);
|
||||
}
|
||||
|
||||
void test02()
|
||||
{
|
||||
cout << "sizeof Animal = " << sizeof(Animal) << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
//test01();
|
||||
test02();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- sizeof Animal = 4
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 4. 纯虚函数和抽象类
|
||||
|
||||
① 在多态中,通常父类中虚函数的实现时毫无意义的,主要都是调用子类重写的内容。因此,可以将虚函数改为纯虚函数。
|
||||
|
||||
② 纯虚函数语法:virtual 返回值类型 函数名 (参数列表) = 0;
|
||||
|
||||
③ 当类中有了纯虚函数,这个类也称为抽象类。
|
||||
|
||||
④ 抽象类特点:
|
||||
|
||||
1. 无法实例化对象
|
||||
2. 子类必须重写抽象类中的纯虚函数,否则也属于抽象类。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//纯虚函数和抽象类
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
//纯虚函数
|
||||
//只要有一个纯虚函数,这个类称为抽象类
|
||||
//抽象类特点:
|
||||
//1、无法实例化对象
|
||||
//2、抽象类的子类 必须要重写父类中的纯虚函数,否则也属于抽象类
|
||||
virtual void func() = 0;
|
||||
};
|
||||
|
||||
class Son : public Base
|
||||
{
|
||||
public:
|
||||
virtual void func()
|
||||
{
|
||||
cout << "func函数调用" << endl;
|
||||
}
|
||||
};
|
||||
void test01()
|
||||
{
|
||||
//Base b; //抽象类是无法实例化对象
|
||||
//new Base; //抽象类是无法实例化对象
|
||||
|
||||
//Son s; //子类中必须重写父类中的纯虚函数,否则无法实例化对象
|
||||
|
||||
Base* base = new Son;
|
||||
base->func();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- func函数调用
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 5. 虚析构和纯虚析构
|
||||
|
||||
① 多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用子类的析构代码。
|
||||
|
||||
② 解决方式:将父类中的析构函数改为虚析构或者纯虚析构。
|
||||
|
||||
③ 虚析构和纯虚析构共性:
|
||||
|
||||
1. 可以解决父类指针释放子类对象
|
||||
2. 都需要有具体的函数实现
|
||||
|
||||
④ 虚析构语法:virtual.类名(){}
|
||||
|
||||
⑤ 纯虚析构语法:
|
||||
|
||||
1. virtual~类名 = 0;
|
||||
2. 类名::~类名(){}
|
||||
|
||||
① 虚析构或纯虚析构就是用来解决通过父类指针释放子类对象。
|
||||
|
||||
② 如果子类中没有堆区数据,可以不写为虚析构或纯虚析构。
|
||||
|
||||
③ 拥有纯虚析构函数的类也属于抽象类。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<string>
|
||||
|
||||
//纯虚函数和纯虚机构
|
||||
class Animal
|
||||
{
|
||||
public:
|
||||
Animal()
|
||||
{
|
||||
cout << "Animal构造函数调用" << endl;
|
||||
}
|
||||
|
||||
//纯虚函数
|
||||
virtual void speak() = 0;
|
||||
|
||||
/*
|
||||
//利用虚析构可以解决,父类指针释放子类对象时不干净的问题
|
||||
virtual ~Animal()
|
||||
{
|
||||
cout << "Animal析构函数调用" << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
//纯虚析构 需要声明也需要实现
|
||||
//有了纯虚析构之后,这个类也属于抽象类,无法实例化对象
|
||||
virtual ~Animal() = 0;
|
||||
|
||||
};
|
||||
|
||||
Animal::~Animal()
|
||||
{
|
||||
cout << "Animal纯虚析构函数调用" << endl;
|
||||
}
|
||||
|
||||
|
||||
class Cat : public Animal
|
||||
{
|
||||
public:
|
||||
Cat(string name)
|
||||
{
|
||||
cout << "Cat构造函数调用" << endl;
|
||||
m_Name = new string(name);
|
||||
}
|
||||
|
||||
virtual void speak()
|
||||
{
|
||||
cout << *m_Name << "小猫在说话" << endl;
|
||||
}
|
||||
|
||||
~Cat()
|
||||
{
|
||||
if (m_Name != NULL)
|
||||
{
|
||||
cout << "Cat析构函数调用" << endl;
|
||||
delete m_Name;
|
||||
m_Name = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
string* m_Name;
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
Animal* animal = new Cat("Tom");
|
||||
animal->speak();
|
||||
//父类指针在析构时候,不会调用子类中析构函数,导致子类如果有堆区属性,出现内存泄露
|
||||
delete animal;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- Animal构造函数调用
|
||||
- Cat构造函数调用
|
||||
- Tom小猫在说话
|
||||
- Cat析构函数调用
|
||||
- Animal纯虚析构函数调用
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 6. 计算器
|
||||
|
||||
① 案例描述:分布利用普通写法和多态技术,设计实现两个操作数进行运算的计算器类。
|
||||
|
||||
② 多态的优点:
|
||||
1. 代码组织结构清晰。
|
||||
2. 多可读性强。
|
||||
3. 利于前期和后期的扩展以及维护。
|
||||
|
||||
③ C++开发提倡利用多态设计程序架构,因为多态优点很多。
|
||||
|
||||
## 6.1 普通写法实现多态
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<string>
|
||||
|
||||
//普通方法实现多态
|
||||
|
||||
class Calculator
|
||||
{
|
||||
public:
|
||||
int getResult(string oper)
|
||||
{
|
||||
if (oper == "+")
|
||||
{
|
||||
return m_Num1 + m_Num2;
|
||||
}
|
||||
else if (oper == "-")
|
||||
{
|
||||
return m_Num1 - m_Num2;
|
||||
}
|
||||
else if (oper == "*")
|
||||
{
|
||||
return m_Num1 * m_Num2;
|
||||
}
|
||||
//如果想扩展新的功能,需要修改源码
|
||||
//在真的开发中 提倡 开闭原则
|
||||
//开闭原则:对扩展进行开发,对修改进行关闭
|
||||
}
|
||||
int m_Num1; //操作数1
|
||||
int m_Num2; //操作数2
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
//创建计算器对象
|
||||
Calculator c;
|
||||
c.m_Num1 = 10;
|
||||
c.m_Num2 = 10;
|
||||
|
||||
cout << c.m_Num1 << "+" << c.m_Num2 << "=" << c.getResult("+") << endl;
|
||||
|
||||
cout << c.m_Num1 << "-" << c.m_Num2 << "=" << c.getResult("-") << endl;
|
||||
|
||||
cout << c.m_Num1 << "*" << c.m_Num2 << "=" << c.getResult("*") << endl;
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 10+10=20
|
||||
- 10-10=0
|
||||
- 10*10=100
|
||||
- 请按任意键继续. . .
|
||||
|
||||
## 6.2 多态设计程序架构
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<string>
|
||||
|
||||
//普通方法实现多态
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//多态
|
||||
|
||||
class AbstractCalculator
|
||||
{
|
||||
public:
|
||||
virtual int getResult()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int m_Num1;
|
||||
int m_Num2;
|
||||
|
||||
};
|
||||
|
||||
//加法计算器类
|
||||
class AddCalculator : public AbstractCalculator
|
||||
{
|
||||
public:
|
||||
int getResult()
|
||||
{
|
||||
return m_Num1 + m_Num2;
|
||||
}
|
||||
};
|
||||
|
||||
//减法计算器类
|
||||
class SubCalculator : public AbstractCalculator
|
||||
{
|
||||
public:
|
||||
int getResult()
|
||||
{
|
||||
return m_Num1 - m_Num2;
|
||||
}
|
||||
};
|
||||
|
||||
//乘法计算器类
|
||||
class MulCalculator : public AbstractCalculator
|
||||
{
|
||||
public:
|
||||
int getResult()
|
||||
{
|
||||
return m_Num1 * m_Num2;
|
||||
}
|
||||
};
|
||||
|
||||
void test02()
|
||||
{
|
||||
//多态使用条件
|
||||
//父类指针或者引用指向子类对象
|
||||
AbstractCalculator* abc = new AddCalculator; //这里用的是父类指针指向子类对象
|
||||
abc->m_Num1 = 100;
|
||||
abc->m_Num2 = 200;
|
||||
|
||||
cout << abc->m_Num1 << "+" << abc->m_Num2 << "=" << abc->getResult() << endl;
|
||||
//用完后记得销毁
|
||||
delete abc;
|
||||
|
||||
//减法运算
|
||||
abc = new SubCalculator; //指针并没有释放
|
||||
abc->m_Num1 = 100;
|
||||
abc->m_Num2 = 200;
|
||||
|
||||
cout << abc->m_Num1 << "-" << abc->m_Num2 << "=" << abc->getResult() << endl;
|
||||
//用完后记得销毁
|
||||
delete abc;
|
||||
|
||||
//乘法运算
|
||||
abc = new MulCalculator; //指针并没有释放
|
||||
abc->m_Num1 = 100;
|
||||
abc->m_Num2 = 200;
|
||||
|
||||
cout << abc->m_Num1 << "*" << abc->m_Num2 << "=" << abc->getResult() << endl;
|
||||
//用完后记得销毁
|
||||
delete abc;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test02();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 100+200=300
|
||||
- 100-200=-100
|
||||
- 100*200=20000
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 7. 制作饮品
|
||||
|
||||
① 案例描述:制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料
|
||||
|
||||
② 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶。
|
||||
|
||||

|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
class AbstractDring
|
||||
{
|
||||
public:
|
||||
//煮水
|
||||
virtual void Boil() = 0;
|
||||
|
||||
//冲泡
|
||||
virtual void Brew() = 0;
|
||||
|
||||
//倒入杯中
|
||||
virtual void PourInCup() = 0;
|
||||
|
||||
//加入辅料
|
||||
virtual void PutSomething() = 0;
|
||||
|
||||
//制作饮品
|
||||
void makeDrink()
|
||||
{
|
||||
Boil();
|
||||
Brew();
|
||||
PourInCup();
|
||||
PutSomething();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//制作咖啡
|
||||
class Coffee :public AbstractDring
|
||||
{
|
||||
public:
|
||||
//煮水
|
||||
virtual void Boil()
|
||||
{
|
||||
cout << "煮农夫山泉" << endl;
|
||||
}
|
||||
|
||||
//冲泡
|
||||
virtual void Brew()
|
||||
{
|
||||
cout << "冲泡咖啡" << endl;
|
||||
}
|
||||
|
||||
//倒入杯中
|
||||
virtual void PourInCup()
|
||||
{
|
||||
cout << "倒入杯中" << endl;
|
||||
}
|
||||
|
||||
//加入辅料
|
||||
virtual void PutSomething()
|
||||
{
|
||||
cout << "加入糖和牛奶" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
//制作茶叶
|
||||
class Tea :public AbstractDring
|
||||
{
|
||||
public:
|
||||
//煮水
|
||||
virtual void Boil()
|
||||
{
|
||||
cout << "煮茶叶" << endl;
|
||||
}
|
||||
|
||||
//冲泡
|
||||
virtual void Brew()
|
||||
{
|
||||
cout << "冲泡茶叶" << endl;
|
||||
}
|
||||
|
||||
//倒入杯中
|
||||
virtual void PourInCup()
|
||||
{
|
||||
cout << "倒入杯中" << endl;
|
||||
}
|
||||
|
||||
//加入辅料
|
||||
virtual void PutSomething()
|
||||
{
|
||||
cout << "加入枸杞" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
//制作函数
|
||||
void doWork(AbstractDring* abs)
|
||||
{
|
||||
abs->makeDrink();
|
||||
delete abs; //释放
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
//制作咖啡
|
||||
doWork(new Coffee);
|
||||
cout << "----------------" << endl;
|
||||
doWork(new Tea);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 煮农夫山泉
|
||||
- 冲泡咖啡
|
||||
- 倒入杯中
|
||||
- 加入糖和牛奶
|
||||
- $----------------$
|
||||
- 煮茶叶
|
||||
- 冲泡茶叶
|
||||
- 倒入杯中
|
||||
- 加入枸杞
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 8. 电脑组装
|
||||
|
||||
案例描述:电脑用主要组成部件为CPU(用于计算),显卡(用于显示),内存条(用于存储),将每个零件封装出抽象基类;并且提供不同的厂商生产不同的零件,例如intel厂商和Lennovo厂商;创建电脑类提供电脑工作的函数,并且调用每个零件工作的接口。测试时组装三台不同的电脑进行工作。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<string>
|
||||
|
||||
//抽象不同零件类
|
||||
//抽象CPU类
|
||||
class CPU
|
||||
{
|
||||
public:
|
||||
//抽象的计算函数
|
||||
virtual void calculate() = 0;
|
||||
};
|
||||
|
||||
//抽象显卡类
|
||||
class VideoCard
|
||||
{
|
||||
public:
|
||||
//抽象的显示函数
|
||||
virtual void display() = 0;
|
||||
};
|
||||
|
||||
//抽象内存条类
|
||||
class Memory
|
||||
{
|
||||
public:
|
||||
//抽象的存储函数
|
||||
virtual void storage() = 0;
|
||||
};
|
||||
|
||||
//电脑类
|
||||
class Computer
|
||||
{
|
||||
public:
|
||||
Computer(CPU* cpu, VideoCard* vc, Memory* mem)
|
||||
{
|
||||
m_cpu = cpu;
|
||||
m_vc = vc;
|
||||
m_mem = mem;
|
||||
}
|
||||
|
||||
//提供工作的函数
|
||||
void work()
|
||||
{
|
||||
m_cpu->calculate();
|
||||
m_vc->display();
|
||||
m_mem->storage();
|
||||
}
|
||||
|
||||
//提供析构函数 释放3个电脑零件
|
||||
~Computer()
|
||||
{
|
||||
if (m_cpu != NULL)
|
||||
{
|
||||
delete m_cpu;
|
||||
m_cpu = NULL;
|
||||
}
|
||||
|
||||
if (m_vc != NULL)
|
||||
{
|
||||
delete m_vc;
|
||||
m_vc = NULL;
|
||||
}
|
||||
|
||||
if (m_mem != NULL)
|
||||
{
|
||||
delete m_mem;
|
||||
m_mem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
CPU* m_cpu; //CPU的零件指针
|
||||
VideoCard* m_vc; //显卡零件指针
|
||||
Memory* m_mem; //内存条零件指针
|
||||
};
|
||||
|
||||
//具体厂商
|
||||
//Intel厂商
|
||||
class IntelCPU : public CPU
|
||||
{
|
||||
public:
|
||||
virtual void calculate()
|
||||
{
|
||||
cout << "Intel的CPU开始计算了!" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class IntelVideoCard : public VideoCard
|
||||
{
|
||||
public:
|
||||
virtual void display()
|
||||
{
|
||||
cout << "Intel的显卡开始计算了!" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class IntelMemory : public Memory
|
||||
{
|
||||
public:
|
||||
virtual void storage()
|
||||
{
|
||||
cout << "Intel的内存条开始存储了!" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
//Lenovo厂商
|
||||
class LenovoCPU : public CPU
|
||||
{
|
||||
public:
|
||||
virtual void calculate()
|
||||
{
|
||||
cout << "Lenovo的CPU开始计算了!" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class LenovoVideoCard : public VideoCard
|
||||
{
|
||||
public:
|
||||
virtual void display()
|
||||
{
|
||||
cout << "Lenovo的显卡开始计算了!" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class LenovoMemory : public Memory
|
||||
{
|
||||
public:
|
||||
virtual void storage()
|
||||
{
|
||||
cout << "Lenovo的内存条开始存储了!" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
//第一台电脑零件
|
||||
CPU* intelCpu = new IntelCPU;
|
||||
VideoCard* intelCard = new IntelVideoCard;
|
||||
Memory* intelMem = new IntelMemory;
|
||||
|
||||
cout << "第一台电脑开始工作:" << endl;
|
||||
//创建第一台电脑
|
||||
Computer* computer1 = new Computer(intelCpu, intelCard, intelMem);
|
||||
computer1->work();
|
||||
delete computer1;
|
||||
|
||||
cout << "---------" << endl;
|
||||
cout << "第二台电脑开始工作:" << endl;
|
||||
//创建第二台电脑
|
||||
Computer* computer2 = new Computer(new LenovoCPU, new LenovoVideoCard, new LenovoMemory);
|
||||
computer2->work();
|
||||
delete computer2;
|
||||
|
||||
cout << "---------" << endl;
|
||||
cout << "第三台电脑开始工作:" << endl;
|
||||
//创建第三台电脑
|
||||
Computer* computer3 = new Computer(new IntelCPU, new LenovoVideoCard, new LenovoMemory);
|
||||
computer3->work();
|
||||
delete computer3;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 第一台电脑开始工作:
|
||||
- Intel的CPU开始计算了!
|
||||
- Intel的显卡开始计算了!
|
||||
- Intel的内存条开始存储了!
|
||||
- $---------$
|
||||
- 第二台电脑开始工作:
|
||||
- Lenovo的CPU开始计算了!
|
||||
- Lenovo的显卡开始计算了!
|
||||
- Lenovo的内存条开始存储了!
|
||||
- $---------$
|
||||
- 第三台电脑开始工作:
|
||||
- Intel的CPU开始计算了!
|
||||
- Lenovo的显卡开始计算了!
|
||||
- Lenovo的内存条开始存储了!
|
||||
- 请按任意键继续. . .
|
||||
BIN
docs/CPlusPlus-main/26_C++的类中多态_files/image.png
Normal file
|
After Width: | Height: | Size: 1005 KiB |
448
docs/CPlusPlus-main/27_C++的文件操作.ipynb
Normal file
293
docs/CPlusPlus-main/27_C++的文件操作.md
Normal file
@ -0,0 +1,293 @@
|
||||
# C++的文件操作
|
||||
|
||||
# 1. 文件操作简介
|
||||
|
||||
① 程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放。
|
||||
|
||||
② 通过文件可以将数据持久化。
|
||||
|
||||
③ C++中对文件操作需要包含头文件<fstream>
|
||||
|
||||
④ 文件类型分为两种:
|
||||
|
||||
1. 文本文件:文件以文本的ASCII码形式存储在计算机中。
|
||||
2. 二进制文件:文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们。
|
||||
|
||||
⑤ 操作文件的三大类
|
||||
|
||||
1. ofstream:写操作
|
||||
2. ifstream:读操作
|
||||
3. fstream:读写操作
|
||||
|
||||
⑥ 文件打开方式可以配合使用,利用|操作符。
|
||||
|
||||
1. 例如,用二进制方式写文件 ios:: binary | ios:: out
|
||||
|
||||

|
||||
|
||||
# 2. 文本文件--写文件
|
||||
|
||||
① 写文件步骤如下:
|
||||
|
||||
1. 包含头文件 #include $<fstream>$
|
||||
2. 创建流对象 ofstream ofs;
|
||||
3. 打开文件 ofs.open("文件路径",打开方式);
|
||||
4. 关闭文件 ofs<<"写入数据";
|
||||
5. 关闭文件 ofs.close();
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<fstream> //头文件包含
|
||||
|
||||
//文本文件 写文件
|
||||
|
||||
void test01()
|
||||
{
|
||||
//1、包含头文件 fstream
|
||||
|
||||
//2、创建流文件
|
||||
|
||||
ofstream ofs; //创建流对象
|
||||
|
||||
//3、指定打开方式
|
||||
ofs.open("test.txt", ios::out); //当没有指定某盘路径时,创建的文件在该项目文件的路径下
|
||||
|
||||
//4、写内容
|
||||
ofs << "姓名:张三" << endl;
|
||||
ofs << "性别:男" << endl;
|
||||
ofs << "年龄:18" << endl;
|
||||
|
||||
//5、关闭文件
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||

|
||||
|
||||
# 3. 文本文件--读操作
|
||||
|
||||
① 读文件与写文件步骤相似,但是读取方式相对比较多。
|
||||
|
||||
② 读文件步骤如下:
|
||||
|
||||
1. 包含头文件 #include$<fstream>$
|
||||
2. 创建流对象 ifstream ifs;
|
||||
3. 打开文件并判断文件是否成功打开 ifs.open("文件路径",打开方式);
|
||||
4. 四种方式读取
|
||||
5. 关闭文件 ifs.close();
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<fstream>
|
||||
#include<string>
|
||||
|
||||
//文本文件 读文件
|
||||
|
||||
void test01()
|
||||
{
|
||||
//1、包含头文件 fstream
|
||||
|
||||
//2、创建流文件
|
||||
|
||||
ifstream ifs; //创建流对象
|
||||
|
||||
//3、打开文件,并且判断是否打开成功
|
||||
ifs.open("test.txt", ios::in);
|
||||
|
||||
if (!ifs.is_open())
|
||||
{
|
||||
cout << "文件打开失败" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
//4、读数据
|
||||
|
||||
/*
|
||||
//第一种
|
||||
char buf[1024] = { 0 }; //字符数组初始化全为0
|
||||
while (ifs >> buf) //一行一行数据读,存到buf里,当读不到数据的时候,返回False,退出循环
|
||||
{
|
||||
cout << buf << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
//第二种
|
||||
char buf[1024] = { 0 };
|
||||
while (ifs.getline(buf, sizeof(buf))) //第一个参数为数据放到哪里(地址),第二个参数为最多要读多少个字节数
|
||||
{
|
||||
cout << buf << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
//第三种
|
||||
string buf;
|
||||
while (getline(ifs,buf))
|
||||
{
|
||||
cout << buf << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
//第四种
|
||||
char c;
|
||||
while ((c = ifs.get()) != EOF) //每一次读取一个字符,字符放入c
|
||||
{ //EOF表示读取到文件尾
|
||||
cout << c;
|
||||
}
|
||||
|
||||
//5、关闭文件
|
||||
ifs.close();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 姓名:张三
|
||||
- 性别:男
|
||||
- 年龄:18
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 4. 二进制文件--写文件
|
||||
|
||||
① 以二进制的方式对文件进行读、写操作,打开方式要指定为 ios::binary
|
||||
|
||||
② 二进制方式写文件主要利用流对象调用成员函数write,函数原型:ostream write(const char * buffer,int len)
|
||||
|
||||
③ 参数解释:字符指针buffer指向内存中一段内存空间,len是读写的字节数。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<fstream>
|
||||
|
||||
//二进制文件 写文件
|
||||
|
||||
class Person
|
||||
{
|
||||
public:
|
||||
char m_Name[64]; //姓名
|
||||
int m_Age; //年龄
|
||||
//写字符串的时候最好不要用C++的string,有可能出现问题,最好用C的数组写字符串,因为它底层是用C写的
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
//1、包含头文件
|
||||
|
||||
//2、创建流文件
|
||||
ofstream ofs;
|
||||
|
||||
|
||||
//3、打开文件
|
||||
ofs.open("person.txt", ios::out | ios::binary); //二进制的方式写文件
|
||||
|
||||
//ofstream ofs.open("person.txt",ios::out | ios::binary) 也可以两步合成一步
|
||||
|
||||
//4、写文件
|
||||
Person p = { "张三",18 };
|
||||
ofs.write((const char*)&p, sizeof(Person)); //对p取地址,然后强转为常量指针
|
||||
|
||||
//5、关闭文件
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
# 5. 二进制文件--读文件
|
||||
|
||||
① 二进制方式读文件主要利用流对象调用成员函数read。
|
||||
|
||||
② 函数原型:istream& read(char *buffer,int len);
|
||||
|
||||
③ 参数解释:字符串buffer指向内存中一段内存空间,len是读写的字节数。
|
||||
|
||||
|
||||
```python
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include<fstream>
|
||||
|
||||
//二进制文件 读文件
|
||||
|
||||
class Person
|
||||
{
|
||||
public:
|
||||
char m_Name[64]; //姓名
|
||||
int m_Age; //年龄
|
||||
//写字符串的时候最好不要用C++的string,有可能出现问题,最好用C的数组写字符串,因为它底层是用C写的
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
//1、包含头文件
|
||||
|
||||
//2、创建流对象
|
||||
ifstream ifs;
|
||||
|
||||
//3、打开文件
|
||||
ifs.open("person.txt", ios::in | ios::binary); //二进制的方式读文件
|
||||
|
||||
if (!ifs.is_open())
|
||||
{
|
||||
cout << "文件打开失败" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
//4、写文件
|
||||
Person p;
|
||||
ifs.read((char*)&p, sizeof(Person));
|
||||
|
||||
cout << "姓名:" << p.m_Name << " 年龄:" << p.m_Name << endl;
|
||||
|
||||
//5、关闭文件
|
||||
ifs.close();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 姓名:张三 年龄:张三
|
||||
- 请按任意键继续. . .
|
||||
BIN
docs/CPlusPlus-main/27_C++的文件操作_files/image.png
Normal file
|
After Width: | Height: | Size: 301 KiB |
2101
docs/CPlusPlus-main/28_C++的模板.ipynb
Normal file
1596
docs/CPlusPlus-main/28_C++的模板.md
Normal file
5593
docs/CPlusPlus-main/29_C++的STL.ipynb
Normal file
4372
docs/CPlusPlus-main/29_C++的STL.md
Normal file
BIN
docs/CPlusPlus-main/29_C++的STL_files/image.png
Normal file
|
After Width: | Height: | Size: 182 KiB |
176
docs/CPlusPlus-main/30_C++的函数对象.ipynb
Normal file
@ -0,0 +1,176 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的函数对象"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 基本概念"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 重载函数调用操作符的类,其对象常称为函数对象。\n",
|
||||
"\n",
|
||||
"② 函数对象使用重载的()时,行为类似函数调用,也叫仿函数。\n",
|
||||
"\n",
|
||||
"③ 函数对象(仿函数)是一个类,不是一个函数。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 2. 特点"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 函数对象在使用时,可以像普通函数那样调用,可以有参数。\n",
|
||||
"\n",
|
||||
"② 函数对象超出普通函数的概念,函数对象可以有自己的状态。\n",
|
||||
"\n",
|
||||
"③ 函数对象可以作为参数传递。\n",
|
||||
"\n",
|
||||
"④ 仿函数写法是非常灵活的,可以作为参数进行传递。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include<iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"\n",
|
||||
"class MyAdd\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" int operator()(int v1, int v2)\n",
|
||||
" {\n",
|
||||
" return v1 + v2;\n",
|
||||
" }\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"//1、函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" MyAdd myAdd;\n",
|
||||
" cout << myAdd(10,10) << endl;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"//2、函数对象超出普通函数的概念,函数对象可以有自己的状态\n",
|
||||
"class MyPrint\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" MyPrint()\n",
|
||||
" {\n",
|
||||
" this->count = 0;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" void operator()(string test)\n",
|
||||
" {\n",
|
||||
" cout << test << endl;\n",
|
||||
" this->count++;\n",
|
||||
" }\n",
|
||||
" int count; //内部自己状态\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"void test02()\n",
|
||||
"{\n",
|
||||
" MyPrint myPrint;\n",
|
||||
" myPrint(\"hellow world\");\n",
|
||||
" myPrint(\"hellow world\");\n",
|
||||
" myPrint(\"hellow world\");\n",
|
||||
" myPrint(\"hellow world\");\n",
|
||||
"\n",
|
||||
" cout << \"myPrint调用次数为:\" << myPrint.count << endl;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"//3、函数对象可以作为参数传递\n",
|
||||
"\n",
|
||||
"void doPrint(MyPrint &mp, string test)\n",
|
||||
"{\n",
|
||||
" mp(test);\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"void test03()\n",
|
||||
"{\n",
|
||||
" MyPrint myPrint;\n",
|
||||
" doPrint(myPrint,\"hellow world\");\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main() \n",
|
||||
"{\n",
|
||||
" test01();\n",
|
||||
" test02();\n",
|
||||
" test03();\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果:\n",
|
||||
" - 20\n",
|
||||
" - hellow world\n",
|
||||
" - hellow world\n",
|
||||
" - hellow world\n",
|
||||
" - hellow world\n",
|
||||
" - myPrint调用次数为:4\n",
|
||||
" - hellow world\n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
103
docs/CPlusPlus-main/30_C++的函数对象.md
Normal file
@ -0,0 +1,103 @@
|
||||
# C++的函数对象
|
||||
|
||||
# 1. 基本概念
|
||||
|
||||
① 重载函数调用操作符的类,其对象常称为函数对象。
|
||||
|
||||
② 函数对象使用重载的()时,行为类似函数调用,也叫仿函数。
|
||||
|
||||
③ 函数对象(仿函数)是一个类,不是一个函数。
|
||||
|
||||
# 2. 特点
|
||||
|
||||
① 函数对象在使用时,可以像普通函数那样调用,可以有参数。
|
||||
|
||||
② 函数对象超出普通函数的概念,函数对象可以有自己的状态。
|
||||
|
||||
③ 函数对象可以作为参数传递。
|
||||
|
||||
④ 仿函数写法是非常灵活的,可以作为参数进行传递。
|
||||
|
||||
|
||||
```python
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
class MyAdd
|
||||
{
|
||||
public:
|
||||
int operator()(int v1, int v2)
|
||||
{
|
||||
return v1 + v2;
|
||||
}
|
||||
};
|
||||
|
||||
//1、函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
|
||||
void test01()
|
||||
{
|
||||
MyAdd myAdd;
|
||||
cout << myAdd(10,10) << endl;
|
||||
}
|
||||
|
||||
//2、函数对象超出普通函数的概念,函数对象可以有自己的状态
|
||||
class MyPrint
|
||||
{
|
||||
public:
|
||||
MyPrint()
|
||||
{
|
||||
this->count = 0;
|
||||
}
|
||||
|
||||
void operator()(string test)
|
||||
{
|
||||
cout << test << endl;
|
||||
this->count++;
|
||||
}
|
||||
int count; //内部自己状态
|
||||
};
|
||||
|
||||
void test02()
|
||||
{
|
||||
MyPrint myPrint;
|
||||
myPrint("hellow world");
|
||||
myPrint("hellow world");
|
||||
myPrint("hellow world");
|
||||
myPrint("hellow world");
|
||||
|
||||
cout << "myPrint调用次数为:" << myPrint.count << endl;
|
||||
}
|
||||
|
||||
//3、函数对象可以作为参数传递
|
||||
|
||||
void doPrint(MyPrint &mp, string test)
|
||||
{
|
||||
mp(test);
|
||||
}
|
||||
|
||||
void test03()
|
||||
{
|
||||
MyPrint myPrint;
|
||||
doPrint(myPrint,"hellow world");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 20
|
||||
- hellow world
|
||||
- hellow world
|
||||
- hellow world
|
||||
- hellow world
|
||||
- myPrint调用次数为:4
|
||||
- hellow world
|
||||
- 请按任意键继续. . .
|
||||
210
docs/CPlusPlus-main/31_C++的谓词.ipynb
Normal file
@ -0,0 +1,210 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的谓词"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 简介"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 返回bool类型的仿函数称为谓词。\n",
|
||||
"\n",
|
||||
"② 如果operator()接受一个参数,那么叫做一元谓词。\n",
|
||||
"\n",
|
||||
"③ 如果operator()接受两个参数,那么叫做二元谓词。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 2. 一元谓词"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include<iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include<vector>\n",
|
||||
"#include<algorithm>\n",
|
||||
"\n",
|
||||
"//仿函数 返回值类型是bool数据类型,称为谓词\n",
|
||||
"//一元谓词\n",
|
||||
"class GreaterFive\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" bool operator()(int val)\n",
|
||||
" {\n",
|
||||
" return val > 5;\n",
|
||||
" }\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" vector<int>v;\n",
|
||||
" for (int i = 0; i < 10; i++)\n",
|
||||
" {\n",
|
||||
" v.push_back(i);\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" //查找容器中,有没有大于5的数字\n",
|
||||
" //GreaterFive() 匿名函数对象\n",
|
||||
" vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());\n",
|
||||
" if (it == v.end())\n",
|
||||
" {\n",
|
||||
" cout << \"未找到\" << endl;\n",
|
||||
" }\n",
|
||||
" else\n",
|
||||
" {\n",
|
||||
" cout << \"找到大于5的数字为:\" << *it << endl;\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main() \n",
|
||||
"{\n",
|
||||
" test01();\n",
|
||||
" \n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 找到大于5的数字为:6\n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 3. 二元谓词"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include<iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include<vector>\n",
|
||||
"#include<algorithm>\n",
|
||||
"\n",
|
||||
"//仿函数 返回值类型是bool数据类型,称为谓词\n",
|
||||
"//二元谓词\n",
|
||||
"class MyCompare\n",
|
||||
"{\n",
|
||||
"public:\n",
|
||||
" bool operator()(int val1,int val2)\n",
|
||||
" {\n",
|
||||
" return val1 > val2;\n",
|
||||
" }\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" vector<int>v;\n",
|
||||
" v.push_back(10);\n",
|
||||
" v.push_back(40);\n",
|
||||
" v.push_back(50);\n",
|
||||
" v.push_back(20);\n",
|
||||
" v.push_back(30);\n",
|
||||
"\n",
|
||||
" sort(v.begin(), v.end());\n",
|
||||
" for (vector<int>::iterator it = v.begin(); it != v.end(); it++)\n",
|
||||
" {\n",
|
||||
" cout << *it << \" \";\n",
|
||||
" }\n",
|
||||
" cout << endl;\n",
|
||||
"\n",
|
||||
" //使用函数对象,改变算法策略,变为排序规则为从大到小\n",
|
||||
" sort(v.begin(), v.end(), MyCompare()); //MyCompare()为函数对象,是匿名函数\n",
|
||||
"\n",
|
||||
" cout << \"----\" << endl;\n",
|
||||
" for (vector<int>::iterator it = v.begin(); it != v.end(); it++)\n",
|
||||
" {\n",
|
||||
" cout << *it << \" \";\n",
|
||||
" }\n",
|
||||
" cout << endl;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main() {\n",
|
||||
"\n",
|
||||
" test01();\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
" \n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果: \n",
|
||||
" - 10 20 30 40 50\n",
|
||||
" - $----$\n",
|
||||
" - 50 40 30 20 10\n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
128
docs/CPlusPlus-main/31_C++的谓词.md
Normal file
@ -0,0 +1,128 @@
|
||||
# C++的谓词
|
||||
|
||||
# 1. 简介
|
||||
|
||||
① 返回bool类型的仿函数称为谓词。
|
||||
|
||||
② 如果operator()接受一个参数,那么叫做一元谓词。
|
||||
|
||||
③ 如果operator()接受两个参数,那么叫做二元谓词。
|
||||
|
||||
# 2. 一元谓词
|
||||
|
||||
|
||||
```python
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
#include<vector>
|
||||
#include<algorithm>
|
||||
|
||||
//仿函数 返回值类型是bool数据类型,称为谓词
|
||||
//一元谓词
|
||||
class GreaterFive
|
||||
{
|
||||
public:
|
||||
bool operator()(int val)
|
||||
{
|
||||
return val > 5;
|
||||
}
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
vector<int>v;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
v.push_back(i);
|
||||
}
|
||||
|
||||
//查找容器中,有没有大于5的数字
|
||||
//GreaterFive() 匿名函数对象
|
||||
vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());
|
||||
if (it == v.end())
|
||||
{
|
||||
cout << "未找到" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "找到大于5的数字为:" << *it << endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 找到大于5的数字为:6
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 3. 二元谓词
|
||||
|
||||
|
||||
```python
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
#include<vector>
|
||||
#include<algorithm>
|
||||
|
||||
//仿函数 返回值类型是bool数据类型,称为谓词
|
||||
//二元谓词
|
||||
class MyCompare
|
||||
{
|
||||
public:
|
||||
bool operator()(int val1,int val2)
|
||||
{
|
||||
return val1 > val2;
|
||||
}
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
vector<int>v;
|
||||
v.push_back(10);
|
||||
v.push_back(40);
|
||||
v.push_back(50);
|
||||
v.push_back(20);
|
||||
v.push_back(30);
|
||||
|
||||
sort(v.begin(), v.end());
|
||||
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
|
||||
{
|
||||
cout << *it << " ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
//使用函数对象,改变算法策略,变为排序规则为从大到小
|
||||
sort(v.begin(), v.end(), MyCompare()); //MyCompare()为函数对象,是匿名函数
|
||||
|
||||
cout << "----" << endl;
|
||||
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
|
||||
{
|
||||
cout << *it << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 10 20 30 40 50
|
||||
- $----$
|
||||
- 50 40 30 20 10
|
||||
- 请按任意键继续. . .
|
||||
335
docs/CPlusPlus-main/32_C++的内建函数对象.ipynb
Normal file
@ -0,0 +1,335 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# C++的内建函数对象"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. 内建函数对象"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① STL内建来了一些函数对象:\n",
|
||||
"\n",
|
||||
"1. 算术仿函数\n",
|
||||
"2. 关系仿函数\n",
|
||||
"3. 逻辑仿函数\n",
|
||||
"\n",
|
||||
"② 用法:\n",
|
||||
"\n",
|
||||
"1. 这些仿函数所产生的对象,用法和一般函数完全相同。\n",
|
||||
"2. 使用内建函数对象,需要引入头文件 #include<functional>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 2. 算术仿函数"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 功能描述:实现四则运算。\n",
|
||||
"\n",
|
||||
"② 其中negate是一元运算,其他都是二元运算。\n",
|
||||
"\n",
|
||||
"③ 仿函数原型:\n",
|
||||
"\n",
|
||||
"1. $template<class T> T plus<T>$ //加法仿函数\n",
|
||||
"2. $template<class T> T minus<T>$ //减法仿函数\n",
|
||||
"3. $template<class T> T multiplies<T>$ //乘法仿函数\n",
|
||||
"4. $template<class T> T divides<T>$ //除法仿函数\n",
|
||||
"5. $template<class T> T modulus<T>$ //取模仿函数\n",
|
||||
"6. $template<class T> T negate<T>$ //取反仿函数\n",
|
||||
"\n",
|
||||
"④ 使用内建函数对象时,需要引入头文件#include <functional>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include<iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include<functional> //内建函数对象头文件\n",
|
||||
"\n",
|
||||
"//内建函数对象 算术仿函数\n",
|
||||
"\n",
|
||||
"//negate 一元仿函数 取反仿函数\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" negate<int>n;\n",
|
||||
"\n",
|
||||
" cout << n(50) << endl;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"//plus 二元仿函数 加法\n",
|
||||
"void test02()\n",
|
||||
"{\n",
|
||||
" plus<int>p; //写一个int就好了,不用写两个int,它默认是两个同类型的int相加\n",
|
||||
"\n",
|
||||
" cout << p(50,60) << endl;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main() {\n",
|
||||
"\n",
|
||||
" test01();\n",
|
||||
" test02();\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果:\n",
|
||||
" - -50\n",
|
||||
" - 110\n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 3. 关系仿函数"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 功能描述:实现关系对比。\n",
|
||||
"\n",
|
||||
"② 仿函数原型: \n",
|
||||
"\n",
|
||||
"1. $template<class T> bool equal_to<T>$ //等于\n",
|
||||
"2. $template<class T> bool notequal_to<T>$ //不等于\n",
|
||||
"3. $template<>class T> bool greater<T>$ //大于\n",
|
||||
"4. $template<class T> bool greater_qual<T>$ //大于等于\n",
|
||||
"5. $template<class T> bool less<T>$ //小于\n",
|
||||
"6. $template<class T>bool less_equal<T>$ //小于等于 \n",
|
||||
"\n",
|
||||
"③ 关系仿函数中最常用的就是greater<>大于。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include<iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include<functional> //内建函数对象头文件\n",
|
||||
"#include<vector>\n",
|
||||
"#include<algorithm>\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"//内建函数对象 关系仿函数\n",
|
||||
"//大于 greater\n",
|
||||
"class MyCompare\n",
|
||||
"{\n",
|
||||
" bool operator()(int v1, int v2)\n",
|
||||
" {\n",
|
||||
" return v1 > v2;\n",
|
||||
" }\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" vector<int>v;\n",
|
||||
"\n",
|
||||
" v.push_back(10);\n",
|
||||
" v.push_back(20);\n",
|
||||
" v.push_back(30);\n",
|
||||
" v.push_back(40);\n",
|
||||
" v.push_back(50);\n",
|
||||
"\n",
|
||||
" for (vector<int>::iterator it = v.begin();it!=v.end();it++)\n",
|
||||
" {\n",
|
||||
" cout << *it << \" \";\n",
|
||||
" }\n",
|
||||
" cout << endl;\n",
|
||||
"\n",
|
||||
" //降序\n",
|
||||
" \n",
|
||||
" //方式一:\n",
|
||||
" //sort(v.begin(), v.end(), MyCompare());\n",
|
||||
" \n",
|
||||
" //方式二:\n",
|
||||
" sort(v.begin(), v.end(), greater<int>()); //greater<int>()为编译器给提供的函数对象,为内建的函数对象\n",
|
||||
"\n",
|
||||
" for (vector<int>::iterator it = v.begin(); it != v.end(); it++)\n",
|
||||
" {\n",
|
||||
" cout << *it << \" \";\n",
|
||||
" }\n",
|
||||
" cout << endl;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"int main() {\n",
|
||||
"\n",
|
||||
" test01();\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果:\n",
|
||||
" - 10 20 30 40 50\n",
|
||||
" - 50 40 30 20 10\n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 4. 逻辑仿函数"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"① 功能描述:实现关系对比\n",
|
||||
"\n",
|
||||
"② 仿函数原型:\n",
|
||||
"\n",
|
||||
"1. $template<class T> bool logical_and<T>$ //逻辑与\n",
|
||||
"2. $template<class T> bool logical_or<T>$ //逻辑或\n",
|
||||
"3. $template<class T> bool logical_not<T>$ //逻辑非\n",
|
||||
"\n",
|
||||
"③ 逻辑仿函数实际应用较少,了解即可。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#include<iostream>\n",
|
||||
"using namespace std;\n",
|
||||
"#include<functional> //内建函数对象头文件\n",
|
||||
"#include<vector>\n",
|
||||
"#include<algorithm>\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"//内建函数对象 逻辑仿函数\n",
|
||||
"//逻辑非 logical_not\n",
|
||||
"\n",
|
||||
"void test01()\n",
|
||||
"{\n",
|
||||
" vector<bool>v;\n",
|
||||
"\n",
|
||||
" v.push_back(true);\n",
|
||||
" v.push_back(false);\n",
|
||||
" v.push_back(true);\n",
|
||||
" v.push_back(true);\n",
|
||||
" v.push_back(false);\n",
|
||||
"\n",
|
||||
" for (vector<bool>::iterator it = v.begin();it!=v.end();it++)\n",
|
||||
" {\n",
|
||||
" cout << *it << \" \";\n",
|
||||
" }\n",
|
||||
" cout << endl;\n",
|
||||
"\n",
|
||||
" //利用逻辑非 将容器v 搬运到 容器v2中,并执行取反操作\n",
|
||||
" vector<bool>v2;\n",
|
||||
" v2.resize(v.size()); //目标容器要提前开辟一个空间\n",
|
||||
"\n",
|
||||
" transform(v.begin(),v.end(),v2.begin(),logical_not<bool>()); //第一个参数:原容器起始迭代器,第二个参数:原容器终止迭代器,第三个参数:目标容器起始迭代器\n",
|
||||
"\n",
|
||||
" for (vector<bool>::iterator it = v2.begin(); it != v2.end(); it++)\n",
|
||||
" {\n",
|
||||
" cout << *it << \" \";\n",
|
||||
" }\n",
|
||||
" cout << endl;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"int main() {\n",
|
||||
"\n",
|
||||
" test01();\n",
|
||||
"\n",
|
||||
" system(\"pause\");\n",
|
||||
"\n",
|
||||
" return 0;\n",
|
||||
"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行结果:\n",
|
||||
" - 1 0 1 1 0\n",
|
||||
" - 0 1 0 0 1\n",
|
||||
" - 请按任意键继续. . ."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.6.3",
|
||||
"language": "python",
|
||||
"name": "python3.6.3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
224
docs/CPlusPlus-main/32_C++的内建函数对象.md
Normal file
@ -0,0 +1,224 @@
|
||||
# C++的内建函数对象
|
||||
|
||||
# 1. 内建函数对象
|
||||
|
||||
① STL内建来了一些函数对象:
|
||||
|
||||
1. 算术仿函数
|
||||
2. 关系仿函数
|
||||
3. 逻辑仿函数
|
||||
|
||||
② 用法:
|
||||
|
||||
1. 这些仿函数所产生的对象,用法和一般函数完全相同。
|
||||
2. 使用内建函数对象,需要引入头文件 #include<functional>
|
||||
|
||||
# 2. 算术仿函数
|
||||
|
||||
① 功能描述:实现四则运算。
|
||||
|
||||
② 其中negate是一元运算,其他都是二元运算。
|
||||
|
||||
③ 仿函数原型:
|
||||
|
||||
1. $template<class T> T plus<T>$ //加法仿函数
|
||||
2. $template<class T> T minus<T>$ //减法仿函数
|
||||
3. $template<class T> T multiplies<T>$ //乘法仿函数
|
||||
4. $template<class T> T divides<T>$ //除法仿函数
|
||||
5. $template<class T> T modulus<T>$ //取模仿函数
|
||||
6. $template<class T> T negate<T>$ //取反仿函数
|
||||
|
||||
④ 使用内建函数对象时,需要引入头文件#include <functional>
|
||||
|
||||
|
||||
```python
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
#include<functional> //内建函数对象头文件
|
||||
|
||||
//内建函数对象 算术仿函数
|
||||
|
||||
//negate 一元仿函数 取反仿函数
|
||||
void test01()
|
||||
{
|
||||
negate<int>n;
|
||||
|
||||
cout << n(50) << endl;
|
||||
}
|
||||
|
||||
//plus 二元仿函数 加法
|
||||
void test02()
|
||||
{
|
||||
plus<int>p; //写一个int就好了,不用写两个int,它默认是两个同类型的int相加
|
||||
|
||||
cout << p(50,60) << endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
test01();
|
||||
test02();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- -50
|
||||
- 110
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 3. 关系仿函数
|
||||
|
||||
① 功能描述:实现关系对比。
|
||||
|
||||
② 仿函数原型:
|
||||
|
||||
1. $template<class T> bool equal_to<T>$ //等于
|
||||
2. $template<class T> bool notequal_to<T>$ //不等于
|
||||
3. $template<>class T> bool greater<T>$ //大于
|
||||
4. $template<class T> bool greater_qual<T>$ //大于等于
|
||||
5. $template<class T> bool less<T>$ //小于
|
||||
6. $template<class T>bool less_equal<T>$ //小于等于
|
||||
|
||||
③ 关系仿函数中最常用的就是greater<>大于。
|
||||
|
||||
|
||||
```python
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
#include<functional> //内建函数对象头文件
|
||||
#include<vector>
|
||||
#include<algorithm>
|
||||
|
||||
|
||||
//内建函数对象 关系仿函数
|
||||
//大于 greater
|
||||
class MyCompare
|
||||
{
|
||||
bool operator()(int v1, int v2)
|
||||
{
|
||||
return v1 > v2;
|
||||
}
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
vector<int>v;
|
||||
|
||||
v.push_back(10);
|
||||
v.push_back(20);
|
||||
v.push_back(30);
|
||||
v.push_back(40);
|
||||
v.push_back(50);
|
||||
|
||||
for (vector<int>::iterator it = v.begin();it!=v.end();it++)
|
||||
{
|
||||
cout << *it << " ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
//降序
|
||||
|
||||
//方式一:
|
||||
//sort(v.begin(), v.end(), MyCompare());
|
||||
|
||||
//方式二:
|
||||
sort(v.begin(), v.end(), greater<int>()); //greater<int>()为编译器给提供的函数对象,为内建的函数对象
|
||||
|
||||
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
|
||||
{
|
||||
cout << *it << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 10 20 30 40 50
|
||||
- 50 40 30 20 10
|
||||
- 请按任意键继续. . .
|
||||
|
||||
# 4. 逻辑仿函数
|
||||
|
||||
① 功能描述:实现关系对比
|
||||
|
||||
② 仿函数原型:
|
||||
|
||||
1. $template<class T> bool logical_and<T>$ //逻辑与
|
||||
2. $template<class T> bool logical_or<T>$ //逻辑或
|
||||
3. $template<class T> bool logical_not<T>$ //逻辑非
|
||||
|
||||
③ 逻辑仿函数实际应用较少,了解即可。
|
||||
|
||||
|
||||
```python
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
#include<functional> //内建函数对象头文件
|
||||
#include<vector>
|
||||
#include<algorithm>
|
||||
|
||||
|
||||
//内建函数对象 逻辑仿函数
|
||||
//逻辑非 logical_not
|
||||
|
||||
void test01()
|
||||
{
|
||||
vector<bool>v;
|
||||
|
||||
v.push_back(true);
|
||||
v.push_back(false);
|
||||
v.push_back(true);
|
||||
v.push_back(true);
|
||||
v.push_back(false);
|
||||
|
||||
for (vector<bool>::iterator it = v.begin();it!=v.end();it++)
|
||||
{
|
||||
cout << *it << " ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
//利用逻辑非 将容器v 搬运到 容器v2中,并执行取反操作
|
||||
vector<bool>v2;
|
||||
v2.resize(v.size()); //目标容器要提前开辟一个空间
|
||||
|
||||
transform(v.begin(),v.end(),v2.begin(),logical_not<bool>()); //第一个参数:原容器起始迭代器,第二个参数:原容器终止迭代器,第三个参数:目标容器起始迭代器
|
||||
|
||||
for (vector<bool>::iterator it = v2.begin(); it != v2.end(); it++)
|
||||
{
|
||||
cout << *it << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
test01();
|
||||
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
运行结果:
|
||||
- 1 0 1 1 0
|
||||
- 0 1 0 0 1
|
||||
- 请按任意键继续. . .
|
||||
2281
docs/CPlusPlus-main/33_C++的常用算法.ipynb
Normal file
1718
docs/CPlusPlus-main/33_C++的常用算法.md
Normal file
BIN
docs/CPlusPlus-main/33_C++的常用算法_files/image.png
Normal file
|
After Width: | Height: | Size: 149 KiB |
180
docs/CPlusPlus-main/README.md
Normal file
@ -0,0 +1,180 @@
|
||||
# 最全面的 C++ 笔记
|
||||
|
||||
笔记视频:
|
||||
|
||||
视频讲解【主讲方:黑马程序员】
|
||||
|
||||
1. https://www.bilibili.com/video/BV1et411b73Z?p=1
|
||||
|
||||
-------------------------------------------------------------
|
||||
-------------------------------------------------------------
|
||||
|
||||
笔记备注:
|
||||
|
||||
1. 在线观看笔记时,有时会出现图片(或公式)显示不完整,这是Github网站没有解析好,笔记下载到本地观看就正常了。(不会下载笔记的,百度查一下"Github如何下载文件"。)
|
||||
2. Pycharm 的 Jupyter Notebook 打开笔记时,图片不会正常显示,笔记是用 Anaconda 的 Jupyter Notebook 打开的。(不会打开笔记的,百度查一下"Anaconda如何打开Jupyter Notebook文件",或者我的主页Python仓库里面"00_Python编辑器"里面有写。)
|
||||
3. 安装 Jupyter Notebook 的目录插件,可以快速通过目录,跳转到相应的章节,如下图所示。(不会安装目录的,百度查一下"Jupyter Notebook如何安装目录",或者我的主页Python仓库里面"00_Python编辑器"里面有相关链接。)
|
||||
|
||||
补充说明:C++代码我是在VS2019中运行的,Jupyter Notebook仅是笔记文档。
|
||||
|
||||

|
||||
|
||||
-------------------------------------------------------------
|
||||
-------------------------------------------------------------
|
||||
|
||||
更多笔记:
|
||||
|
||||
我的Github主页,还有其他优秀视频的笔记,希望能帮助到你~
|
||||
|
||||
1. https://github.com/AccumulateMore
|
||||
|
||||
我的哔哩哔哩, 大模型、多模态笔记【手把手教你做科研 更新ing】,希望能帮助到你~
|
||||
|
||||
1. https://www.bilibili.com/video/BV1xM4m1m7vA/?spm_id_from=333.999.0.0&vd_source=c9745e4447536b28b2b0735071d30bd6
|
||||
|
||||
"♥我的笔记,希望对你有帮助♥"
|
||||
|
||||
♥小声哔哔:你的star,是我更新的动力~♥
|
||||
|
||||
-------------------------------------------------------------
|
||||
-------------------------------------------------------------
|
||||
|
||||
搭建交流群,帮助孤单的自学者交流
|
||||
|
||||
| 【深度学习 学习交流①群】 | 【深度学习 学习交流②群】 | 微信 |
|
||||
| -------- | -------- | -------- |
|
||||
| <br/> | <br/> | <br> |
|
||||
|
||||
超过200人,扫码入群方式失效,只能微信好友邀请入群。
|
||||
|
||||
看人之短,无一可交之人。看人之长,天下皆是吾师。
|
||||
|
||||
备注:好友申请时,声明目的,需要什么
|
||||
|
||||
| 备注 | 备注 | 备注 |
|
||||
| -------------------- | -------- | -------- |
|
||||
| 需要论文辅导(研0研1免费,半年掌握三年知识)<br/> | 要进学习交流群<br/> | 要数据集<br> |
|
||||
| 需要学习指导(指数级学习,快速拿到offer)<br/> | 需要实习(可开实习证明)<br/> | ......<br> |
|
||||
| 需要商业级项目(快速从0到1,简历增添项目)<br/> | 指导改简历(从面试官角度出发)<br/> | ......<br> |
|
||||
|
||||
-------------------------------------------------------------
|
||||
-------------------------------------------------------------
|
||||
|
||||
帮你们就业,有意向的可以投简历
|
||||
|
||||
备注:初学者也可以根据市场上就业需求,去学习自己。
|
||||
|
||||
联影医疗 地点(可选):上海、北京、深圳、武汉、广州、成都、西安、沈阳、三亚等
|
||||
|
||||
内推人:联影老员工
|
||||
|
||||
岗位职责【图像方向】:
|
||||
|
||||
参与联影集团产品的AI算法开发工作或图形算法开发工作,负责下列至少一项工作:
|
||||
|
||||
1. 负责提供产品级高端算法解决方案,包括:联影通用软件平台、联影高级应用后处理工作站、联影智能uAl平台、联影机器人手术规划与导航、MR/CT/RT/MI/US事业部的算法需求、科研院所和医院的前瞻性研究项目等;参与创新技术的产品化工作。
|
||||
2. 医学图像3D渲染算法和应用维护与开发,利用图像处理和人工智能技术,从事医学图像处理领域相关算法的设计和研发。
|
||||
|
||||
任职要求:
|
||||
|
||||
1. 熟悉机器视觉原理,熟悉以下领域之一:3D重建、立体视觉、SLAM、通用图像视频分类、目标检测、人体姿态估计。
|
||||
2. 熟悉以下医学图像后处理算法之一:图形算法、重建算法、分割算法、检测算法、分类算法、配准算法、深度学习算法、流体力学算法、灌注算法、纹理分析算法等。
|
||||
|
||||
岗位职责【语音方向】:
|
||||
|
||||
1. 负责音频信号处理和识别相关算法的研究和实现,包含但不限于回声消除、麦克风阵列、盲源分离等技术。
|
||||
2. 负责深度学习、神经网络等AI音频算法的研究和实现。
|
||||
|
||||
任职要求:
|
||||
|
||||
1. 扎实的数学理论及数字信号处理基础,掌握Matlab及C/C++语言编程。
|
||||
2. 有语音、音频信号处理(降噪,回声消除、麦阵、音效等)相关经验。
|
||||
3. 有深度学习、神经网络、智能语音识别相关研究。
|
||||
|
||||
岗位职责【大模型方向】:
|
||||
|
||||
1. 负责大语言模型方面的算法开发、优化、应用落地。
|
||||
2. 负责相应AI解决方案设计,参与关键技术研发,攻关技术难点。
|
||||
3. 负责设计和实现大语言模型相关的算法和模型实现,研究并设计新是算法和模型,解决大语言模型应用问题。
|
||||
4. 负责开发和优化大语言模型的训练过程,设计并实现大语言模型的训练算法和策略,配置和优化训练的超参数和计算资源,保证模型的训练效果和效率。
|
||||
5. 负责构建和管理大规模医疗文本数据集,用于模型预训练和微调,完成不用场景下的下游任务。
|
||||
6. 负责进行大语言模型的评估和验证,设计评估指标和实验;设计和实施评估指标和实验,对训练好的大语言模型进行性能评估和分析。识别模型的弱点和改进空间,提出相应的改进策略和方法。
|
||||
7. 参与高校、科研、医疗机构科研合作,协助科研成果落地转化。
|
||||
|
||||
任职要求:
|
||||
|
||||
1. 具有机器学习、自然语言处理、医学影像分析,或相关领域的学习和研究。
|
||||
2. 有预训练大语言模型或GPT模型等相关研究开发经验。
|
||||
3. 在机器学习(ICML,NeurlPS、ICLR等)、计算机视觉(CVPR、ICCV、ECCV等)、自然语言处理(ACL,EMNLP等)和医疗影像分析(MICCAI、IPMI)等顶级会议,或者顶级期刊(IEEE T-PAMI,IEEE TMI、Medical lmage Analysis)发表过相关论文。
|
||||
4. 具有人工智能相关专业(计算机视觉、机器学习、医疗图像分析等)硕士及以上学位。
|
||||
5. 能熟练使用英语。
|
||||
|
||||
补充:能内推简历的,也可以联系我,把岗位职责、任职要求发给我【你收公司内推奖金、ta们就业,双赢】。
|
||||
|
||||
-------------------------------------------------------------
|
||||
-------------------------------------------------------------
|
||||
|
||||
想学习商业级项目的,下面商业级项目可以学习,与大量求职者卷一卷,提高核心竞争力。
|
||||
|
||||
| 商业项目 | 商业项目 | 商业项目 | 商业项目 |
|
||||
| -------------------- | -------- | -------- | -------- |
|
||||
| 人脸识别与管理系统<br/> | 车牌识别与管理系统<br/> | 手势识别系统<br/> | 人脸面部活体检测系统<br> |
|
||||
| 目标检测与自动标注系统<br/> | 人脸表情识别系统<br/> | 行人跌倒检测系统<br/> | PCB板缺陷检测系统<br> |
|
||||
| 安全帽检测系统<br/> | 生活垃圾分类系统<br/> | 火焰烟雾检测系统<br/> | 路面坑洞检测系统<br> |
|
||||
| 钢材表面缺陷检测系统<br/> | 肺炎诊断系统<br/> | 面部口罩检测系统<br/> | 西红柿成熟度检测系统<br> |
|
||||
| 血细胞检测计数系统<br/> | 舰船分类检测系统<br/> | 吸烟行为检测系统<br/> | 水稻害虫检测系统<br> |
|
||||
| 交通标志检测系统<br/> | 行人追踪计数系统<br/> | 车辆追踪计数系统<br/> | 脑肿瘤检测系统<br> |
|
||||
| 无人机视角检测系统<br/> | 裂缝检测分析系统<br/> | 水下海生物检测系统<br/> | 草莓成熟度检测系统<br> |
|
||||
| 条形码检测系统<br/> | 交通信号灯检测系统<br/> | 金属品瑕疵检测系统<br/> | 链条缺陷检测系统<br> |
|
||||
| 螺栓螺母检测系统<br/> | 焊缝缺陷检测系统<br/> | 蛀牙检测识别系统<br/> | 非机动车头盔检测系统<br> |
|
||||
| 水果检测识别系统<br/> | 蔬菜检测系统<br/> | 高密度人脸检测系统<br/> | 肾结石检测系统<br> |
|
||||
| 反光衣检测预警系统<br/> | 人员闯入报警系统<br/> | 玉米病害检测系统<br/> | 橙子病害识别系统<br> |
|
||||
| 木薯病害识别预防系统<br/> | 野火烟雾检测系统<br/> | 路面坑洞检测分割系统<br/> | 遥感地面物体检测系统<br> |
|
||||
| 田间杂草检测系统<br/> | 葡萄病害识别系统<br/> | 车牌检测识别系统<br/> | 草莓病害检测分割系统<br> |
|
||||
| 车辆行人追踪系统<br/> | 水稻病害识别系统<br/> | 中草药识别系统<br/> | 车辆行人检测系统<br> |
|
||||
| 条形码识别系统<br/> | 交通信号灯识别系统<br/> | 水下海生物检测系统<br/> | 交通事故检测系统<br> |
|
||||
| 安检危险品检测系统<br/> | 农作物检测系统<br/> | 危险驾驶行为检测系统<br/> | 维修工具检测系统<br> |
|
||||
| 建筑墙面损伤检测系统<br/> | 煤矿传送带异物检测系统<br/> | 老鼠智能检测系统<br/> | 水面垃圾检测系统<br> |
|
||||
| 遥感视角船只检测系统<br/> | 胃肠道息肉检测系统<br/> | 心脏间隔壁分割系统<br/> | 半导体芯片缺陷检测系统<br> |
|
||||
| 视网膜疾病诊断系统<br/> | 运动鞋品牌识别系统<br/> | X光骨折检测系统<br/> | 遥感视角农田分割系统<br> |
|
||||
| 电瓶车进电梯检测系统<br/> | 遥感视角房屋分割系统<br/> | CT肺结节检测系统<br/> | 舌苔舌像诊断系统<br> |
|
||||
| 输电线路设备检测系统<br/> | 零售柜商品识别系统<br/> | 远距离停车位检测系统<br/> | 安全帽检测系统<br> |
|
||||
| 机场航拍小目标检测系统<br/> | 景区垃圾识别系统<br/> | 快递包裹检测系统<br/> | 无人机目标检测系统<br> |
|
||||
| 疲劳驾驶检测系统<br/> | 布匹缺陷检测系统<br/> | 夜视行人检测系统<br/> | 教研人员检测与计数系统<br> |
|
||||
|
||||
-------------------------------------------------------------
|
||||
-------------------------------------------------------------
|
||||
|
||||
2021年我硕士毕业时,【简历】技能书写,可以借鉴
|
||||
|
||||

|
||||
|
||||
用了几个技巧,分享给大家:
|
||||
|
||||
1. 技能只写掌握了XX,没掌握不要写,掌握且更熟练的放前面,掌握但不熟练的放后面。
|
||||
2. 写掌握某项技能时,后面要论证自己真的掌握了,提供相关经历,方便面试官切入询问。
|
||||
3. 围绕算法岗展开技能阐述,从编程语言、到深度学习框架、到图像处理算法、服务器数据库存储图像等。
|
||||
4. 只写岗位需要的技能,与算法岗不需要的硬件知识、组织能力等不要写,让简历更高匹配算法岗。
|
||||
5. 掌握一种类别技能,只占一行,不要有的两行、有的一行,看着不整齐。
|
||||
6. 面试官及HR会看着感觉整齐、可信、岗位匹配度高。
|
||||
|
||||
要知道,很多大公司HR经常一天要看几百份,甚至上千份简历,基本都是10秒内看一份简历。
|
||||
|
||||
就是这关键的10秒,HR就决定了是进入面试还是PASS。
|
||||
|
||||
我已经指导过上千位同学,即使市场大环境不好,很多同学都入职各家公司成功了。
|
||||
|
||||
| 金九 内推第一名 | 银十 内推第一名 | 2024内推第一名 |
|
||||
| ------ | ------ | ------ |
|
||||
| <br/>|<br/> | <br> |
|
||||
|
||||
一起沾沾喜气,好运是可以传染的~
|
||||
|
||||
个人经验:拿offer最快的方式,就是不走弯路,在少量的时间,积累大量技能。
|
||||
|
||||
(不要等到火烧眉毛,再来找我抢救.......)
|
||||
|
||||
-------------------------------------------------------------
|
||||
-------------------------------------------------------------
|
||||
|
||||
"♥我们读书是为了成为提灯人去照亮黑暗,而不是为了自己有灯而沾沾自喜还要去吹灭别人的蜡烛♥"
|
||||
11
docs/脚本/生成目录.py
Normal file
@ -0,0 +1,11 @@
|
||||
import os
|
||||
|
||||
# 设置要扫描的根目录
|
||||
root_dir = "../CPlusPlus-main"
|
||||
|
||||
# 遍历目录并输出所有文件
|
||||
for root, dirs, files in os.walk(root_dir):
|
||||
for file in files:
|
||||
name_without_ext = os.path.splitext(file)[0]
|
||||
rel_path = os.path.join(root, file).replace("\\", "/") # 统一路径格式为 Unix 风格
|
||||
print(f"- {name_without_ext}: {rel_path}")
|
||||
36
docs/脚本/转成md.py
Normal file
@ -0,0 +1,36 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
||||
def convert_ipynb_to_md(root_dir, output_dir=None):
|
||||
for root, dirs, files in os.walk(root_dir):
|
||||
for file in files:
|
||||
if file.endswith(".ipynb"):
|
||||
ipynb_path = os.path.join(root, file)
|
||||
print(f"正在转换: {ipynb_path}")
|
||||
|
||||
if output_dir:
|
||||
# 指定输出目录(保留子目录结构)
|
||||
rel_path = os.path.relpath(root, root_dir)
|
||||
full_output_dir = os.path.join(output_dir, rel_path)
|
||||
os.makedirs(full_output_dir, exist_ok=True)
|
||||
cmd = [
|
||||
"jupyter", "nbconvert", "--to", "markdown",
|
||||
ipynb_path, "--output-dir", full_output_dir
|
||||
]
|
||||
else:
|
||||
# 输出到原目录
|
||||
cmd = [
|
||||
"jupyter", "nbconvert", "--to", "markdown",
|
||||
ipynb_path
|
||||
]
|
||||
|
||||
subprocess.run(cmd)
|
||||
|
||||
|
||||
# ✅ 用法:修改下面两个路径
|
||||
source_folder = "../CPlusPlus-main" # ← 你的.ipynb源目录
|
||||
markdown_output_folder = None # ← 设置为 None 表示输出在原目录下
|
||||
# markdown_output_folder = "docs_md" # ← 设置输出目录
|
||||
|
||||
convert_ipynb_to_md(source_folder, markdown_output_folder)
|
||||
5
main.py
@ -1,5 +0,0 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
# 运行 mkdocs serve 命令
|
||||
subprocess.run(['mkdocs', 'serve'])
|
||||
39
mkdocs.yml
@ -54,6 +54,40 @@ nav:
|
||||
- 第十七章 标准库特殊设施: Cpp-Notes-main/Cpp-Primer/17.标准库特殊设施.md
|
||||
- 第十八章 用于大型程序的工具: Cpp-Notes-main/Cpp-Primer/18.用于大型程序的工具.md
|
||||
- 第十九章 特殊工具与技术: Cpp-Notes-main/Cpp-Primer/19.特殊工具与技术.md
|
||||
- CPlusPlus:
|
||||
- 01_C++的注释: CPlusPlus-main/01_C++的注释.md
|
||||
- 02_C++的main函数: CPlusPlus-main/02_C++的main函数.md
|
||||
- 03_C++的打印: CPlusPlus-main/03_C++的打印.md
|
||||
- 04_C++的常量: CPlusPlus-main/04_C++的常量.md
|
||||
- 05_C++的变量: CPlusPlus-main/05_C++的变量.md
|
||||
- 06_C++的关键字: CPlusPlus-main/06_C++的关键字.md
|
||||
- 07_C++的标识符: CPlusPlus-main/07_C++的标识符.md
|
||||
- 08_C++的数据类型: CPlusPlus-main/08_C++的数据类型.md
|
||||
- 09_C++的转义字符: CPlusPlus-main/09_C++的转义字符.md
|
||||
- 10_C++的数据输入: CPlusPlus-main/10_C++的数据输入.md
|
||||
- 11_C++的运算符: CPlusPlus-main/11_C++的运算符.md
|
||||
- 12_C++的程序流程结构: CPlusPlus-main/12_C++的程序流程结构.md
|
||||
- 13_C++的数组: CPlusPlus-main/13_C++的数组.md
|
||||
- 14_C++的函数: CPlusPlus-main/14_C++的函数.md
|
||||
- 15_C++的指针: CPlusPlus-main/15_C++的指针.md
|
||||
- 16_C++的结构体: CPlusPlus-main/16_C++的结构体.md
|
||||
- 17_C++的内存模型: CPlusPlus-main/17_C++的内存模型.md
|
||||
- 18_C++的引用: CPlusPlus-main/18_C++的引用.md
|
||||
- 19_C++的面向对象: CPlusPlus-main/19_C++的面向对象.md
|
||||
- 20_C++的类中封装: CPlusPlus-main/20_C++的类中封装.md
|
||||
- 21_C++的调用其他类: CPlusPlus-main/21_C++的调用其他类.md
|
||||
- 22_C++的类中特性: CPlusPlus-main/22_C++的类中特性.md
|
||||
- 23_C++的类中友元: CPlusPlus-main/23_C++的类中友元.md
|
||||
- 24_C++的类中运算符重载: CPlusPlus-main/24_C++的类中运算符重载.md
|
||||
- 25_C++的类中继承: CPlusPlus-main/25_C++的类中继承.md
|
||||
- 26_C++的类中多态: CPlusPlus-main/26_C++的类中多态.md
|
||||
- 27_C++的文件操作: CPlusPlus-main/27_C++的文件操作.md
|
||||
- 28_C++的模板: CPlusPlus-main/28_C++的模板.md
|
||||
- 29_C++的STL: CPlusPlus-main/29_C++的STL.md
|
||||
- 30_C++的函数对象: CPlusPlus-main/30_C++的函数对象.md
|
||||
- 31_C++的谓词: CPlusPlus-main/31_C++的谓词.md
|
||||
- 32_C++的内建函数对象: CPlusPlus-main/32_C++的内建函数对象.md
|
||||
- 33_C++的常用算法: CPlusPlus-main/33_C++的常用算法.md
|
||||
|
||||
|
||||
theme:
|
||||
@ -85,6 +119,11 @@ theme:
|
||||
icon:
|
||||
logo: material/school
|
||||
|
||||
plugins:
|
||||
- search
|
||||
- mkdocs-jupyter
|
||||
|
||||
|
||||
#markdown_extensions:
|
||||
# - admonition
|
||||
# - def_list
|
||||
|
||||