目录
第 3 节 项目精讲-"不服就干-直接干"之 do-while 循环
第 5 节 循环中的特殊控制:continue 与 break
第 14 节 项目拓展 2-宅男福利:控制台上跳极乐净土(动画版)
项目五 黑客攻击系统-重复验证
为看书困难的小伙伴推荐视频教程:百度网盘 提取码:r59a
第 0 节: 需求分析、项目实现
项目实现:
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
int main(void) {
string name;
string pwd;
while (1) {
system("cls");
std::cout << "请输入账号:";
std::cin >> name;
std::cout << "请输入密码:";
std::cin >> pwd;
if (name == "54hk" && pwd == "123456") {
break;
} else {
system("pause");
cout << "用户名或密码错误!" << endl;
}
}
system("cls");
std::cout << "1.网站 404 攻击" << std::endl;
std::cout << "2.网站篡改攻击" << std::endl;
std::cout << "3.网站攻击记录" << std::endl;
std::cout << "4.DNS 攻击" << std::endl;
std::cout << "5.服务器重启攻击" << std::endl;
system("pause");
return 0;
}
第 1 节 “愚公移山”之 while 循环
使用场合:
当需要反复执行某些“过程”时,就可以使用 while 循环。
移山,移到什么时候?
只要山还在,就一直挖!
while (门前的山还在) {
一直挖
}
使用方法
while (条件) {
语句 1
语句 2
.......
}
强烈建议,无论循环体内有几条语句,都使用{}
break 的作用
跳出所在的循环。
死循环
有些场合(比如,游戏引擎的主循环, 就是一个死循环)
更多场合,需要避免死循环。
demo:
1+2+3+4+...100
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
int main(void) {
int i = 1;
int s = 0;
while (i<=100) {
s += i;
i++;
}
cout << "s=" << s << endl;
system("pause");
return 0;
}
流程图
第 2 节 "后羿射日"之 for 循环
从功能上,for 循环和 while 循环是完全等效的!
使用场合
在循环次数已经确定的情况下,使用 for 循环更方便!
射掉 9 个太阳即可。
使用方法
for (表达式 1; 表达式 2;表达式 3){
循环体
}
说明:
表达式 1: 为循环做准备
表达式 2: 循环条件
表达式 3: 改变循环计数
注意:
表达式 1、表达式 2、表达式 3, 这 3 个表达式的任意一个或多个,都可以省略!
但是其中的“;”不可以省略!
for (; ; ) {
循环体
}
相当于:
while (1) {
循环体
}
for 循环的表达式 1
在 C89 标准中,表达式 1 不能定义变量
在 C99 标准和 C++中,表达式 1 可以定义变量
表达式 1 中定义的变量,仅在 for 循环中有效。
流程图
for (表达式 1; 表达式 2;表达式 3){
循环语句
}
for 循环的次数控制:
for (int i=0; i<10; i++) { ... } //常用方式
for (int i=1; i<=10; i++) { ... } //较少使用
使用 for 循环实现“后裔射日”
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
//后羿射日
int main(void) {
for (int i=1; i<=9; i++) {
cout << "射第" << i << "个太阳" << endl;
}
system("pause");
return 0;
}
for 和 while 的选择
1)当已经确定了循环次数时,建议使用 for
2)其他情况,可以使用 for ,也可以使用 while, 建议使用 while
使用 for 循环实现 1+2+3+...100 = ?
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
int main(void) {
int s = 0;
//1 + 2 + 3 + ... 100
for (int i=1; i<=100; i++) {
s += i;
}
cout << s << endl;
system("pause");
return 0;
}
第 3 节 项目精讲-"不服就干-直接干"之 do-while 循环
使用场合:
先执行一次循环体,然后再判断条件,以判定是否继续下一轮循环!
即:至少执行一次循环体!
使用方法
do {
循环体
} while (条件)
使用 do-while 计算 1+2+3+...100
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
int main(void) {
int s = 0;
int i = 1;
do {
s += i;
i++;
} while(i<=100);
cout << s << endl;
system("pause");
return 0;
}
特殊用法:【在特殊的宏定义中使用】
do {
// 循环体
} while(0);
第 4 节 项目需求、项目实现
需求分析:
不能重复输入账号和密码.
项目实现:
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
int main(void) {
string name;
string pwd;
while (1) {
std::cout << "请输入账号:";
std::cin >> name;
std::cout << "请输入密码:";
std::cin >> pwd;
if (name == "54hk" && pwd == "123456") {
break;
} else {
cout << "用户名或密码错误!" << endl;
}
}
std::cout << "1.网站 404 攻击" << std::endl;
std::cout << "2.网站篡改攻击" << std::endl;
std::cout << "3.网站攻击记录" << std::endl;
std::cout << "4.DNS 攻击" << std::endl;
std::cout << "5.服务器重启攻击" << std::endl;
system("pause");
return 0;
}
第 5 节 循环中的特殊控制:continue 与 break
break
结束本层循环。
continue
结束本次循环,进入一次循环
for 语句中的 continue
while 语句中的 continue
demo:
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
int main(void) {
string ret;
for (int i=0; i<3; i++) {
cout << "开始第" << i+1 << "次相亲..." << endl;
cout << "你喜欢打王者吗?" << endl;
cin >> ret;
if (ret != "yes") {
continue;
}
cout << "加个微信吧..." << endl;
}
system("pause");
return 0;
}
第 6 节 代码世界中的传送阵:goto 语句
传送阵
demo:
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
int main(void) {
string ret;
for (int i=0; i<3; i++) {
cout << "开始第" << i+1 << "次相亲..." << endl;
cout << "你喜欢打王者吗?" << endl;
cin >> ret;
if (ret != "yes") {
continue;
}
cout << "加个微信吧..." << endl;
cout << "我中意你, 你中意我吗?" << endl;
cin >> ret;
if (ret == "yes") {
goto happy;
}
}
system("pause");
return 0;
happy:
cout << "开启浪漫之旅..." << endl;
system("pause");
return 0;
}
第 7 节 “甜蜜的谎言”之循环嵌套
要点:
把内层的循环,看成一个完整的“大语句”
demo:
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
// 一天想我几次?
// 24 小时,每秒一次
int main(void) {
int count = 0;
for (int i=0; i < 24; i++) {
for (int j=0; j<60; j++) {
for (int k=0; k<60; k++) {
count++;
cout << i << ":" << j << ":" << k
<< " 想你第" << count << "次" << endl;
Sleep(1000);
}
}
}
cout << "一天想你" << count << "次" << endl;
system("pause");
return 0;
}
第 8 节 常见错误总结
1. 循环体之前加分号
2. 循环结束后,循环计数变量的值
第 9 节 英语不是障碍:计算机英语加油站
while | 当...时候,用于 while 循环 |
for | 用于for循环 |
break | 破裂 |
continue | 继续 -> 调到 |
success | 成功 |
fail | 失败 |
error | 错误 |
commit | 提交 |
push | 推 |
create | 创建 |
clone | 克隆,复制 |
第 10 节 编程思维修炼
分析:
玫瑰曲线:
x = cos(t) * a * sin(nt) //t 表示角度
y = sin(t) * a * sin(nt)
a 可以取一个值,例如 150
x = cos(t) * 150 * sin(nt) //t 表示角度
y = sin(t) * 150 * sin(nt)
当 n 是奇数正整数时,玫瑰曲线有 n 个花瓣,t 的范围是 0 到 180 度
当 n 是偶数正整数时,玫瑰曲线有 2n 个花瓣,t 的范围是 0 到 360 度
解决方案:
使用循环,绘制 0 到 180 度或 360 度的曲线。
添加画笔模块:
每个角色,都有一个隐藏的画笔
当这个画笔处于“抬笔”状态时, 角色移动时,就不会画出笔迹
当这个画笔处于“落笔”状态时, 角色移动时,就会画出笔迹
注意:调整画笔的中心点。
第 11 节 职场修炼:程序员到底能干多久
现状:
很多程序员,过了 30 岁,纷纷转行。
原因:
1)薪资过万后,很难进一步提升
2)可替代性高,在新人面前,没有绝对优势。
3)结婚成家后,在 996 工作环境下,难以承受。
解决方案:
1)选择合适的方向
前端开发,PHP 开发等方向,技术含量低,可替代性高。
2)掌握企业的核心业务,核心技术,向技术管理方向发展
3)掌握外包开发核心技能,逐步拓展外包人脉。
第 12 节 逼格提升:github-使用项目创建代码仓库
已经在本地创建项目,然后再发布到 github。
第 13 节 项目拓展 1-循环的经典应用:暴力破解密码
client.cpp
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
int main (void){
string pwd;
while (1) {
cout << "Please input your password: ";
cin >> pwd;
if (pwd == "000123") {
break;
} else {
cout << "Password error." << endl;
}
}
cout << "login success" << endl;
cout << "1. 注册" << endl;
cout << "2. 管理" << endl;
cout << "3. 查询" << endl;
cout << "4. 删除" << endl;
system("pause");
return 0;
}
crack.cpp
#include <iostream>
using namespace std;
int main(void)
{
char pwd[7];
char dict[64]; // 10+26+26+1 = 63;
char tmp[32];
int index = 0;
for (int i = 0; i < 10; i++)
{
dict[index++] = '0' + i;
}
/*
for (int i=0; i<26; i++) {
dict[index++] = 'a' + i;
}
for (int i=0; i<26; i++) {
dict[index++] = 'A' + i;
}
dict[index++] = '_';
*/
dict[index] = '\0';
int n = index; // 字符个数
for (int p1 = 0; p1 < n; p1++)
{
for (int p2 = 0; p2 < n; p2++)
{
for (int p3 = 0; p3 < n; p3++)
{
for (int p4 = 0; p4 < n; p4++)
{
for (int p5 = 0; p5 < n; p5++)
{
for (int p6 = 0; p6 < n; p6++)
{
tmp[0] = dict[p1];
tmp[1] = dict[p2];
tmp[2] = dict[p3];
tmp[3] = dict[p4];
tmp[4] = dict[p5];
tmp[5] = dict[p6];
tmp[6] = '\0';
cout << tmp << endl;
}
}
}
}
}
}
return 0;
}
在控制台:
crack.exe | client.exe
第 14 节 项目拓展 2-宅男福利:控制台上跳极乐净土(动画版)
_T( ) 补充说明:
如果项目使用的是字符集是”多字节字符集”
那么在使用 easyx 的相关接口时, 就不需要使用 _T( )
如果项目使用的是字符集是”Unicode 字符集”或其他字符集
那么在使用 easyx 的相关接口时, 就要使用 _T( )
不论什么字符集, 都使用_T(), 则都可以适应.
_T( )是一个特殊的”宏”, 其中的参数是常量时,才有效果.
如果参数是变量, 则可能会无效.
所以, 当加载的文件名是变量时, 有两个方法:
方法 1) 把字符集改为 使用”多字节字符集”
方法 2) 使用自定义的函数, 进行字符编码的转换
Demo
#include <iostream>
#include <graphics.h>
#include <Windows.h>
#include <string>
#include <string.h>
#include <MMSystem.h> // 播放音乐需要的头文件
#pragma comment(lib, "winmm.lib") //告诉编译器, 加载 winmm.lib 库文件
using namespace std;
#define COUNT 148
int main(void)
{
char fileName[128];
std::cout << "正在加载..." << std::endl;
//预加载
IMAGE images[COUNT];
for (int i = 1; i <= COUNT; i++)
{
sprintf(fileName, "D:\\tmp\\images2\\_%04d_图层-%d.jpg", COUNT - i, i);
loadimage(&images[i - 1], fileName);
}
initgraph(800, 450);
// 重复播放"极乐净土.mp3"
mciSendString(_T("play 极乐净土.mp3 repeat"), 0, 0, 0);
while (1)
{
for (int i = 0; i < COUNT; i++)
{
putimage(0, 0, &images[i - 1]);
Sleep(75);
}
}
system("pause");
closegraph();
return 0;
}
第 15 节 项目练习-循环控制强化训练
循环练习第 1 关
难度: 1
行数和每行*的个数,由用户输入。
参考:
#include <iostream>
#include <Windows.h>
using namespace std;
int main(void)
{
int rows;
int cols;
cout << "请输入行数: ";
cin >> rows;
cout << "请输入每行需要打印的列数: ";
cin >> cols;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << "*";
}
cout << endl;
}
system("pause");
return 0;
}
循环练习第 2 关
难度 1.5
dmeo
#include <iostream>
#include <Windows.h>
using namespace std;
int main(void)
{
int rows;
cout << "请输入行数: ";
cin >> rows;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < i + 1; j++)
{
cout << "*";
}
cout << endl;
}
system("pause");
return 0;
}
循环练习第 3 关
难度: 1.5
Demo
#include <iostream>
#include <Windows.h>
using namespace std;
int main(void)
{
int rows;
cout << "请输入行数: ";
cin >> rows;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < rows - i; j++)
{
cout << "*";
}
cout << endl;
}
system("pause");
return 0;
}
循环练习第 4 关
难度系数 2.0
*的个数 | 空格的个数 | |
第1行 | 1 | 7(n-1) |
第2行 | 3 | 6(n-2) |
第3行 | 5 | 3 |
第4行 | 7 | 2 |
第i行 | 2*i-1 | n-i |
第n行 | 2*n-1 |
Demo
#include <iostream>
#include <Windows.h>
using namespace std;
int main(void)
{
int rows;
cout << "请输入行数: ";
cin >> rows;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < rows - i - 1; j++)
{
cout << " ";
}
for (int j = 0; j < 2 * i + 1; j++)
{
cout << "*";
}
cout << endl;
}
system("pause");
return 0;
}
循环练习第 5 关
难度:2.5
打印乘法口诀表
Demo
#include <iostream>
#include <Windows.h>
#include <iomanip>
using namespace std;
int main(void)
{
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= i; j++)
{
// setw(2) 是下一个数据的输出宽度为 2,
//仅对下一个数据的输出有效, 即只有一次效果
// std::left 使数据在自己规定的宽度内左对齐,默认是右对齐, 持续有效
cout << i << "*" << j << "=";
if (j == 1)
{
cout << setw(1) << std::left << i * j << " ";
}
else
{
cout << setw(2) << std::left << i * j << " ";
}
}
cout << endl;
}
system("pause");
return 0;
}
循环练习第 6 关
输出所有水仙花数
水仙花数: 3 位数字, 各位的立方之和,等于这个数本身.
说明: 严格的说只有 3 位的整数, 才可能是水仙花数.
Demo
#include <iostream>
#include <Windows.h>
#include <iomanip>
using namespace std;
int main(void)
{
int a, b, c;
for (int i = 100; i <= 999; i++)
{
a = i % 10;
b = (i / 10) % 10;
c = i / 100;
if (a * a * a + b * b * b + c * c * c == i)
{
cout << i << endl;
}
}
system("pause");
return 0;
}
循环练习第 7 关
输出指定项的斐波那契数列.
1, 1, 2, 3, 5, 8, 13, 21, ..
难度: 2.5
Demo
#include <iostream>
#include <Windows.h>
#include <iomanip>
using namespace std;
int main(void)
{
int n = 0;
long long a = 1;
long long b = 1;
long long value;
cout << "请输入斐波那契数列的个数: ";
cin >> n;
if (n <= 0)
{
cout << "要求是大于 0 的正数." << endl;
system("pause");
return 1;
}
if (n == 1)
{
cout << "1" << endl;
system("pause");
return 0;
}
if (n == 2)
{
cout << "1 1" << endl;
system("pause");
return 0;
}
cout << "1 1 ";
for (int i = 3; i <= n; i++)
{
value = a + b;
// a 和 b 前进一位
a = b;
b = value;
cout << value << " ";
}
cout << endl;
system("pause");
return 0;
}
循环练习第 8 关
输入一个 10 进制的正整数,把它转换为 2 进制输出。
6
110
Demo
#include <iostream>
#include <Windows.h>
#include <iomanip>
using namespace std;
int main(void)
{
int ret[32] = {0};
int n;
int i;
cout << "请输入一个正整数: ";
cin >> n;
if (n < 0)
{
cout << "需要输入一个正整数!" << endl;
system("pause");
return 1;
}
i = 0;
while (n != 0)
{
ret[i] = n % 2;
n = n / 2;
i++;
}
for (i--; i >= 0; i--)
{
cout << ret[i];
}
system("pause");
return 0;
}
循环练习第 9 关
输入一个 2 进制正数,把它转换为 10 进制输出。
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
int main(void)
{
string str;
int s = 0;
int p = 1;
cout << "请输入一个二进制数: ";
cin >> str;
for (int i = str.length() - 1; i >= 0; i--)
{
int x = str[i] - '0';
s += x * p;
p *= 2;
}
cout << "s=" << s << endl;
system("pause");
return 0;
}
循环练习第 10 关
输入一个字符串,然后把这个字符串逆转输出
123456789
987654321
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
int main(void)
{
string str;
int i;
int j;
char tmp;
cout << "请输入一个字符串: " << endl;
cin >> str;
i = 0;
j = str.length() - 1;
while (i < j)
{
tmp = str[i];
str[i] = str[j];
str[j] = tmp;
i++;
j--;
}
cout << str << endl;
system("pause");
return 0;
}
循环练习第 11 关
经典算法题: 千鸡百钱.
1000 块钱, 要买 100 只鸡.
公鸡每只 50 块
母鸡每只 30 块
小鸡每 3 只 10 块
问:一共有多少种买法?
难度 3.0
Demo
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
/*
1000 块钱, 要买 100 只鸡.
公鸡每只 50 块
母鸡每只 30 块
小鸡每 3 只 10 块
*/
int main(void)
{
int cock_max = 1000 / 50;
int hen_max = 1000 / 30;
for (int i = 1; i <= cock_max; i++)
{
for (int j = 1; j <= hen_max; j++)
{
int k = 100 - i - j; //小鸡的个数
if (k % 3 == 0 && i * 50 + j * 30 + k / 3 * 10 == 1000)
{
cout << "公鸡:" << i << " 母鸡:" << j << " 小鸡:" << k << endl;
}
}
}
system("pause");
return 0;
}
循环练习第 12 关
输入一个英文字符串(一句话),统计输入的单词个数.
难度 2.8
I love you!
demo
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
int main(void)
{
char line[256]; //'\0'就是 0
int i = 0;
// 访问字符串(字符数组)的下标
int count = 0; //单词计数
cout << "请输入一句话:";
gets_s(line, sizeof(line));
// 跳过前面的连续空格
while (line[i] == ' ')
i++;
while (line[i])
{ // while(line[i] != '\0')
// 跳过连续的多个非空格组合(就是单词!)
while (line[i] && line[i] != ' ')
i++;
while (line[i] == ' ')
i++;
count++;
'\0' 就是 0
}
cout << "一共有" << count << "个单词" << endl;
system("pause");
return 0;
}
循环练习第 13 关
输入一句话,然后把这个字符串以单词为单位,逆转输出。(腾讯笔试题)
比如将“Alice call Jack”转换为“Jack call Alice”,
实现速度最快,移动最少。
难度: 3.0
为看书困难的小伙伴推荐视频教程:百度网盘 提取码:r59a