C++ 基础入门
第一章 C++ 介绍
一、为什么要学习 C++
- C++ 能提升新能。提升性能意味着钱。C++ 之父 Bjarne Stroustrup 戏称 C++ 可以减轻全球变暖问题
- 编程序言的需求总结为四个:
- 效率(efficiency)
- 灵活(flexibility)
- 抽象(abstraction)
- 生产力(productivity)
- C语言注重前两者,C++注重前三者,Java,.net这些注重后两者
- Why C++? 王者归来
- C++ 应用范围广泛
二、C++ 为什么难学
- C++ 支持的编程范式(paradigm)
- 过程式(procedual)
- 数据抽象(data abstraction)
- 基于对象(object-based)
- 面向对象式(object-oriented)
- 函数式(functional)
- 泛型形式
- 模板元形式
- 值语义雨对象语义
- 值语义可以拷贝与赋值、对象语义不可以进行拷贝与赋值
- function/bind的救赎(上)、这篇文章对编程范式进行一些探讨
三、C++ 11值得学习的新特性
- 只能指针如 shared_ptr、weak_ptr等
- rvalue reference;
- function/bind
- lambda expression and closure
四、开发工具选择
- Visual Studio
第二章 C++ 初识
一、第一个 C++ 程序
编写一个 C++ 程序总共分为 4 个步骤
- 创建项目
- 创建文件
- 编写代码
- 运行程序
1、创建项目
Visual Studio 使我们用来编写 C++ 程序的主要工具,我们先将它打开
2、创建文件
-
鼠标右键源文件
-
添加
-
新建项
-
-
编写代码
#include <iostream> using namespace std; int main() { // 输出 Hello World cout << "Hello World" << endl; system("pause"); return 0; }
-
执行代码
二、注释
作用:在代码中添加一些说明和解释,方便自己或其他程序员阅读代码
两种格式:
- 单行注释:
// 描述信息
- 通常放在一行代码的上方,或者一条语句的末尾,对该行代码说明
- 多行注释:
/* 描述信息 */
- 通常放在一段代码的上方,对该段代码做整体说明
提示:编译器在编译代码时会忽略注释的内容
#include <iostream>
using namespace std;
/*
main 是一个程序的入口,
每个程序都必须有这个一个函数
有且只有一个
*/
int main()
{
// 输出 Hello World
cout << "Hello World" << endl;
system("pause");
return 0;
}
三、变量
作用:给一段指定的内存空间起名,方便操作这段内存
语法:数据类型 变量名 = 初始值;
示例:
#include <iostream>
using namespace std;
int main()
{
// 变量的定义
// 语法:数据类型 变量名 = 初始值;
int num = 10;
cout << "num = " << num << endl;
system("pause");
return 0;
}
四、常量
作用:用于记录程序中不可更改的数据
C++ 定义常量两种方式:
- #define 宏常量:
#define 常量名 常量值
- 通常在文件上方定义,标识一个常量
- const 修饰的变量
const 数据类型 常量名 = 变量值
- 通常在变量定义前加关键字 const,修饰该变量为常量,不可修改
示例:
#include <iostream>
using namespace std;
// 定义一个宏常量
#define DAY 7
int main()
{
// day = 8; 报错,宏常量不可修改
cout << "一周里总共有 " << DAY << " 天" << endl;
// const 修饰变量
const int month = 12;
// month = 24; 报错,const修饰的变量也成为常量
cout << "一年里总共有 " << month << " 个月" << endl;
system("pause");
return 0;
}
五、关键字
作用:关键字是 C++ 中预先表刘的单词(标识符)
- 在定义变量或常量的时候,不要使用关键字
asm | else | new | this |
---|---|---|---|
auto | enum | operator | throw |
bool | explicit | private | true |
break | export | protected | try |
case | extern | public | typedef |
catch | false | register | typeid |
char | float | reinterpret_cast | typename |
class | for | return | union |
const | friend | short | unsigned |
const_cast | goto | signed | using |
continue | if | sizeof | virtual |
default | inline | static | void |
delete | int | static_cast | volatile |
do | long | struct | wchar_t |
double | mutable | switch | while |
dynamic_cast | namespace | template |
示例:
#include <iostream>
using namespace std;
int main()
{
// int int = 10; int 是关键字,不可以作为变量的名称
system("pause");
return 0;
}
六、标识符命名规则
作用:C++ 规定给标识符(变量,常量)命名时,有一套自己的规则
- 标识符不能是关键字
- 标识符只能由字母、数字。下划线组成
- 第一个字符必须为字母或下划线
- 标识符中字母区分大小写
建议:给标识符命名时,争取做到建明制衣的效果,方便自己和他人的阅读
示例:
#include <iostream>
using namespace std;
/*
标识符命名规则
1、标识符不可以是关键字
2、标识符是由字母、数字、下划线构成
3、标识符第一个字符必须为字母或下划线
4、标识符中字母区分大小写
*/
int main()
{
// 1、标识符不可以是关键字
// int int = 10;
// 2、标识符是由字母、数字、下划线构成
int abc = 10;
int _abc = 20;
int _123abc = 30;
// 3、标识符第一个字符必须为字母或下划线
// int 123_abc = 40;
// 4、标识符中字母区分大小写
int aaa = 100;
cout << aaa << endl;
// cout << AAA << endl;
system("pause");
return 0;
}
第三章 数据类型
C++ 规定在创建一个变量或常量时,必须指定出响应的数据类型,否则无法给变量分配内存
一、整型
作用:整型变量表示的是 整数类型 的数据
C++ 中能够表示整型的类型有以下几种方式,区别在于所占内存空间不同:
数据类型 | 占用空间 | 取值范围 |
---|---|---|
short(短整型) | 2字节 | (-2^15 ~ 2^15 - 1) |
int(整型) | 4字节 | (-2^31 ~ 2^31 - 1) |
long(长整型) | Windows为4字节,Linux为4字节(32位),8字节(64位) | (-2^31 ~ 2^31 - 1) |
long long(长长整型) | 8字节 | (-2^63 ~ 2^63 - 1) |
示例:
#include <iostream>
using namespace std;
int main()
{
// 1、短整型 (-32768 ~ 32767)
short num1 = 32768;
// 2、 整型 (-2,147,483,648 ~ 2,147,483,647)
int num2 = 32768;
// 3、长整型 (-2,147,483,648 ~ 2,147,483,647)
long num3 = 10;
// 4、长长整型 (-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807)
long long num4 = 10;
cout << num1 << endl;
cout << num2 << endl;
cout << num3 << endl;
cout << num4 << endl;
system("pause");
return 0;
}
二、sizeof 关键字
作用:利用 sizeof 关键字 可以统计数据类型所占内存大小
语法:sizeof(数据类型 / 变量)
示例:
#include <iostream>
using namespace std;
int main()
{
// 1、短整型 (-32768 ~ 32767)
short num1 = 32768;
// 2、 整型 (-2,147,483,648 ~ 2,147,483,647)
int num2 = 32768;
// 3、长整型 (-2,147,483,648 ~ 2,147,483,647)
long num3 = 10;
// 4、长长整型 (-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807)
long long num4 = 10;
cout << "short 类型所占内训空间为: " << sizeof(short) << endl;
cout << "int 类型所占内训空间为: " << sizeof(int) << endl;
cout << "long 类型所占内训空间为: " << sizeof(long) << endl;
cout << "long long 类型所占内训空间为: " << sizeof(long long) << endl;
cout << "num1 所占内训空间为: " << sizeof(num1) << endl;
cout << "num2 所占内训空间为: " << sizeof(num2) << endl;
cout << "num3 所占内训空间为: " << sizeof(num3) << endl;
cout << "num4 所占内训空间为: " << sizeof(num4) << endl;
system("pause");
return 0;
}
结论:short < int <= long < long long
三、实型(浮点型)
作用:用于表示小数
浮点型变量分为两种:
- 单精度 float
- 双精度 double
两者的区别在于表示的有效数字范围不同
数据类型 | 占用空间 | 有效数字范围 |
---|---|---|
float | 4字节 | 7位有效数字 |
double | 8字节 | 15~16位有效数字 |
示例:
#include <iostream>
using namespace std;
int main()
{
// 1、单精度 float
float f1 = 3.1415926f;
// 2、双精度 double
double d1 = 3.1415927;
// 默认情况下输出一个小数,会显示出6位有效数字
cout << "f1 = " << f1 << "; floatSize = " << sizeof(float) << endl;
cout << "d1 = " << d1 << "; doubleSize = " << sizeof(double) << endl;
// 3、科学计数法
float f2 = 3e2; // 3 * 10 ^ 2
cout << "f2 = " << f2 << endl;
float f3 = 3e-2; // 3 * 0.1 ^ 2
cout << "f3 = " << f3 << endl;
system("pause");
return 0;
}
四、字符型
作用:字符型变量用于显示单个字符
语法:char ch = '1'
注意:在显示字符变量时用单引号括起来,不要用双引号,单引号内只能有一个字符,不可以是字符串
- C 和 C++ 中字符型变量只占用 1个字节
- 字符型变量并不是把字符本身放到内存中存储,而是将对应的 ASCII 编码放到存储单元
示例:
#include <iostream>
using namespace std;
int main()
{
// 1、字符型 char
char ch = 'a';
cout << "ch = " << ch << "; charSize = " << sizeof(char) << endl;
// 2、 字符型变量对应 ASCII 编码
cout << "ch = " << ch << "; charASCII = " << int(ch) << endl;
system("pause");
return 0;
}
五、转义字符
作用:用于表示一些 不能显示出来的 ASCII 字符
现阶段我们常用的转义字符有:\n \\ \t
转义字符 | 含义 | ASCII码值(十进制) |
---|---|---|
\a | 响铃符(报警) | 007 |
\b | 退格符,将光标位置移到下一页开头 | 008 |
\f | 进纸符,将光标位置移到下一页开头 | 012 |
\n | 换行符,将光标位置移到下一行开头 | 010 |
\r | 回车符,将光标位置移到本行开头 | 013 |
\t | 水平制表符,光标跳到下一个Tab位置 | 009 |
\v | 垂直制表符 | 011 |
\\ | 单反斜杠 | 092 |
\' | 单引号 | 039 |
\" | 双引号 | 034 |
? | 问号 | 063 |
\0 | 空字符 | 000 |
\ooo | 用1~3位八进制数 ooo 为码值所对应的字符 | ooo(八进制) |
\xhh | 用1、2位十六进制 hh 为码符所对应的字符 | hh(十六进制) |
示例:
#include <iostream>
using namespace std;
int main()
{
// 转义字符
// 换行符 \n
cout << "Hello World" << endl;
cout << "Hello World\n";
// 反斜杠 \\
cout << "\\" << endl;
// 水平制表符 \t
cout << "C\tHello World" << endl;
cout << "C++\tHello World" << endl;
cout << "Java\tHello World" << endl;
cout << "Python\tHello World" << endl;
system("pause");
return 0;
}
六、字符串型
作用:用于表示一串字符
两种风格:
-
C 风格字符串:
char 变量名[] = "字符串值;"
-
示例:
#include <iostream> using namespace std; int main() { // 字符串型 char str1[] = "Hello World"; cout << str1 << endl; system("pause"); return 0; }
注意:C风格字符串, 需要用 双引号 括起来
-
-
C++ 风格字符串:
string 变量名 = "字符串值;"
-
示例:
#include <iostream> #include <string> // 版本高的可以不用 using namespace std; int main() { // 字符串型 string str = "Hello World"; cout << str << endl; system("pause"); return 0; }
注意:C++ 风格字符串, 需要加入头文件 #include <string> // 版本高的可以不用
-
七、布尔类型
作用:布尔类型类型代表真或假的值
bool 类型只有两个值:
- true --- 真(本质是1)
- false --- 假(本质是0)
bool 类型占 1个字节 大小
示例:
#include <iostream>
using namespace std;
int main()
{
// 布尔类型
bool status = true;
cout << status << endl;
// 重新赋值
status = false;
cout << status << endl;
// 查看占用内存空间
cout << "size of bool = " << sizeof(bool) << endl;
system("pause");
return 0;
}
八、数据的输入
作用:用于键盘获取数据
关键字:cin
语法:cin >> 变量;
示例:
#include <iostream>
using namespace std;
int main()
{
// 数据的输入
// 整型输入
int a = 0;
cout << "请输入整型变量:" << endl;
cin >> a;
cout << a << endl;
// 浮点型输入
double d = 3.14;
cout << "请输入浮点型变量:" << endl;
cin >> d;
cout << d << endl;
// 字符型输入
char c = 'a';
cout << "请输入字符型变量:" << endl;
cin >> c;
cout << c << endl;
// 字符串型输入
string s = "";
cout << "请输入字符串型变量:" << endl;
cin >> s;
cout << s << endl;
// 布尔型输入
bool b = true;
cout << "请输入布尔型变量:" << endl;
cin >> b;
cout << b << endl;
system("pause");
return 0;
}
第四章 运算符
作用:用于执行代码的运算
本章我们主要讲解以下几类运算符
运算符类型 | 作用 |
---|---|
算数运算符 | 用于处理四则运算 |
赋值运算符 | 用于将表达式的值付给变量 |
比较运算符 | 用于表达式的比较,并返回一个真值或假值 |
逻辑运算符 | 用于根据表达式的值返回真值或假值 |
一、算数运算符
作用:用于处理四则运算
算数运算符包括以下符号:
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
+ | 正号 | +3 | 3 |
- | 负号 | -3 | -3 |
+ | 加 | 10 + 5 | 15 |
- | 减 | 10 - 5 | 5 |
* | 乘 | 10 * 5 | 50 |
/ | 除 | 10 / 5 | 2 |
% | 取模(取余) | 10 % 3 | 1 |
++ | 前置递增 | a = 2; b = ++a; | a = 3; b = 3; |
++ | 后置递增 | a = 2; b = a++; | a = 3; b = 2; |
-- | 前置递减 | a = 2; b = --a; | a = 1; b = 1; |
-- | 后置递减 | a = 2; b = a--; | a = 1; b = 2; |
示例:
#include <iostream>
using namespace std;
int main()
{
// 算数运算符
int a1 = 10;
int b1 = 3;
// 加法运算
cout << a1 << " + " << b1 << " = " << a1 + b1 << endl;
// 减法运算
cout << a1 << " - " << b1 << " = " << a1 - b1 << endl;
// 乘法运算
cout << a1 << " × " << b1 << " = " << a1 * b1 << endl;
// 除法运算(两个整数相除,结果依然是整数,将小数部分去除)
cout << a1 << " ÷ " << b1 << " = " << a1 / b1 << endl;
// 取余运算
cout << a1 << " % " << b1 << " = " << a1 % b1 << endl;
// 递增运算 - 前置递增(先让变量 +1 然后进行表达式运算)
int a = 10;
++a;
cout << "++a = " << a << endl;
// 递增运算 - 后置递增(先让表达式运算 后让变量 +1)
int b = 10;
b++;
cout << "b++ = " << b << endl;
// 前置和后置的区别
int a2 = 10;
int b2 = ++a2 * 10;
cout<< "a2 = " << a2 << "; b2 = " << b2 << endl;
int a3 = 10;
int b3 = a3++ * 10;
cout << "a3 = " << a3 << "; b3 = " << b3 << endl;
system("pause");
return 0;
}
二、赋值运算符
作用:用于将表达式的值赋给变量
赋值运算符包括以下几个符号
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
= | 赋值 | a = 2; b = 3; | a = 2; b = 3; |
+= | 加等于 | a = 0; a += 2; | a = 2; |
-= | 减等于 | a = 5; a -= 3; | a = 2; |
*= | 乘等于 | a = 2; a *= 2; | a = 4; |
/= | 除等于 | a = 4; a /= 2; | a = 2; |
%= | 模等于 | a = 3; a %= 2; | a = 1; |
示例:
#include <iostream>
using namespace std;
int main()
{
// 赋值运算符
// =
int a = 10;
a = 100;
cout << "a = " << a << endl;
// +=
a = 10;
a += 2; // a = a + 2
cout << "a = " << a << endl;
// -=
a = 10;
a -= 2; // a = a + 2
cout << "a = " << a << endl;
// *=
a = 10;
a *= 2; // a = a * 2
cout << "a = " << a << endl;
// /=
a = 10;
a /= 2; // a = a / 2
cout << "a = " << a << endl;
// %=
a = 10;
a %= 3; // a = a % 3
cout << "a = " << a << endl;
system("pause");
return 0;
}
三、比较运算符
作用:用于表达式的比较,并返回一个真值或假值
比较运算符有以下符号:
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
== | 等于 | 4 == 3 | 0 |
!= | 不等于 | 4 != 3 | 1 |
< | 小于 | 4 < 3 | 0 |
> | 大于 | 4 > 3 | 1 |
<= | 小于等于 | 4 <= 3 | 0 |
>= | 大于等于 | 4 >= 3 | 1 |
示例:
#include <iostream>
using namespace std;
int main()
{
// 比较运算符
int a = 10;
int b = 20;
// ==
cout << a << " == " << b << " = " << (a == b) << endl;
// !=
cout << a << " != " << b << " = " << (a != b) << endl;
// <
cout << a << " < " << b << " = " << (a < b) << endl;
// >
cout << a << " < " << b << " = " << (a < b) << endl;
// <=
cout << a << " <= " << b << " = " << (a <= b) << endl;
// >=
cout << a << " >= " << b << " = " << (a >= b) << endl;
system("pause");
return 0;
}
四、逻辑运算符
作用:用于根据表达式的值返回真值或假值
逻辑运算符有以下符号:
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
! | 非 | !a | 如果 a 为假,则 !a 为真;反之 !a 为假 |
&& | 与 | a && b | 如果 a 和 b 都为真,则结果为真;反之为假 |
|| | 或 | a || b | 如果 a 或 b 为真,则结果为真;反之为假 |
示例:
#include <iostream>
using namespace std;
int main()
{
// 逻辑运算符
// 非 真变假,假变真
int a = 10;
cout << "\n 非运算:" << endl;
cout << " !a = " << !a << endl;
cout << " !!a = " << !!a << endl;
// 与
cout << "\n 与运算:" << endl;
int a1 = 10;
int b1 = 10;
cout << a1 << " && " << b1 << " = " << (a1 && b1) << endl;
a1 = 0;
cout << a1 << " && " << b1 << " = " << (a1 && b1) << endl;
b1 = 0;
cout << a1 << " && " << b1 << " = " << (a1 && b1) << endl;
// 或
cout << "\n 或运算:" << endl;
int a2 = 10;
int b2 = 10;
cout << a2 << " || " << b2 << " = " << (a2 || b2) << endl;
a2 = 0;
cout << a2 << " || " << b2 << " = " << (a2 || b2) << endl;
b2 = 0;
cout << a2 << " || " << b2 << " = " << (a2 || b2) << endl;
system("pause");
return 0;
}
第五章 程序流程解构
C/C++支持最基本的三种程序运行结构:顺序结构、选择结构、循环结构
- 顺序结构:程序按顺序执行,不发生跳转
- 选择结构:依据条件是否满足,有选择的执行相应功能
- 循环结构:依据条件是否满足,循环多次执行某段代码
一、选择结构
1、if 语句
作用:执行满足条件的语句
if 语句的三种形式:
- 单行格式 if 语句
- 多行格式 if 语句
- 多条件的 if 语句
(1) 单行格式 if 语句
语法:
if (条件)
{
// 条件满足执行的语句
}
示例:
#include <iostream>
using namespace std;
int main()
{
// 选择结构 单行格式 if 语句
// 输入一个分数,如果分数大于 600 分 视为开上一本大学,并在屏幕上打印
int score = 0;
cout << "请输入考生分数:" << endl;
cin >> score;
cout << "该考生分数:" << score << endl;
// if 条件后边不要写分号 if (score > 600);
if (score > 600)
{
cout << "恭喜您考上了一本大学!!!" << endl;
}
system("pause");
return 0;
}
(2) 多行格式 if 语句
语法:
if (条件)
{
// 执行满足条件的代码块
}
else
{
// 执行不满足条件的代码块
}
示例:
#include <iostream>
using namespace std;
int main()
{
// 选择结构 多行格式 if 语句
/* 输入一个分数
大于 600 - 恭喜您考上了一本大学!!!
小于 600 - 很遗憾您没有考上一本大学!!!
*/
int score = 0;
cout << "请输入考生分数:" << endl;
cin >> score;
cout << "该考生分数:" << score << endl;
if (score > 600)
{
cout << "恭喜您考上了一本大学!!!" << endl;
}
else
{
cout << "很遗憾您没有考上一本大学!!!" << endl;
}
system("pause");
return 0;
}
(3) 多条件的 if 语句
语法:
if (条件1)
{
// 满足 条件1 执行的代码块
}
else if (条件2)
{
// 满足 条件2 执行的代码块
}
...
else
{
// 以上条件都不满足执行的代码块
}
示例:
#include <iostream>
using namespace std;
int main()
{
// 选择结构 多条件的 if 语句
/*
输入一个分数
大于 600 - 一本
大于 500 - 二本
大于 400 - 三本
小于 400 - 回去喂猪
*/
int score = 0;
cout << "请输入考生分数:" << endl;
cin >> score;
cout << "该考生分数:" << score << endl;
if (score > 600)
{
cout << "恭喜您考上了一本大学!!!" << endl;
}
else if (score > 500)
{
cout << "恭喜您考上了二本大学!!!" << endl;
}
else if (score > 400)
{
cout << "恭喜您考上了三本大学!!!" << endl;
}
else
{
cout << "恭喜您可以回去喂猪了!!!" << endl;
}
system("pause");
return 0;
}
(4) 嵌套 if 语句
在 if 语句中,可以嵌套使用 if 语句,达到更精确的条件判断
案例需求:
- 提示用户输入一个高考分数,根据分数做出如下判断
- 分数如果大于 600 分视为考上一本,大于 500 分考上二本,大于 400 分考上三本,其余视为未考上本科
- 在一本分数中,如果大于 700 分,考入北大, 大于 650 分,考入清华,大于 600 分,考入西安电子科技大学
示例:
#include <iostream>
using namespace std;
int main()
{
int score = 0;
cout << "请输入考生分数:" << endl;
cin >> score;
cout << "该考生分数:" << score << endl;
if (score > 600)
{
if (score > 700)
{
cout << "恭喜您考入北京大学!!!" << endl;
}
else if (score > 650)
{
cout << "恭喜您考入清华大学!!!" << endl;
}
else
{
cout << "恭喜您考入西安电子科技大学!!!" << endl;
}
}
else if (score > 500)
{
cout << "恭喜您考上了二本大学!!!" << endl;
}
else if (score > 400)
{
cout << "恭喜您考上了三本大学!!!" << endl;
}
else
{
cout << "恭喜您可以回去喂猪了!!!" << endl;
}
system("pause");
return 0;
}
(5) 课后练习
三只小猪称体重
有三只小猪 ABC,分别输入三只小猪的体重,并且判断哪只小猪最重
案例:
#include <iostream>
using namespace std;
int main()
{
// 创建三只小猪的体重变量
int pig1 = 0;
int pig2 = 0;
int pig3 = 0;
// 输入三只小猪的重量
cout << "请输入小猪A的体重:" << endl;
cin >> pig1;
cout << "请输入小猪B的体重:" << endl;
cin >> pig2;
cout << "请输入小猪C的体重:" << endl;
cin >> pig3;
// 打印小猪的重量
cout << "小猪A的体重为:" << pig1 << endl;
cout << "小猪B的体重为:" << pig2 << endl;
cout << "小猪C的体重为:" << pig3 << endl;
if (pig1 > pig2) // A > B
{
if (pig1 > pig3) // A > C
{
cout << "小猪A是最重的!!!" << endl;
}
else // A < C
{
cout << "小猪C是最重的!!!" << endl;
}
}
else // A < B
{
if (pig2 > pig3) // B > C
{
cout << "小猪B是最重的!!!" << endl;
}
else // B < C
{
cout << "小猪C是最重的!!!" << endl;
}
}
system("pause");
return 0;
}
2、三目运算符
作用:通过三木运算符实现简单的判断
语法:表达式1 ? 表达式2 : 表达式3;
解释:
- 如果表达式1的值为真,执行表达式2,并返回表达式2的结果
- 如果表达式1的值为假,执行表达式3,并返回表达式3的结果
示例:
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int b = 20;
int c = 0;
c = a > b ? a : b;
cout << "c = " << c << endl;
// C++ 中三目运算符返回的是变量,可以继续赋值
(a > b ? a : b) = 100;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
system("pause");
return 0;
}
3、switch 语句
作用:执行多条件分支语句
语法:
switch (表达式)
{
case 结果1 : 执行语句; break;
case 结果2 : 执行语句; break;
...
default : 执行语句; break;
}
示例:
#include <iostream>
using namespace std;
int main()
{
// switch 给电影打分
// 10 ~ 9 经典
// 8 ~ 7 非常好
// 6 ~ 5 一般
// 5 以下 垃圾
// 1. 提示用户给电影评分
cout << "请给《上海堡垒》这部电影打分:" << endl;
// 用户开始进行打分
int score = 0;
cin >> score;
cout << "您给《上海堡垒》这部电影打的分数为:" << score << endl;
switch (score)
{
case 10:
case 9:
cout << "您认为《上海堡垒》这部电影是经典电影" << endl;
break;
case 8:
case 7:
cout << "您认为《上海堡垒》这部电影非常好" << endl;
break;
case 6:
case 5:
cout << "您认为《上海堡垒》这部电影一般" << endl;
break;
default:
cout << "您认为《上海堡垒》这部电影是一部烂片" << endl;
break;
}
system("pause");
return 0;
}
switch 缺点:判断的时候只能是整型或者字符型,不可以是一个区间
switch 优点:结构清晰,执行效率高
二、循环结构
1、while 循环语句
作用:满足循环条件,执行循环语句
语法:while (条件) {循环语句}
解释:只要循环条件结果为真,就执行循环语句
示例:
#include <iostream>
using namespace std;
int main()
{
// while 循环语句
// 在屏幕中打印 0 ~ 9 这是个数
int num = 0;
while (num <= 9)
{
cout << num << endl;
num++;
}
system("pause");
return 0;
}
课后练习:
案例描述:系统随机生成 1 ~ 100 之间的数字,玩家猜测,如果猜错,提示玩家数字过大或过小,如果猜对恭喜玩家胜利,并且退出游戏
#include <iostream>
// #include <ctime> 老版本需要导入
using namespace std;
int main()
{
// 添加随机数种子 作用利用当前系统时间生成随机数,防止每次随机数都一样
srand((unsigned int)time(NULL));
// 1、系统生成随机数
int num = rand() % 100 + 1; // rand()%100 + 1 生成 0 + 1 ~ 99 + 1 随机数
cout << "随机生成的数字为: " << num << endl;
// 2、玩家进行猜测
int input_num = 0;
while (true)
{
cout << "请输入您猜测的数字: ";
cin >> input_num;
// 3、判断玩家的猜测
// 猜对 退出游戏
// 猜错 提示猜的结果 过大或者过小 重新返回第2步
if (input_num == num)
{
cout << "恭喜您猜对了!!!" << endl;
break;
}
else if (input_num > num)
{
cout << "您输入的数字太大了!!!" << endl;
}
else {
cout << "您输入的数字太小了!!!" << endl;
}
}
system("pause");
return 0;
}
2、do...while 循环语句
作用:满足循环条件,执行循环语句
语法:do { 循环语句 } while (循环条件)
注意:与 while 的区别在于 do...while会先执行一次循环语句,在判断循环条件
示例:
#include <iostream>
using namespace std;
int main()
{
// do...while 循环语句
int num = 0;
do
{
cout << num << endl;
num++;
}
while (num < 10);
system("pause");
return 0;
}
课后练习:
案例描述:水仙花数是指一个三位数,它的每个位上的数字的3次幂之和等于它本身
例如:1^3 + 5^3 + 3^3 = 153
请利用 do...while 语句,求出三位数中的水仙花数
#include <iostream>
using namespace std;
int main()
{
// 请利用 do...while 语句,求出三位数中的水仙花数
int num = 100;
do
{
// 获取个位数
int ones = num % 10;
// 获取十位数
int tens = (num / 10) % 10;
// 获取百位数
int hundreds = num / 100;
// 判断是否是水仙花数
if (hundreds * hundreds * hundreds + tens * tens * tens + ones * ones * ones == num)
{
cout << num << " 是一个水仙花数!!!" << endl;
}
num++;
}
while (num < 1000);
system("pause");
return 0;
}
3、for 循环语句
作用:满足循环条件,执行循环语句
语法:for (其实表达式; 条件表达式; 末尾循环体) {循环语句;}
示例:
#include <iostream>
using namespace std;
int main()
{
// for 循环语句 输出 0 ~ 9
for (int i = 0; i < 10; i++)
{
cout << i << endl;
}
system("pause");
return 0;
}
注意:for循环中的表达式,要用分号进行分隔
总结 while、do...while、for 都是开发中常用的循环语句,for循环结构比较清晰,比较常用
课后练习:
案例描述:从1开始数到数字 100,如果数字个位含有7,或者十位数字含有 7,或者该数字是 7 的倍数,我们打印敲桌子,其余数字直接打印输出
#include <iostream>
using namespace std;
int main()
{
// 从1开始数到数字 100,如果数字个位含有7,或者十位数字含有 7,或者该数字是 7 的倍数,我们打印敲桌子,其余数字直接打印输出
for (int i = 1; i < 100; i++)
{
if (i % 10 == 7 || i / 10 == 7 || i % 7 == 0)
{
cout << "敲桌子!!!" << endl;
}
else
{
cout << i << endl;
}
}
system("pause");
return 0;
}
4、嵌套循环
作用:在循环体重在嵌套一层循环,解决一些实际问题
示例:
#include <iostream>
using namespace std;
int main()
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
cout << "* ";
}
cout << endl;
}
system("pause");
return 0;
}
课后练习
案例描述:九九乘法表
#include <iostream>
using namespace std;
int main()
{
// 九九乘法表
for (int i = 1; i < 10; i++)
{
for (int j = 1; j <= i; j++)
{
cout << j << " × " << i << " = " << j * i << "; ";
}
cout << endl;
}
system("pause");
return 0;
}
三、循环控制语句
1、break 语句
作用:用于跳出 选择结构 或者 循环结构
break 使用的时机:
- 在 switch 条件语句中,作用是终止 case 并跳出 switch
- 出现在循环语句中,作用是跳出当前循环的语句
- 出现在嵌套循环中,跳出最近的内层循环语句
示例1:
#include <iostream>
using namespace std;
int main()
{
// 在 switch 语句中使用 break
cout << "请选择您挑战的副本难度:\n 1、普通 \n 2、中等 \n 3、困难" << endl;
int select = 0;
cin >> select;
switch (select)
{
case 1:
cout << "您挑战的副本难度为: 普通" << endl;
break;
case 2:
cout << "您挑战的副本难度为: 中等" << endl;
break;
default:
cout << "您挑战的副本难度为: 困难" << endl;
break;
}
system("pause");
return 0;
}
示例2:
#include <iostream>
using namespace std;
int main()
{
for (int i = 0; i < 10; i++)
{
if (i == 5)
{
break;
}
cout << i << endl;
}
system("pause");
return 0;
}
示例3:
#include <iostream>
using namespace std;
int main()
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (j == 5)
{
break;
}
cout << "* ";
}
cout << endl;
}
system("pause");
return 0;
}
示例4:
#include <iostream>
using namespace std;
int main()
{
int num = 0;
while (true)
{
if (num == 5)
{
break;
}
cout << num << endl;
num++;
}
system("pause");
return 0;
}
2、continue 语句
作用:在循环语句中,跳过本次循环中余下尚未执行的语句,继续执行下一次循环
示例:
#include <iostream>
using namespace std;
int main()
{
for (int i = 0; i < 100; i++)
{
if (i % 2 == 0)
{
continue;
}
cout << i << endl;
}
system("pause");
return 0;
}
3、goto 语句
作用:可以无条件跳转语句
语法:goto 标记;
示例:
#include <iostream>
using namespace std;
int main()
{
cout << "1" << endl;
goto FLAG;
cout << "2" << endl;
cout << "3" << endl;
cout << "4" << endl;
FLAG:
cout << "5" << endl;
system("pause");
return 0;
}
注意:在程序中不建议使用 goto 语句,一面造成程序混乱
第六章 数组
一、概述
所谓数组,就是一个集合,里面存放了相同类型的数据元素
特点:
- 数组中的每个 数据元素都是相同的数据类型
- 数组是由 连续的内存 位置组成的
二、一维数组
1、一维数组定义方式
一维数组定义的三种方式:
- 数据类型 数组名[数组长度];
- 数据类型 数组名[数组长度] = { 值1, 值2, ... };
- 数据类型 数组名[ ] = { 值1, 值2, ... };
示例:
#include <iostream>
using namespace std;
int main()
{
// 定义方式1: 数据类型 数组名[数字长度];
cout << "定义方式1: 数据类型 数组名[数字长度];" << endl;
int scores[5];
// 利用下标赋值
scores[0] = 100;
scores[1] = 90;
scores[2] = 80;
scores[3] = 70;
scores[4] = 60;
for (int i = 0; i < 5; i++)
{
cout << scores[i] << endl;
}
// 定义方式2:数据类型 数组名[数组长度] = { 值1, 值2, ... };
cout << "\n定义方式2:数据类型 数组名[数组长度] = { 值1, 值2, ... };" << endl;
// int ages[5] = { 10, 23, 31 };
int ages[5] = { 10, 23, 31, 64, 18 };
for (int i = 0; i < 5; i++)
{
cout << ages[i] << endl;
}
// 定义方式3:数据类型 数组名[] = { 值1, 值2, ... };
cout << "\n定义方式3:数据类型 数组名[ ] = { 值1, 值2, ... };" << endl;
string names[] = { "波多野结衣", "三上悠亚", "桥本有菜", "河北彩花", "苍井空", "小泽玛利亚" };
for (int i = 0; i < 6; i++)
{
cout << names[i] << endl;
}
system("pause");
return 0;
}
总结:
- 数组名的命名规范与变量名命名规范一致,不要和变量重名
- 数组中的下标从 0 开始索引
2、一维数组数组名
用途:
- 可以统计整个数组在内存中的长度
- 可以获取数组在内存中的首地址
示例:
#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;
cout << "数组中第二个元素的首地址为: " << (int)&arr[1] << endl;
// arr = 100; 数组名是常量,不可以进行赋值操作
system("pause");
return 0;
}
课后练习:
案例一:五只小猪称体重
案例描述:在一个数组中记录了五只小猪的体重,如:int arr[5] = { 300, 350, 200, 400, 500 }; 找出并打印最重的小猪体重
int main()
{
// 定义一个最大值变量
int max = 0;
// 创建5只小猪体重的数组
int arr[5] = { 300, 350, 200, 400, 250 };
// 循环数组更新最大值
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
if (max < arr[i])
{
max = arr[i];
}
else
{
continue;
}
}
cout << "最重的小猪体重为: " << max << endl;
system("pause");
return 0;
}
案例二:数组元素逆置
案例描述:请生命一个5个元素的数组,并将元素逆置(如原数组元素为:1,3,2,5,4;逆置后输出结果为:4,5,2,3,1)
#include <iostream>
using namespace std;
int main()
{
// 定义数组
int arr[5] = { 1, 3, 2, 5, 4 };
// 定义起始元素下标
int start_index = 0;
// 定义结尾元素下标
int end_index = sizeof(arr) / sizeof(arr[0]) - 1;
cout << "数组逆置前:[";
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
if (i == sizeof(arr) / sizeof(arr[0]) - 1)
{
cout << arr[i] << "]";
}
else
{
cout << arr[i] << ", ";
}
}
cout << endl;
// 数组逆置
while (start_index < end_index)
{
// 定义一个临时变量
int temp = arr[start_index];
// 实现元素互换
arr[start_index] = arr[end_index];
arr[end_index] = temp;
// 更新下标
start_index++;
end_index--;
}
// 打印逆置后的数组
cout << "数组逆置后:[";
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
if (i == sizeof(arr) / sizeof(arr[0]) - 1)
{
cout << arr[i] << "]";
}
else
{
cout << arr[i] << ", ";
}
}
cout << endl;
system("pause");
return 0;
}
3、排序算法
(1) 冒泡排序
作用:最常用的排序算法,对数组内元素进行排序
- 比较相邻的元素,如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素做同样的工作,执行完毕后,找到第一个最大值
- 重复以上步骤,每次比较次数 -1,直到不需要比较
示例:将数组 { 3,2,8,0,5,7,1,3,9 } 进行升序排序
#include <iostream>
using namespace std;
int main()
{
// 将数组 { 3,2,8,0,5,7,1,3,9 } 进行升序排序
int arr[9] = { 3,2,8,0,5,7,1,3,9 };
int arr_length = sizeof(arr) / sizeof(arr[0]);
cout << "数组排序前:[";
for (int i = 0; i < arr_length; i++)
{
if (i == arr_length - 1)
{
cout << arr[i] << "]";
}
else
{
cout << arr[i] << ", ";
}
}
cout << endl;
// 数据排序
for (int i = 0; i < arr_length; i++)
{
for (int j = 0; j < arr_length -1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
cout << "数组排序后:[";
for (int i = 0; i < arr_length; i++)
{
if (i == arr_length - 1)
{
cout << arr[i] << "]";
}
else
{
cout << arr[i] << ", ";
}
}
cout << endl;
system("pause");
return 0;
}
三、二维数组
二维数组就是 在一维数组上多加了一个纬度。
1、二维数组定义方式
二维数组定义的4种方式:
数据类型 数组名[行数][列数];
数据类型 数组名[行数][列数] = {{数据1, 数据2}, {数据3, 数据4}};
数据类型 数组名[行数][列数] = {数据1, 数据2, 数据3, 数据4};
数据类型 数组名[][列数] = {{数据1, 数据2}, {数据3, 数据4}};
建议:以上四种定义方式,利用 第二种更加直观,提高代码的可读性
示例:
#include <iostream>
using namespace std;
int main()
{
// 二维数组的定义方式
/*
1. 数据类型 数组名[行数][列数];
2. 数据类型 数组名[行数][列数] = {{数据1, 数据2}, {数据3, 数据4}};
3. 数据类型 数组名[行数][列数] = {数据1, 数据2, 数据3, 数据4};
4. 数据类型 数组名[][列数] = { 数据1, 数据2, 数据3, 数据4 };
*/
// 方式1:数据类型 数组名[行数][列数];
int arr1[2][3];
arr1[0][0] = 1;
arr1[0][1] = 2;
arr1[0][2] = 3;
arr1[1][0] = 4;
arr1[1][1] = 5;
arr1[1][2] = 6;
// cout << arr1[0][0] << endl;
// cout << arr1[0][1] << endl;
// cout << arr1[0][2] << endl;
// cout << arr1[1][0] << endl;
// cout << arr1[1][1] << endl;
// cout << arr1[1][2] << endl;
// 外层循环打印行数,内层循环打印列数
for (int i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++)
{
for (int j = 0; j < sizeof(arr1[0]) / sizeof(arr1[0][0]); j++)
{
cout << arr1[i][j] << endl;
}
}
cout << endl;
// 方式2:数据类型 数组名[行数][列数] = {{数据1, 数据2}, {数据3, 数据4}};
int arr2[2][3] = {
{1,2,3},
{4,5,6}
};
// 外层循环打印行数,内层循环打印列数
for (int i = 0; i < sizeof(arr2) / sizeof(arr2[0]); i++)
{
for (int j = 0; j < sizeof(arr2[0]) / sizeof(arr2[0][0]); j++)
{
cout << arr2[i][j] << endl;
}
}
cout << endl;
// 方式3:数据类型 数组名[行数][列数] = { 数据1, 数据2, 数据3, 数据4 };
int arr3[2][3] = { 1,2,3,4,5,6 };
// 外层循环打印行数,内层循环打印列数
for (int i = 0; i < sizeof(arr3) / sizeof(arr3[0]); i++)
{
for (int j = 0; j < sizeof(arr3[0]) / sizeof(arr3[0][0]); j++)
{
cout << arr3[i][j] << endl;
}
}
cout << endl;
// 方式4:数据类型 数组名[][列数] = { 数据1, 数据2, 数据3, 数据4 };
int arr4[][3] = { 1,2,3,4,5,6 };
// 外层循环打印行数,内层循环打印列数
for (int i = 0; i < sizeof(arr4) / sizeof(arr4[0]); i++)
{
for (int j = 0; j < sizeof(arr4[0]) / sizeof(arr4[0][0]); j++)
{
cout << arr4[i][j] << endl;
}
}
system("pause");
return 0;
}
2、二维数组数组名
- 查看二维数组所占内存空间
- 获取二维数组首地址
示例:
#include <iostream>
using namespace std;
int main()
{
// 二维数组数组名
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;
// 查看二维数组的首地址
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;
system("pause");
return 0;
}
课后练习:
案例描述:有三名同学(张三,李四,王五),再一次考试中的成绩分别如下表,请分别输出三名同学的总成绩
姓名 | 语文 | 数学 | 英语 |
---|---|---|---|
张三 | 100 | 100 | 100 |
李四 | 90 | 50 | 100 |
王五 | 60 | 70 | 80 |
示例:
#include <iostream>
using namespace std;
int main()
{
string names[3] = { "张三" , "李四", "王五" };
int scores[3][3] = {
{100,100,100},
{90,50,100},
{60,70,80}
};
for (int i = 0; i < sizeof(scores) / sizeof(scores[0]); i++)
{
int total_score = 0;
for (int j = 0; j < sizeof(scores[0]) / sizeof(scores[0][0]); j++)
{
total_score += scores[i][j];
}
cout << "学生: " << names[i] << " 成绩总分为:" << total_score << endl;
}
system("pause");
return 0;
}
第七章 函数
一、概述
作用:将一段经常使用的代码封装起来,减少重复代码
一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能
二、函数的定义
函数的定义一般主要有 5个 步骤‘
- 返回值类型:一个函数可以返回一个值,在函数定义中
- 函数名:给函数起个名称
- 参数列表:使用该函数时,传入的数据
- 函数体语句:花括号内的代码,函数内需要执行的语句
- return 表达式:和返回值类型挂钩,函数执行完成后,返回响应的数据
语法:
返回值类型 函数名 (参数列表)
{
/*
函数体语句
...
*/
return 表达式;
}
示例:
#include <iostream>
using namespace std;
// 实现一个加法函数,功能是,传入两个整数数据,计算数据相加的结果,并返回
int add(int num1, int num2)
{
int sum = num1 + num2;
return sum;
}
三、函数的调用
功能:使用定义好的函数
语法:函数名(参数)
示例:
#include <iostream>
using namespace std;
// 实现一个加法函数,功能是,传入两个整数数据,计算数据相加的结果,并返回
// num1, num2 称为形式参数,简称形参
int add(int num1, int num2)
{
int sum = num1 + num2;
return sum;
}
int main()
{
// 定义两个 int类型的变量,变量名随便
int num1 = 10;
int num2 = 20;
// 调用 add 函数 调用时的 num1, num2 称为实际参数,简称实参,调用函数时,实参的值会传递给形参
int sum = add(num1, num2);
cout << sum << endl;
system("pause");
return 0;
}
总结:函数定义力小括号内称为形参,函数调用时传入的参数称为实参
四、值传递
- 所谓值传递,就是函数调用时实参将值传入给形参
- 值传递时,如果形参发生变化,并不会影响实参
示例:
#include <iostream>
using namespace std;
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; 返回值不需要的时候,可以不写
}
int main()
{
//调用函数
int num1 = 10;
int num2 = 20;
swap(num1, num1);
cout << "实参:" << endl;
cout << "num1 = " << num1 << endl;
cout << "num2 = " << num2 << endl;
system("pause");
return 0;
}
五、函数的常见样式
常见的函数样式有四种
- 无参无返
- 有参无返
- 无参有返
- 有参有返
示例:
#include <iostream>
using namespace std;
// 函数常见样式
// 1.无参无返
void func01()
{
// void a = 10; // 无类型不可以创建变量,原因:无法分配内存
cout << "this is func01" << endl;
// funt01(); 函数调用
}
// 2.有参无返
void func02(int a)
{
cout << "this is func02 参数a = " << a << endl;
// funt02(100); 函数调用
}
// 3.无参有返
int func03()
{
cout << "this is func03" << endl;
return 100;
// funt03(); 函数调用
}
// 4.有参有返
int func04(int a)
{
cout << "this is func04 参数a = " << a << endl;
return a + 100;
// funt03(100); 函数调用
}
int main()
{
// 无参无返调用函数
func01();
// 有参无返调用函数
func02(100);
// 无参有返调用函数
cout << func03() << endl;
// 有参有返调用函数
cout << func04(100) << endl;
system("pause");
return 0;
}
六、函数的声明
作用:告诉编译器函数名称及如何调用函数。函数的时机主体可以单独定义
- 函数的声明可以多次,但是函数的定义只能有一次
示例:
#include <iostream>
using namespace std;
// 函数的生命
// 声明可以多次,定义只能一次
// 声明:
int max(int a, int b);
int max(int a, int b);
// 定义:
int max(int a, int b)
{
return a > b ? a : b;
}
int main()
{
cout << max(88, 66) << endl;
cout << max(66, 88) << endl;
system("pause");
return 0;
}
总结:提前告诉编译器函数的存在,可以利用函数的生命
函数定义之后,函数的生命可以卸载调用函数之后
七、函数的分文件填写
作用:让带吗结构更加清晰
函数份文件编写一般有四个步骤
- 创建后缀名为.h的头文件
- 创建后缀名为.cpp的源文件
- 在头文件中写函数的声明
- 在源文件中写函数的定义
示例:
-
swap.h 文件
#include <iostream> using namespace std; // 函数的声明 void swap(int a, int b);
-
swap.cpp 文件
#include "swap.h" // 函数的定义 void swap(int a, int b) { cout << "交换前:" << endl; cout << "a = " << a << endl; cout << "b = " << b << endl; int temp = a; a = b; b = temp; cout << "交换后:" << endl; cout << "a = " << a << endl; cout << "b = " << b << endl; }
-
main.cpp
#include <iostream> using namespace std; #include "swap.h" int main() { swap(88, 66); swap(66, 88); system("pause"); return 0; }
第八章 指针(重点)
一、指针的基本概念
指针的作用:可以通过指针间接访问内存
- 内存编号是从 0 开始记录的,一般用十六进制数字表示
- 可以利用指针变量保存地址
二、指针变量的定义和使用
指针变量定义语法:数据类型 * 变量名
示例:
#include <iostream>
using namespace std;
int main()
{
// 1、定义指针
int a = 10;
// 指针定义的语法:数据类型 * 指针变量
int* p;
// 让指针记录变量 a 的地址
p = &a;
cout << "a 的地址为:" << &a << endl;
cout << "指针 p 为:" << p << endl;
// 2、使用指针
// 可以通过解引用的方式来找到指针指向的内存
// 指针前加 * 代表解引用,找到指针指向的内存中的数据
cout << "a = " << a << endl;
cout << "*p = " << *p << endl;
system("pause");
return 0;
}
三、指针所占内存空间
提问:指针也是中数据类型,name这种数据类型占用多少内存空间?
示例:
#include <iostream>
using namespace std;
int main()
{
int a = 10;
// int* p;
// p = &a; // 指针指向数据a的内存地址
int* p = &a; // 等价上边的两行代码
// 32位操作系统下,指针占用4个字节空间大小,64位操作系统下,指针占用8个字节空间大小(不管是什么数据类型)
cout << "*p = " << *p << endl; // * 解引用
cout << "int 指针大小为:" << sizeof(p) << endl;
cout << "char 指针大小为:" << sizeof(char *) << endl;
cout << "float 指针大小为:" << sizeof(float *) << endl;
cout << "double 指针大小为:" << sizeof(double *) << endl;
system("pause");
return 0;
}
四、空指针和野指针
空指针:指针变量指向内存中编号为 0 的内存空间
用途:初始化指针变量
注意:空指针指向的内存是不可能访问的
1、空指针
指针变量 p 指向 内存地址编号为 0 的空间
#include <iostream>
using namespace std;
int main()
{
// 指针变量 p 指向 内存地址编号为 0 的空间
int* p = NULL;
// 访问空指针报错
// 内存编号 0 ~ 255 为系统占用内存,不允许用户访问
cout << *p << endl;
system("pause");
return 0;
}
2、野指针
指针变量指向非法的内存空间
#include <iostream>
using namespace std;
int main()
{
// 指针变量 p 指向 内存地址编号为 0x1100 的空间
int* p = (int *)0x1100;
// 访问野指针报错
cout << *p << endl;
system("pause");
return 0;
}
五、const 修饰指针
const 修饰指针的有三种情况:
- const 修饰指针 -- 常量指针
- const 修饰常量 -- 指针常量
- const 即修饰指针,又修饰常量
示例:
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int b = 10;
// 1、const 修饰的是指针,指针指向可以修改,指针指向的值不可以更改
const int* p1 = &a;
p1 = &b; // 修改指针指向
// *p1 = 100; 报错
cout << *p1 << endl;
// 2、const 修饰的是常量,指针指向不可以修改,指针指向的值可以更改
int* const p2 = &a;
// p2 = &b; 报错
*p2 = 100;
cout << *p2 << endl;
// 3、const 即修饰指针,又修饰常量, 指针和指针指向的值都不可以修改
const int* const p3 = &a;
// p3 = &b; 报错
// *p3 = 100; 报错
cout << *p3 << endl;
system("pause");
return 0;
}
六、指针和数组
作用:利用指针访问数组中的元素
示例:
#include <iostream>
using namespace std;
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int* p = arr; // 指向数组的指针
cout << "第一个元素:" << arr[0] << endl;
cout << "指针访问第一个元素:" << *p << endl;
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
// 利用循环遍历指针数组
cout << *p << endl;
p++;
}
system("pause");
return 0;
}
七、指针和函数
作用:利用指针作为函数参数,可以修改实参的值
示例:
#include <iostream>
using namespace std;
// 值传递
void swap01(int a, int b)
{
int temp = a;
a = b;
b = temp;
cout << "swap01 a = " << a << endl;
cout << "swap01 b = " << b << endl;
}
// 地址传递
void swap02(int * p1, int * p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
cout << "swap02 a = " << *p1 << endl;
cout << "swap02 b = " << *p2 << endl;
}
int main()
{
int a = 10;
int b = 20;
// 值传递 不会改变实参
swap01(a, b);
cout << "execute swap01 after a = " << a << endl;
cout << "execute swap01 after b = " << b << endl;
// 指针传递 会改变实参
swap02(&a, &b);
cout << "execute swap02 after a = " << a << endl;
cout << "execute swap02 after b = " << b << endl;
system("pause");
return 0;
}
总结:如果不想修改实参,就用值传递,如果想修改实参,就用指针传递
八、指针&数组&函数
案例描述:封装一个函数利用冒泡排序,实现对整数数组的升序排序
例如数组:int arr[10] = {4,3,6,9,1,2,10,8,7,5};
示例:
#include <iostream>
using namespace std;
// 地址传递 int* arr 也可以写成 int arr[]
void bubbleSort(int* arr, int len)
{
// 数据排序
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len - 1 - i; j++)
{
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)
{
cout << ":[";
for (int i = 0; i < len; i++)
{
if (i == len - 1)
{
cout << arr[i] << "]";
}
else
{
cout << arr[i] << ", ";
}
}
cout << endl;
}
int main()
{
int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
int len = sizeof(arr) / sizeof(arr[0]);
// 调用打印方法
cout << "数组排序前";
printArray(arr, len);
// 调用排序算法
bubbleSort(arr, len);
// 调用打印方法
cout << "数组排序前";
printArray(arr, len);
system("pause");
return 0;
}
第九章 结构体
一、结构体基本概念
结构体属于用户 自定义的数据类型,允许用户存储不同的数据类型
二、结构体定义和使用
语法:struct 结构体名 { 结构体成员列表 };
通过结构体创建变量的方式有三种:
- struct 结构体名 变量名
- struct 结构体名 变量名
- 定义结构体是顺便创建变量
示例:
#include <iostream>
using namespace std;
// 结构体定义 - 自定义数据类型就是一些基础类型的集合
// 1、定义老师数据类型
struct Teacher
{
// 成员列表
string name; // 姓名
int age; // 年龄
char gender; // 性别
float score; // 分数
bool status; // 状态
}s3;
int main()
{
// 2、通过老师类型创建具体学生
// 2.1 struct Teacher s1
// C++ 中 结构体创建时 struct 关键字可以省略
struct Teacher s1;
// 给 s1 属性赋值, 通过 . 访问结构体变量中的属性
s1.name = "桥本有菜";
s1.age = 18;
s1.gender = 'F';
s1.score = 18.8f;
s1.status = true;
cout << "姓名:" << s1.name << "; 性别:" << s1.gender << "; 年龄:" << s1.age << "岁; 分数:" << s1.score << "; 状态:" << s1.status << endl;
// 2.2 struct Teacher s2 = {...}
struct Teacher s2 = {
"三上悠亚",
22,
'F',
16.2f,
false
};
cout << "姓名:" << s2.name << "; 性别:" << s2.gender << "; 年龄:" << s2.age << "岁; 分数:" << s2.score << "; 状态:" << s2.status << endl;
// 2.3 在定义结构体时顺便创建结构体变量
s3.name = "小泽玛利亚";
s3.age = 36;
s3.gender = 'F';
s3.score = 28.8f;
s3.status = true;
cout << "姓名:" << s3.name << "; 性别:" << s3.gender << "; 年龄:" << s3.age << "岁; 分数:" << s3.score << "; 状态:" << s3.status << endl;
system("pause");
return 0;
}
C++ 中 结构体创建时 struct 关键字可以省略。 定义时不可以省略
结构体变量利用操作符 “.” 访问成员
三、结构体数组
作用:将自定义的结构体放入到数组中方便维护
语法:struct 结构体名 数组名[元素个数] = { {},{},... }
示例:
#include <iostream>
using namespace std;
// 1、定义结构体
struct Teacher
{
// 成员列表
string name; // 姓名
int age; // 年龄
char gender; // 性别
float score; // 分数
bool status; // 状态
};
int main()
{
// 2、创建结构体数组
struct Teacher arr[3] = {
{ "桥本有菜", 18, 'F', 18.8f, true },
{ "三上悠亚", 22, 'F', 16.2f, false },
{ "小泽玛利亚", 36, 'F', 28.8f, true },
};
// 3、修改结构体数组中的数值
arr[2].name = "河北彩花";
arr[2].age = 26;
// 4、循环打印老师信息
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
cout << "姓名:" << arr[i].name << "; 性别:" << arr[i].gender << "; 年龄:" << arr[i].age << "岁; 分数:" << arr[i].score << "; 状态:" << arr[i].status << endl;
}
system("pause");
return 0;
}
四、结构体指针
作用通过指针访问结构体中的成员
- 利用操作符
->
可以通过结构体指针访问结构体属性
示例:
#include <iostream>
using namespace std;
// 1、定义结构体
struct Teacher
{
// 成员列表
string name; // 姓名
int age; // 年龄
char gender; // 性别
float score; // 分数
bool status; // 状态
};
int main()
{
// 2、创建结构体变量
struct Teacher teacher = { "桥本有菜", 18, 'F', 18.8f, true };
// 3、通过指针指向结构体变量
struct Teacher* p = &teacher;
// 4、通过指针访问结构体变量中的数据
cout << "姓名:" << p->name << "; 性别:" << p->gender << "; 年龄:" << p->age << "岁; 分数:" << p->score << "; 状态:" << p->status << endl;
// 5、通过指针修改结构体变量中的数据
p->name = "三上悠亚";
p->age = 22;
p->status = false;
cout << "姓名:" << p->name << "; 性别:" << p->gender << "; 年龄:" << p->age << "岁; 分数:" << p->score << "; 状态:" << p->status << endl;
system("pause");
return 0;
}
总结:结构体指针可以通过 -> 操作符 来访问结构体中的成员
五、结构体嵌套结构体
作用:结构体中的成员可以是另一个结构体
例如:每个老师辅导一个学员,一个老师的结构体中,记录一个学生的结构体
示例:
#include <iostream>
using namespace std;
// 1、定义学生结构体
struct Student {
string name;
int age;
char gender;
bool status;
};
// 2、定义教师结构体
struct Teacher
{
// 成员列表
string name; // 姓名
int age; // 年龄
char gender; // 性别
float score; // 分数
bool status; // 状态
struct Student stu; // 子结构体 学生
};
int main()
{
// 3、创建老师
Teacher t;
t.name = "桥本有菜";
t.age = 18;
t.gender = 'F';
t.score = 18.8f;
t.status = true;
t.stu.name = "刘安冰";
t.stu.age = 24;
t.stu.gender = 'M';
t.stu.status = true;
cout << "老师信息 - " << "姓名:" << t.name << "; 性别:" << t.gender << "; 年龄:" << t.age << "岁; 分数:" << t.score << "; 状态:" << t.status << endl;
cout << "学生信息 - " << "姓名:" << t.stu.name << "; 性别:" << t.stu.gender << "; 年龄:" << t.stu.age << "岁" << endl;
system("pause");
return 0;
}
六、结构体做函数参数
作用:将结构体作为参数向函数中传递
传递方式有两种:
- 值传递
- 地址传递
示例:
#include <iostream>
using namespace std;
// 1、定义教师结构体
struct Teacher
{
// 成员列表
string name; // 姓名
int age; // 年龄
char gender; // 性别
float score; // 分数
bool status; // 状态
};
// 2、值传递
void printTeacher1(struct Teacher t)
{
t.name = "三上悠亚";
t.age = 22;
t.status = false;
cout << "子函数中 - " << "姓名:" << t.name << "; 性别:" << t.gender << "; 年龄:" << t.age << "岁; 分数:" << t.score << "; 状态:" << t.status << endl;
}
// 3、地址传递
void printTeacher2(struct Teacher* p)
{
p->name = "三上悠亚";
p->age = 22;
p->status = false;
cout << "子函数中 - " << "姓名:" << p->name << "; 性别:" << p->gender << "; 年龄:" << p->age << "岁; 分数:" << p->score << "; 状态:" << p->status << endl;
}
int main()
{
// /4、创建老师
struct Teacher t;
t.name = "桥本有菜";
t.age = 18;
t.gender = 'F';
t.score = 18.8f;
t.status = true;
cout << "主函数中 - " << "姓名:" << t.name << "; 性别:" << t.gender << "; 年龄:" << t.age << "岁; 分数:" << t.score << "; 状态:" << t.status << endl;
printTeacher1(t);
cout << "主函数中 - " << "姓名:" << t.name << "; 性别:" << t.gender << "; 年龄:" << t.age << "岁; 分数:" << t.score << "; 状态:" << t.status << endl;
printTeacher2(&t);
cout << "主函数中 - " << "姓名:" << t.name << "; 性别:" << t.gender << "; 年龄:" << t.age << "岁; 分数:" << t.score << "; 状态:" << t.status << endl;
system("pause");
return 0;
}
总结:如果不想修改主函数中的数据,用值传递,反之用地址传递
七、结构体中 const 使用场景
作用:用 const 来防止误操作
示例:
#include <iostream>
using namespace std;
// 1、定义教师结构体
struct Teacher
{
// 成员列表
string name; // 姓名
int age; // 年龄
char gender; // 性别
float score; // 分数
bool status; // 状态
};
// 2、const 使用场景 将函数中的形参改为指针,可以减少内存空间,而且不会复制新的副本出来
void printTeacher(const Teacher* t)
{
/* 操作失败,因为添加了 const 修饰符
t->name = "三上悠亚";
t->age = 22;
t->status = false;
*/
cout << "子函数中 - " << "姓名:" << t->name << "; 性别:" << t->gender << "; 年龄:" << t->age << "岁; 分数:" << t->score << "; 状态:" << t->status << endl;
}
int main()
{
// 3、创建老师
struct Teacher t = { "桥本有菜", 18, 'F', 18.8f, true };
cout << "主函数中 - " << "姓名:" << t.name << "; 性别:" << t.gender << "; 年龄:" << t.age << "岁; 分数:" << t.score << "; 状态:" << t.status << endl;
printTeacher(&t);
cout << "主函数中 - " << "姓名:" << t.name << "; 性别:" << t.gender << "; 年龄:" << t.age << "岁; 分数:" << t.score << "; 状态:" << t.status << endl;
system("pause");
return 0;
}
八、结构体案例
1、案例一
案例描述:学校正在做毕设项目,每名老师带领无名学生,总共3名老师,需求如下
- 设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和存放5名学生的数组作为成员
- 学生的成员有姓名、考试分数、创建数组存放3名老师,通过函数给每个老师及所带的学生赋值
- 最终打印出老师数据以及老师所带的学生数据
示例:
#include <iostream>
using namespace std;
// 1、定义学生结构体
struct Student
{
// 成员列表
string name; // 姓名
int age; // 年龄
char gender; // 性别
float score; // 分数
bool status; // 状态
};
// 2、定义教师结构体
struct Teacher
{
// 成员列表
string name; // 姓名
int age; // 年龄
char gender; // 性别
float score; // 分数
bool status; // 状态
Student students[5]; // 学生列表
};
// 3、定义创建数据函数
void allocateSpace(Teacher teachers[], int len)
{
string names[3] = { "桥本有菜", "三上悠亚", "小泽玛利亚" };
string studentNameSeed = "ABCDE";
for (int i = 0; i < len; i++)
{
teachers[i].name = names[i];
teachers[i].age = 18;
teachers[i].gender = 'F';
teachers[i].score = 18.8f;
teachers[i].status = true;
for (int j = 0; j < sizeof(teachers[i].students) / sizeof(teachers[i].students[0]); j++)
{
float random = rand() % 61 + 40; // 40 ~ 100
teachers[i].students[j].name = "学生-";
teachers[i].students[j].name += studentNameSeed[j];
teachers[i].students[j].age = 12;
teachers[i].students[j].gender = 'M';
teachers[i].students[j].score = random;
teachers[i].students[j].status = random > 60.0f ? true : false;
}
}
}
// 4、定义打印函数
void printInfo(const Teacher teachers[], int len)
{
for (int i = 0; i < len; i++)
{
cout << "老师信息: " << "姓名:" << teachers[i].name << "; 性别:" << teachers[i].gender << "; 年龄:" << teachers[i].age << "岁; 分数:" << teachers[i].score << "; 状态:" << teachers[i].status << endl;
for (int j = 0; j < sizeof(teachers[i].students) / sizeof(teachers[i].students[0]); j++)
{
cout << "\t学生信息: " << "姓名:" << teachers[i].students[j].name << "; 性别:" << teachers[i].students[j].gender << "; 年龄:" << teachers[i].students[j].age << "岁; 分数:" << teachers[i].students[j].score << "; 状态:" << teachers[i].students[j].status << endl;
}
}
}
int main()
{
// 随机数种子
srand((unsigned int)time(NULL));
// 4、创建3名老师的数组
struct Teacher teachers[3];
// 5、通过函数给三名老师的信息赋值,并给老师带的学生信息赋值
int len = sizeof(teachers) / sizeof(teachers[0]);
allocateSpace(teachers, len);
// 6、打印所有老师及所带的学生信息
printInfo(teachers, len);
system("pause");
return 0;
}
2、案例二
案例描述:设计一个英雄的结构体,包括姓名,年龄,性别;创建结构体数组,数组中存放 5名 英雄
通过冒泡排序,将数组中的英雄按照没年龄进行升序排序,最终打印排序后的结果
姓名 | 年龄 | 性别 |
---|---|---|
刘备 | 23 | 男 |
关羽 | 22 | 男 |
张飞 | 20 | 男 |
赵云 | 21 | 男 |
貂蝉 | 19 | 女 |
示例:
#include <iostream>
using namespace std;
// 定义结构体
struct Hero
{
// 成员列表
string name; // 姓名
int age; // 年龄
string gender; // 性别
};
// 排序
void bubbleSort(Hero heros[], int len)
{
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len - 1 - i; j++)
{
cout << heros[i].age << " " << heros[j + 1].age << endl;
if (heros[j].age > heros[j + 1].age)
{
Hero temp = heros[j];
heros[j] = heros[j + 1];
heros[j + 1] = temp;
}
}
}
}
// 打印
void printHeros(Hero heros[], int len)
{
for (int i = 0; i < len; i++)
{
cout << heros[i].name << "今年" << heros[i].age << "岁,他是个" << heros[i].gender << "的" << endl;
}
}
int main()
{
// 创建结构体数组
struct Hero heros[5] = {
{ "刘备", 23, "男" },
{ "关羽", 22, "男" },
{ "张飞", 20, "男" },
{ "赵云", 21, "男" },
{ "貂蝉", 19, "女" },
};
int len = sizeof(heros) / sizeof(heros[0]);
printHeros(heros, len);
bubbleSort(heros, len);
cout << endl;
printHeros(heros, len);
system("pause");
return 0;
}
第十章 扩展
二、通讯录管理系统
1、系统需求
通讯录是一个可以记录亲人、好友信息的工具
本教程中主要利用 C++ 来实现一个通讯录管理系统
系统中需要实现的功能如下:
- 添加联系人:向通讯录中添加信任,信息包括(姓名、性别、年龄、联系电话、家庭住址)最多记录 1000 人
- 显示联系人:显示通讯录中所有联系人信息
- 删除联系人:按照姓名进行删除指定联系人
- 查找联系人:按照姓名查看制定联系人信息
- 修改联系人:按照姓名重新修改指定联系人
- 清空联系人:清空通讯录中所有信息
- 退出通讯录:退出当前使用的通讯录
2、创建项目
打开 Visual Studio 2019 点击创建新项目,创建新的 C++ 项目



