八、循环(一)
1、for循环
1)for循环语法
//for循环语法
for(初始化表达式;运行条件表达式;变动表达式)
{
循环内容;
}
//示例
for(int i=0;i<10;i++)
{
std::cout<<i<<std::endl;
}
std::cout<<"循环结束";
①打印9-1
//打印9-1
#include <iostream>
int main()
{
for (int i = 9; i > 0; i--)
{
std::cout << i << std::endl;
}
}
②打印所有大写字母
//打印所有大写字母
#include <iostream>
int main()
{
for (char i = 65; i <=90; i++) //A的ascii码为65
{
std::cout << i << std::endl;
}
}
③打印所有大写字母,但是每行只有五个字母
//打印所有大写字母
#include <iostream>
int main()
{
int count{ 0 };
for (char i = 65; i <=90; i++) //A的ascii码为65
{
count++;
if (count > 5)
{
std::cout << std::endl;
count = 1;
}
std::cout << i;
}
}
法二:
//打印所有大写字母
#include <iostream>
int main()
{
for (char a{ 65 }; a < 91; a++)
{
if ((!((a - 65) % 5)) && (a > 65)) //取余数,如果余数=0,则进行换行
{
std::cout << std::endl;
}
std::cout << a;
}
}
④要求用户输入一个大写字母,打印从这个字母后的所有大写字母,比如用户输入C,那么屏蔽上打印DEFG..Z
//输入一个大写字母,打印从这个字母后的所有大写字母
#include <iostream>
int main()
{
char userIn;
std::cout << "请输入一个大写字母:";
std::cin >> userIn;
for (char a = userIn + 1; a < 91; a++)
{
if (!((a - userIn - 1) % 5) && (a > (userIn + 1)))
{
std::cout << std::endl;
}
std::cout << a;
}
}
2、for循环之网银证书密码攻击
需求:设计一个系统来模拟网银密码被攻击的场景,用户输入一个6位数字密码,然后我们破解它的密码并显示出来
#include <iostream>
#include <conio.h>
int main()
{
int password, repassword;
std::cout << "请设置一个6位数字的密码:";
std::cin >> password;
std::cout << "请再次输入你的密码:";
std::cin >> repassword;
lset:
if (password == repassword)
{
system("cls");
//破解程序
std::cout << "破解程序启动";
for (int hackpass = 0; hackpass < 1000000; hackpass++)
{
if (hackpass == password)
{
std::cout << "你的密码为:" << hackpass << std::endl;
goto lexit;
}
}
}
else
{
goto lset;
}
lexit:
std::cout << "密码破解成功,程序退出!";
}
3、for循环补充知识
1)循环的嵌套
①打印九九乘法表,输出结果如下
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::setfill('0');
for (int y{}; y < 10; y++)
{
for (int x{}; x < 10; x++)
{
std::cout << std::setw(3)<<x * y << " ";
}
std::cout << std::endl;
}
}
2)跳出for循环的三种方式
能力 | 语句 | 说明 |
---|---|---|
1 | continue | 跳出本次循环,进入下一次循环 |
2 | break | 跳出循环 |
3 | goto | 跳出嵌套循环,即跳出所有循环 |
①continue:跳出本次循环
//continue:跳出本次循环
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::setfill('0');
for (int y{}; y < 10; y++)
{
if (y == 0) continue;
for (int x{}; x < 10; x++)
{
if (x == 0) continue;
std::cout << std::setw(3) << x * y << " ";
}
std::cout << std::endl;
}
}
②break:跳出循环
//break:跳出循环
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::setfill('0');
for (int y{}; y < 10; y++)
{
for (int x{}; x < 10; x++)
{
if (x == 5) break;
std::cout << std::setw(3) << x * y << " ";
}
std::cout << std::endl;
}
}
注:break只能跳出本层循环,但是无法跳出上层循环
③goto:可以跳出所有循环
3)for循环的变体
//正常for循环
for(初始化;条件;变动表达式)
{
}
//变体一:无初始化,只要前面声明过,for中就不需要初始化
for(;条件;变动表达式)
{
}
//变体二:无变动表达式
for(;条件;) //死循环
{
}
//变体三:
for(;;) //无条件执行,中间是一个条件表达式,即bool值
{
}
4、for循环练习
需求:质数是只能被自己和1整除的数,在不对称加密算法中,质数扮演着重要的作用,设计一个程序,找出1000以内的质数
补充知识:数学库cmath提供了计算平方根的函数sqrt。a=sqrt(100);则a=10
//找出1000以内的质数(法一)
#include <iostream>
#include <cmath>
int main()
{
bool bcase{}; //用于记录
for (int i = 3; i < 1000; i++)
{
bcase = false;
for (int c = 2; c < i; c++)
{
if (i % c == 0) //可以整除说明,不是质数,则跳出循环
{
bcase = true; //只要不是质数,就将bcase设置为true
break;
}
}
if (!bcase) std::cout << i << std::endl; //若bcase为false,说明是质数,就将其输出
}
}
//找出1000以内的质数(法一代码优化)
#include <iostream>
#include <cmath>
int main()
{
bool bcase{}; //用于记录
for (int i = 3; i < 1000; i+=2) //质数一定是奇数,所有每一次+2,相比法一提高50%运算效率
{
bcase = false;
for (int c = 3; c < i; c+=2) //因为第一次从3开始,且没有偶数了,所以此处也直接从3开始,并且因为是奇数,所以此处也+2
{
if (i % c == 0)
{
bcase = true;
break;
}
}
if (!bcase) std::cout << i << std::endl;
}
}
//找出1000以内的质数(法一代码优化)
#include <iostream>
#include <cmath>
int main()
{
bool bcase{}; //用于记录
for (int i = 3; i < 1000; i+=2) //质数一定是奇数,所有每一次+2,相比法一提高50%运算效率
{
bcase = false;
for (int c = 3; c < sqrt(i); c+=2) //开平方
{
if (i % c == 0)
{
bcase = true;
break;
}
}
if (!bcase) std::cout << i << std::endl;
}
}
5、for循环练习:政府采购项目
需求:某单位要采购一批办公家具,共有10000元资金,要买100件家具,其中高级桌子每张500元,普通桌子每张300元,椅子三把100元,要求把资金刚好花完,并且所有 家具的数量刚好加起来是100件。请设计一个软件系统来给出采购方案。
//政府采购项目(法一)
#include <iostream>
int main()
{
for (int a = 0; a <= 100; a++) //高级桌子
{
for (int b = 0; b <= 100; b++) //普通桌子
{
for (int c = 0; c <= 100; c++) //高级椅子
{
if ((a + b + c == 100) && (a * 500 + b * 300 + c * 100 / 3 == 10000))
{
std::cout << "高级桌子采购" << a << "张,普通桌子采购" << b << "张,高级椅子采购" << c << "把\n";
}
}
}
}
}
//运算次数=100*100*100=1000000次
//政府采购项目(法二)
#include <iostream>
int main()
{
int acount = 10000 / 500; //高级桌子最多允许购买数量
int bcount = 10000 / 300; //普通桌子最多允许购买数量
for (int a = 0; a <= acount; a++)
{
for (int b = 0; b <= bcount; b++) //普通桌子
{
int c = 100 - a - b; //椅子购买数量
if ((c%3==0)&&(a * 500 + b * 300 +c * 100 / 3 == 10000)) //椅子只能一次买3把
{
std::cout << "高级桌子采购" << a << "张,普通桌子采购" << b << "张,高级椅子采购" << c << "把\n";
}
}
}
}
//运算次数=20*33=660次
//政府采购项目(法三)
#include <iostream>
int main()
{
for (int num = 0; num <= 3; num++)
{
std::cout << "高级桌子采购" << num*4 << "张,普通桌子采购" << 25-num*7 << "张,高级椅子采购" << 75+3+num << "把\n";
}
}
//运算次数=3次
法三解析:
a:高级桌子 b:普通桌子 c:高级椅子
0≤a≤20 0≤b≤33
当a和b都取到最大,则20+33+c=100,可知c的最小值为45,即45≤c≤100
a * 500 + b * 300 +c * 100 / 3 == 10000
等式两边同时*3
1500a+900b+100c=30000
等式两边同时/100
得出等式①:15a+9b+c=300
又因为等式②:a+b+c=100
由等式①-等式②得等式③:14a+8b=200
由等式③/等式②得:7a+4b=100,即4b=100-7a,即b=25-7/4a
通过b的取值范围可知:0≤25-7a/4≤33
因b是整数,即25-7a/4是整数,所以a是4的倍数,即a=4num
可得a=4num,b=25-7a/4,即b=25-7a/4 *4num
即b=25-7num
c=100-a-b,即c=100-4um-25+7num,即c=75+3num
综上:
a=4num
b=25-7num
c=75+3num
根据a,b的范围,可得
0≤4num≤20,即0≤4num≤20 ,,即num≤5
0≤25-7num≤33,即-25≤-7num≤7,即25/7≥num,即num≤3
根据c的取值范围,可知
45≤75+3num≤100,即num≤33
所以综上所述:即num≤3
6、for循环练习:麟江湖显示升级经验列表
需求:为游戏麟江湖设计升级所需的经验梯度表,用户按下L键,将为用户打印出我们游戏从1-100级所需的升级经验表、设等级为lv,当前等级需要的经验值为lvlv100。要求输入不分大小写,对齐输出内容。
#include <iostream>
#include <conio.h>
#include <iomanip>
int main()
{
std::cout << "请输入字母L查看等级所需经验:\n";
char cIn = _getch();
if ((cIn == 'l') || (cIn == 'L'))
{
for (int lv{1}; lv < 101; lv++)
{
std::cout << std::setfill(' ');
std::cout << "\n等级" << std::setw(3) << lv << " 所需经验" << std::setw(10) << lv * lv * 100 << std::endl;
}
}
}