3、菜单功能
功能描述:用户选择功能的界面
菜单界面效果如下图:

步骤:
- 封装函数显示该界面 如
void showMenu()
- 在main 函数中调用封装好的函数
示例
#include <iostream>
using namespace std;
// 封装显示菜单函数
void showMenu()
{
cout << "***************************" << endl;
cout << "***** 1、添加联系人 *****" << endl;
cout << "***** 2、显示联系人 *****" << endl;
cout << "***** 3、删除联系人 *****" << endl;
cout << "***** 4、查找联系人 *****" << endl;
cout << "***** 5、修改联系人 *****" << endl;
cout << "***** 5、修改联系人 *****" << endl;
cout << "***** 6、清空联系人 *****" << endl;
cout << "***** 0、退出通讯录 *****" << endl;
cout << "***************************" << endl;
}
int main()
{
// 菜单调用
showMenu();
system("pause");
return 0;
}
4、退出功能
功能描述:退出通讯录系统
思路:根据用户不同选择,进入不同的功能,可以选择 switch 分支,将整个架构进行搭建
当用户选择 0 时,执行退出,选择其他先不做操作,也不会退出程序
示例:
#include <iostream>
using namespace std;
// 封装显示菜单函数
void showMenu()
{
cout << "***************************" << endl;
cout << "***** 1、添加联系人 *****" << endl;
cout << "***** 2、显示联系人 *****" << endl;
cout << "***** 3、删除联系人 *****" << endl;
cout << "***** 4、查找联系人 *****" << endl;
cout << "***** 5、修改联系人 *****" << endl;
cout << "***** 6、清空联系人 *****" << endl;
cout << "***** 0、退出通讯录 *****" << endl;
cout << "***************************" << endl;
}
int main()
{
int select = 0;
while (true)
{
// 菜单调用
showMenu();
cin >> select;
switch (select)
{
case 1:
cout << "1、添加联系人" << endl;
break;
case 2:
cout << "2、显示联系人" << endl;
break;
case 3:
cout << "3、删除联系人" << endl;
break;
case 4:
cout << "4、查找联系人" << endl;
break;
case 5:
cout << "5、修改联系人" << endl;
break;
case 6:
cout << "6、清空联系人" << endl;
break;
case 0:
cout << "欢迎下次使用!!!" << endl;
system("pause");
return 0;
break;
default:
break;
}
}
system("pause");
return 0;
}
5、添加联系人
功能描述:实现添加联系人,联系人上限为 1000 人,联系人信息包括(姓名、性别、年龄、联系电话、家庭住址)
添加联系人实现步骤:
- 设计联系人结构体
- 设计通讯录结构体
- main函数中创建通讯录
- 封装添加联系人函数
- 测试添加联系人功能
// 封装添加联系人函数
void addcontactPerson(struct addressBook* address_books)
{
// 判断通讯录是否超过最大值
if (address_books->contactPersonSize >= MAX)
{
cout << "通讯录已满,无法添加!!!" << endl;
}
else
{
// 添加联系人 姓名、性别、年龄、联系电话、家庭住址
string name;
cout << "请输入姓名:";
cin >> name;
address_books->contact_persons[address_books->contactPersonSize].name = name;
int gender;
cout << "请输入性别 1男 2女:";
while (true)
{
cin >> gender;
if (gender == 1 || gender == 2)
{
address_books->contact_persons[address_books->contactPersonSize].gender = gender;
break;
}
else
{
cout << "输入有误,请重新输入" << endl;
cout << "请输入性别 1男 2女:";
}
}
int age;
cout << "请输入年龄:";
cin >> age;
address_books->contact_persons[address_books->contactPersonSize].age = age;
string phone;
cout << "请输入联系电话:";
cin >> phone;
address_books->contact_persons[address_books->contactPersonSize].phone = phone;
string address;
cout << "请输入家庭住址:";
cin >> address;
address_books->contact_persons[address_books->contactPersonSize].address = address;
address_books->contactPersonSize++;
cout << "添加成功!!!" << endl;
system("pause");
system("cls");
}
}
6、显示联系人
功能描述:显示通讯录中已有的联系人信息
显示联系人实现步骤:
- 封装显示联系人函数
- 测试现实联系人功能
思路:判断如果当前通讯录中没有人员,就提示为空,大叔大于 0 ,显示通讯录中信息
示例:
// 封装显示联系人函数
void showContactPersonAll(const struct addressBook address_books)
{
if (address_books.contactPersonSize == 0)
{
cout << "通讯录中还没有联系人!!!" << endl;
}
else
{
for (int i = 0; i < address_books.contactPersonSize; i++)
{
cout << "姓名:" << address_books.contact_persons[i].name << "; 年龄:" << address_books.contact_persons[i].age << "; 性别:" << (address_books.contact_persons[i].gender == 1 ? "男" : "女") << "; 练习方式:" << address_books.contact_persons[i].phone << "; 家庭住址:" << address_books.contact_persons[i].address << endl;
}
}
system("pause");
system("cls");
}
7、删除联系人
功能描述:按照姓名进行删除指定联系人
删除联系人实现步骤
- 封装检测联系人是否存在函数
- 封装删除练习人函数
- 测试删除联系人
封装检测联系人是否存在函数:删除联系人之前,我们需要先判断用户输入的联系人是否存在,如果存在则删除,不存在提示用户没有要删除的联系人,因此我们可以把检测联系人是否存在封装成一个函数,如果存在,返回联系人在通讯录中的位置,不存在返回 -1
封装删除练习人函数:根据用户输入的联系人判断通讯录中是否有此人
查找到进行删除,并提示删除成功
查不到提示查无此人
示例
// 封装检测联系人是否存在
int isExist(struct addressBook* address_books, string name)
{
for (int i = 0; i < address_books->contactPersonSize; i++)
{
if (address_books->contact_persons[i].name == name)
{
return i;
}
}
return -1;
}
// 封装删除联系人函数
void delContactPerson(struct addressBook* address_books)
{
string name;
cout << "请输入要删除的姓名:";
cin >> name;
int index = isExist(address_books, name);
if (index == -1)
{
cout << "查无此人" << endl;
}
else
{
// 将指定要删除的名称 后的联系人向前移动,并且让通讯录中记录的人员个数做 -1 的操作
for (int i = index; i < address_books->contactPersonSize; i++)
{
address_books->contact_persons[i] = address_books->contact_persons[i + 1];
}
address_books->contactPersonSize--;
cout << "删除成功!!!" << endl;
}
system("pause");
system("cls");
}
8、查找联系人
功能描述:按照姓名查看指定联系人信息
查找联系人实现步骤
- 封装查找联系人函数
- 测试查找指定联系人
实现思路:判断用户指定的联系人是否存在,如果存在显示心爱,不存在则提示查无此人
示例:
// 封装查找联系人函数
void findContactPerson(const struct addressBook address_books)
{
string name;
cout << "请输入要查找的姓名:";
cin >> name;
int index = isExist(address_books, name);
if (index == -1)
{
cout << "查无此人" << endl;
}
else
{
cout << "姓名:" << address_books.contact_persons[index].name << "; 年龄:" << address_books.contact_persons[index].age << "; 性别:" << (address_books.contact_persons[index].gender == 1 ? "男" : "女") << "; 练习方式:" << address_books.contact_persons[index].phone << "; 家庭住址:" << address_books.contact_persons[index].address << endl;
}
system("pause");
system("cls");
}
9、修改联系人
功能描述:按照姓名重新修改指定联系人
修改联系人实现步骤:
- 封装修改联系人函数
- 测试修改联系人功能
实现思路:查找用户输入的联系人,查找成功进行修改操作,查找失败提示查无此人
示例:
// 封装修改联系人函数
void updateContactPerson(struct addressBook* address_books)
{
string name;
cout << "请输入要查找的姓名:";
cin >> name;
int index = isExist(*address_books, name);
if (index == -1)
{
cout << "查无此人" << endl;
}
else
{
// 编辑联系人 姓名、性别、年龄、联系电话、家庭住址
string name;
cout << "请输入姓名:";
cin >> name;
address_books->contact_persons[address_books->contactPersonSize].name = name;
int gender;
cout << "请输入性别 1男 2女:";
while (true)
{
cin >> gender;
if (gender == 1 || gender == 2)
{
address_books->contact_persons[address_books->contactPersonSize].gender = gender;
break;
}
else
{
cout << "输入有误,请重新输入" << endl;
cout << "请输入性别 1男 2女:";
}
}
int age;
cout << "请输入年龄:";
cin >> age;
address_books->contact_persons[address_books->contactPersonSize].age = age;
string phone;
cout << "请输入联系电话:";
cin >> phone;
address_books->contact_persons[address_books->contactPersonSize].phone = phone;
string address;
cout << "请输入家庭住址:";
cin >> address;
address_books->contact_persons[address_books->contactPersonSize].address = address;
cout << "修改成功!!!" << endl;
}
system("pause");
system("cls");
}
10、清空联系人
功能描述:清空通讯录中所有信息
清空联系人实现步骤
- 封装清空联系人函数
- 测试清空联系人
实现思路:将通讯录所有联系人清理掉,只要将通讯录的联系人数量置为 0 ,做逻辑清空即可。
示例:
// 封装清空联系人函数
void clearContactPerson(struct addressBook* address_books)
{
address_books->contactPersonSize = 0;
cout << "通讯录已清空!!!" << endl;
system("pause");
system("cls");
}
11、总结
完整代码
#include <iostream>
using namespace std;
#define MAX 1000 // 最大人数
// 设计联系人结构体 联系人信息包括(姓名、性别、年龄、联系电话、家庭住址)
struct contactPerson
{
string name; // 姓名
int gender; // 性别 1男 2女
int age; // 年龄
string phone; // 联系电话
string address; // 家庭住址
};
// 设计通讯录结构体
struct addressBook
{
// 通讯录中保存的数组联系人
struct contactPerson contact_persons[MAX];
// 通讯录中当前记录练习人个数
int contactPersonSize;
};
// 封装显示菜单函数
void showMenu()
{
cout << "***************************" << endl;
cout << "***** 1、添加联系人 *****" << endl;
cout << "***** 2、显示联系人 *****" << endl;
cout << "***** 3、删除联系人 *****" << endl;
cout << "***** 4、查找联系人 *****" << endl;
cout << "***** 5、修改联系人 *****" << endl;
cout << "***** 6、清空联系人 *****" << endl;
cout << "***** 0、退出通讯录 *****" << endl;
cout << "***************************" << endl;
}
// 封装添加联系人函数
void addContactPerson(struct addressBook* address_books)
{
// 判断通讯录是否超过最大值
if (address_books->contactPersonSize >= MAX)
{
cout << "通讯录已满,无法添加!!!" << endl;
}
else
{
// 添加联系人 姓名、性别、年龄、联系电话、家庭住址
string name;
cout << "请输入姓名:";
cin >> name;
address_books->contact_persons[address_books->contactPersonSize].name = name;
int gender;
cout << "请输入性别 1男 2女:";
while (true)
{
cin >> gender;
if (gender == 1 || gender == 2)
{
address_books->contact_persons[address_books->contactPersonSize].gender = gender;
break;
}
else
{
cout << "输入有误,请重新输入" << endl;
cout << "请输入性别 1男 2女:";
}
}
int age;
cout << "请输入年龄:";
cin >> age;
address_books->contact_persons[address_books->contactPersonSize].age = age;
string phone;
cout << "请输入联系电话:";
cin >> phone;
address_books->contact_persons[address_books->contactPersonSize].phone = phone;
string address;
cout << "请输入家庭住址:";
cin >> address;
address_books->contact_persons[address_books->contactPersonSize].address = address;
address_books->contactPersonSize++;
cout << "添加成功!!!" << endl;
system("pause");
system("cls");
}
}
// 封装显示联系人函数
void showContactPersonAll(const struct addressBook address_books)
{
if (address_books.contactPersonSize == 0)
{
cout << "通讯录中还没有联系人!!!" << endl;
}
else
{
for (int i = 0; i < address_books.contactPersonSize; i++)
{
cout << "姓名:" << address_books.contact_persons[i].name << "; 年龄:" << address_books.contact_persons[i].age << "; 性别:" << (address_books.contact_persons[i].gender == 1 ? "男" : "女") << "; 练习方式:" << address_books.contact_persons[i].phone << "; 家庭住址:" << address_books.contact_persons[i].address << endl;
}
}
system("pause");
system("cls");
}
// 封装检测联系人是否存在
int isExist(const struct addressBook address_books, string name)
{
for (int i = 0; i < address_books.contactPersonSize; i++)
{
if (address_books.contact_persons[i].name == name)
{
return i;
}
}
return -1;
}
// 封装删除联系人函数
void delContactPerson(struct addressBook* address_books)
{
string name;
cout << "请输入要删除的姓名:";
cin >> name;
int index = isExist(*address_books, name);
if (index == -1)
{
cout << "查无此人" << endl;
}
else
{
// 将指定要删除的名称 后的联系人向前移动,并且让通讯录中记录的人员个数做 -1 的操作
for (int i = index; i < address_books->contactPersonSize; i++)
{
address_books->contact_persons[i] = address_books->contact_persons[i + 1];
}
address_books->contactPersonSize--;
cout << "删除成功!!!" << endl;
}
system("pause");
system("cls");
}
// 封装查找联系人函数
void findContactPerson(const struct addressBook address_books)
{
string name;
cout << "请输入要查找的姓名:";
cin >> name;
int index = isExist(address_books, name);
if (index == -1)
{
cout << "查无此人" << endl;
}
else
{
cout << "姓名:" << address_books.contact_persons[index].name << "; 年龄:" << address_books.contact_persons[index].age << "; 性别:" << (address_books.contact_persons[index].gender == 1 ? "男" : "女") << "; 练习方式:" << address_books.contact_persons[index].phone << "; 家庭住址:" << address_books.contact_persons[index].address << endl;
}
system("pause");
system("cls");
}
// 封装修改联系人函数
void updateContactPerson(struct addressBook* address_books)
{
string name;
cout << "请输入要查找的姓名:";
cin >> name;
int index = isExist(*address_books, name);
if (index == -1)
{
cout << "查无此人" << endl;
}
else
{
// 编辑联系人 姓名、性别、年龄、联系电话、家庭住址
string name;
cout << "请输入姓名:";
cin >> name;
address_books->contact_persons[index].name = name;
int gender;
cout << "请输入性别 1男 2女:";
while (true)
{
cin >> gender;
if (gender == 1 || gender == 2)
{
address_books->contact_persons[index].gender = gender;
break;
}
else
{
cout << "输入有误,请重新输入" << endl;
cout << "请输入性别 1男 2女:";
}
}
int age;
cout << "请输入年龄:";
cin >> age;
address_books->contact_persons[index].age = age;
string phone;
cout << "请输入联系电话:";
cin >> phone;
address_books->contact_persons[index].phone = phone;
string address;
cout << "请输入家庭住址:";
cin >> address;
address_books->contact_persons[index].address = address;
cout << "修改成功!!!" << endl;
}
system("pause");
system("cls");
}
// 封装清空联系人函数
void clearContactPerson(struct addressBook* address_books)
{
address_books->contactPersonSize = 0;
cout << "通讯录已清空!!!" << endl;
system("pause");
system("cls");
}
// 程序入口函数
int main()
{
// main函数中创建通讯录
addressBook address_books;
// 初始化通讯录中当前人数个数
address_books.contactPersonSize = 0;
// 菜单选择
int select = 0;
while (true)
{
// 菜单调用
showMenu();
cout << "请输入您的操作:";
cin >> select;
switch (select)
{
case 1:
addContactPerson(&address_books); // 利用地址传递,可以修饰实参
break;
case 2:
showContactPersonAll(address_books); // 用 const 来防止误操作
break;
case 3:
delContactPerson(&address_books);
break;
case 4:
findContactPerson(address_books);
break;
case 5:
updateContactPerson(&address_books);
break;
case 6:
clearContactPerson(&address_books);
break;
case 0:
cout << "欢迎下次使用!!!" << endl;
system("pause");
return 0;
break;
default:
break;
}
}
system("pause");
return 0;
}
一、Visual studio 2019 快捷键
1、常用快捷键
快捷键 | 功能 |
---|---|
Ctrl+K+C | 注释代码 |
Ctrl+K+U | 取消注释代码 |
Ctrl+K+D | 格式化全部代码 |
Ctrl+Shift+A | 新建类 |
Ctrl+R+G | 删除无效Using |
Ctrl+H | 批量替换 |
Ctrl+J | 自动提示 |
Ctrl+G | 跳转到指定行 |
Ctrl+E+E | 在交互窗口中运行选中代码(很实用) |
Alt+Enter | 快速引用 |
shift+F9 | 监控(代码运行时) |
shift+F6 | 生成(当前类库) |
F6 | 生成(整个解决方案中类库) |
Shift+F12 | 查找所有引用 |
Tab+Tab | 代码联想 |
cw+Tab+Tab | Console.WriteLine() |
2、项目相关的快捷键
快捷键 | 功能 |
---|---|
Ctrl + Shift + B | 生成项目 |
Ctrl + Alt + L | 显示 Solution Explorer(解决方案资源管理器) |
Shift + Alt+ C | 添加新类 |
Shift + Alt + A | 添加新项目到项目 |
CTRL + F7 | 生成编译 |
CTRL + O | 打开文件 |
CTRL + SHIFT + O | 打开项目 |
CTRL + SHIFT + C | 显示类视图窗口 |
F4 | 显示属性窗口 |
SHIFT + F4 | 显示项目属性窗口 |
CTRL + SHIFT + E | 显示资源视图 |
F12 | 转到定义 |
CTRL + F12 | 转到声明 |
CTRL + ALT + J | 对象浏览 |
CTRL + ALT + F1 | 帮助目录 |
CTRL + F1 | 动态帮助 |
F1 | 帮助 |
SHIFT + F1 | 当前窗口帮助 |
CTRL + ALT + F3 | 帮助-搜索 |
SHIFT + ALT + ENTER | 全屏显示 |
CTRL + - | 向后定位 |
CTRL + SHIFT + - | 向前定位 |
CTRL + F4 | 关闭文档窗口 |
CTRL + PAGE DOWN | 光标定位到窗口上方 |
CTRL + PAGE UP | 光标定位到窗口下方 |
CTRL + F6 | |
CTRL + TAB | 下一个文档窗口 |
CTRL + SHIFT + F6 | |
CTRL + SHIFT + TAB | 上一个文档窗口 |
ALT + F6 | 下一个面板窗口 |
CTRL + K, CTRL + L | 取消remark |
CTRL + K, CTRL + C | 注释选择的代码 |
CTRL + K, CTRL + U | 取消对选择代码的注释 |
CTRL + M, CTRL + O | 折叠代码定义 |
CTRL + M, CTRL + L | 展开代码定义 |
CTRL + DELETE | 删除至词尾 |
CTRL + BACKSPACE | 删除至词头 |
SHIFT + TAB | 取消制表符 |
CTRL + U | 转小写 |
CTRL + SHIFT + U | 转大写 |
CTRL + SHIFT + END | 选择至文档末尾 |
CTRL + SHIFT + HOME | 选择至文档末尾开始 |
SHIFT + END | 选择至行尾 |
SHIFT + HOME | 选择至行开始处 |
SHIFT + ALT + END | 垂直选择到最后尾 |
SHIFT + ALT + HOME | 垂直选择到最前面 |
CTRL + A | 全选 |
CTRL + W | 选择当前单词 |
CTRL + SHIFT + PAGE UP | 选择至本页前面 |
CTRL + SHIFT + PAGE DOWN | 选择至本页后面 |
CTRL + END | 文档定位到最后 |
CTRL + HOME | 文档定位到最前 |
CTRL + G | 转到… |
CTRL + K, CTRL + P | 上一个标签 |
CTRL + K, CTRL + N | 下一个标签 |
ALT + F10 | 调试-ApplyCodeChanges |
CTRL + ALT+ Break | 停止调试 |
CTRL + SHIFT + F9 | 取消所有断点 |
CTRL + F9 | 允许中断 |
CTRL + SHIFT + F5 | 调试-重新开始 |
F5 | 运行调试 |
CTRL + F5 | 运行不调试 |
F10 | 跨过程序执行 |
F11 | 单步逐句执行 |
CTRL + J | 列出成员 |
CTRL + PAGE DOWN | 下一个视图 |
CTRL + B | 格式-粗体 |
CTRL + SHIFT + T | 格式-文字缩进 |
3、编辑相关的键盘快捷键
快捷键 | 功能 |
---|---|
Ctrl + Enter | 在当前行插入空行 |
Ctrl + Shift + Enter | 在当前行下方插入空行 |
Ctrl + 空格键 | 使用 IntelliSense(智能感知)自动完成 |
Alt + Shift + 箭头键(←,↑,↓,→) | 选择代码的自定义部分 |
Ctrl + } | 匹配大括号、括号 |
Ctrl + Shift +} | 在匹配的括号、括号内选择文本 |
Ctrl + Shift + S | 保存所有文件和项目 |
Ctrl + K,Ctrl + C | 注释选定行 |
Ctrl + K,Ctrl + U | 取消选定行的注释 |
Ctrl + K,Ctrl + D | 正确对齐所有代码 |
Shift + End | 从头到尾选择整行 |
Shift + Home | 从尾到头选择整行 |
Ctrl + Delete | 删除光标右侧的所有字 |
Ctrl+K,D | 格式化全部代码 |
Ctrl+K,F | 格式化选中的代码 |
Shift+Alt+Enter | 切换全屏编辑 |
Ctrl+B,T / Ctrl+K,K | 切换书签开关 |
Ctrl+B,N / Ctrl+K,N | 移动到下一书签 |
Ctrl+B,P | 移动到上一书签 |
Ctrl+B,C | 清除全部标签 |
Ctrl+I | 渐进式搜索 |
Ctrl+Shift+I | 反向渐进式搜索 |
Ctrl+F | 查找 |
Ctrl+Shift+F | 在文件中查找 |
F3 | 查找下一个 |
Shift+F3 | 查找上一个 |
Ctrl+H | 替换 |
Ctrl+Shift+H | 在文件中替换 |
Alt+F12 | 查找符号(列出所有查找结果) |
Ctrl+Shift+V | 剪贴板循环 |
Ctrl+左右箭头键 | 一次可以移动一个单词 |
Ctrl+上下箭头键 | 滚动代码屏幕,但不移动光标位置。 |
Ctrl+Shift+L | 删除当前行 |
Ctrl+M,M | 隐藏或展开当前嵌套的折叠状态 |
Ctrl+M,L | 将所有过程设置为相同的隐藏或展开状态 |
Ctrl+M,P | 停止大纲显示 |
Ctrl+E,S | 查看空白 |
Ctrl+E,W | 自动换行 |
Ctrl+G | 转到指定行 |
Shift+Alt+箭头键 | 选择矩形文本 |
Alt+鼠标左按钮 | 选择矩形文本 |
Ctrl+Shift+U | 全部变为大写 |
Ctrl+U | 全部变为小写 |
4、导航相关的键盘快捷键
快捷键 | 功能 |
---|---|
Ctrl +Up/Down | 滚动窗口但不移动光标 |
Ctrl + - | 让光标移动到它先前的位置 |
Ctrl ++ | 让光标移动到下一个位置 |
F12 | 转到定义 |
5、调试相关的键盘快捷键
快捷键 | 功能 |
---|---|
Ctrl + Alt + P | 附加到进程 |
F10 | 调试单步执行 |
F5 | 开始调试 |
Shift + F5 | 停止调试 |
Ctrl + Alt + Q | 添加快捷匹配 |
F9 | 设置或删除断点 |
F6 | 生成解决方案 |
Ctrl+F6 | 生成当前项目 |
F7 | 查看代码 |
Shift+F7 | 查看窗体设计器 |
Ctrl+F5 | 开始执行(不调试) |
Shift+F5 | 停止调试 |
Ctrl+Shift+F5 | 重启调试 |
Ctrl+F9 | 启用/停止断点 |
Ctrl+Shift+F9 | 删除全部断点 |
Ctrl+F10 | 运行到光标处 |
F11 | 逐语句 |
6、搜索相关的键盘快捷键
快捷键 | 功能 |
---|---|
Ctrl + K Ctrl + K | 将当前行添加书签 |
Ctrl + K Ctrl + N | 导航至下一个书签 |
Ctrl + . | 如果你键入一个类名如 Collection,且命名空间导入不正确的话,那么这个快捷方式组合将自动插入导入 |
Ctrl + Shift + F | 在文件中查找 |
Shift + F12 | 查找所有引用 |
Ctrl + F | 显示查找对话框 |
Ctrl + H | 显示替换对话框 |
Ctrl + G | 跳转到行号或行 |
Ctrl + Shift + F | 查找所选条目在整个解决方案中的引用 |
7、窗口相关的键盘快捷键
快捷键 | 功能 |
---|---|
Ctrl+W,W | 浏览器窗口 |
Ctrl+W,S | 解决方案管理器 |
Ctrl+W,C | 类视图 |
Ctrl+W,E | 错误列表 |
Ctrl+W,O | 输出视图 |
Ctrl+W,P | 属性窗口 |
Ctrl+W,T | 任务列表 |
Ctrl+W,X | 工具箱 |
Ctrl+W,B | 书签窗口 |
Ctrl+W,U | 文档大纲 |
Ctrl+D,B | 断点窗口 |
Ctrl+D,I | 即时窗口 |
Ctrl+Tab | 活动窗体切换 |
Ctrl+Shift+N | 新建项目 |
Ctrl+Shift+O | 打开项目 |
Ctrl+Shift+S | 全部保存 |
Shift+Alt+C | 新建类 |
Ctrl+Shift+A | 新建项 |
8、单元测试相关键盘快捷键
快捷键 | 功能 |
---|---|
Ctrl + R , A | 执行所有测试 |
Ctrl + R , T | 执行当前所在测试方法 |
Ctrl + R , D | 执行最后一次测试的所有测试 |
Ctrl + R , F | 执行最后一次测试的所有测试的失败测试 |
9、其他快捷键
快捷键 | 功能 |
---|---|
Ctrl+J / Ctrl+K,L | 列出成员 |
Ctrl+Shift+空格键 / Ctrl+K,P | 参数信息 |
Ctrl+K,I | 快速信息 |
Ctrl+E,C / Ctrl+K,C | 注释选定内容 |
Ctrl+E,U / Ctrl+K,U | 取消选定注释内容 |
Ctrl+K,M | 生成方法存根 |
Ctrl+K,X | 插入代码段 |
Ctrl+K,S | 插入外侧代码 |
F12 | 转到所调用过程或变量的定义 |
软考密码:Xing19971215qwe