C/C++ 第四讲 循环结构

4.1 循环语句的基本形式

while和for: 当型循环,先判断再循环

do while: 直到型循环,先执行再判断

while语句

1
2
while (表达式)
语句
  • 表达式真(非0)则执行再回来
  • 语句只能一条,但可以为复合语句
  • 表达式的括号后无;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//例:求1~99的奇数和
#include <iostream>
using namespace std;
int main()
{
int i(1), s(0);
while (i<100)
{
s=s+i;
i=i+2;
}
cout<<"s="<<s<<endl;
system("pause");
return 0;
}

for语句

1
2
for (表达式1;表达式2;表达式3)
循环体语句
  • 表达式1:循环变量赋初值

  • 表达式2:循环条件

  • 表达式3:循环变量变化情况

  • 表达式结束处无;

  • 表达式都可省,两个;不可省

image-20230928084455572

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//1~99奇数和
int i, s(0);
for (i=1;i<100;i=i+2)
s=s+i

//省略表达式的版本
int i(1), s(0);
for ( ; ; ) //表达式2空:无条件循环(死循环),用break破解。
{
if (i>=100)
break;
s=s+i;
i=i+2;
}

do while语句

1
2
3
do
语句
while (表达式);
  • 先执行循环体,再判断条件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;
int main()
{
int i(1), s(0);
do
{
s=s+i;
i=i+2;
} while(i<100);
cout<<"s="<<s<<endl;
system("pause");
return 0;
}
  • 末尾有;

4.2 循环结构的应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//辗转相除法求二自然数的最大公约数
//大数除小数,余为零则小数为最大公约数;不为零则小数除余数继续。
#include <iostream>
using namespace std;
int main()
{
//确保输入2自然数
do
{
cout<<"输入两自然数m,n:"
cin>>m>>n;
} while(m<=0n<=0);
//不需要m>n
while(r=m%n!=0)
{
m=n;n=r
}
cout<<"最大公约数为:"<<n<<endl;
system("pause");
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//判断是否为素数
#include <iostream>
using namespace std;
int main()
{
int k,m;
cin>>m;
for(k=2;k<m;k++)
if (m%k==0)
break;
if(k==m) //一直循环到最后,没break
cout<<"是素数"<<endl;
else
cout<<"不是素数"<<endl;
system("pause");
return 0;
}

4.3 循环嵌套

  • 外循环和内循环必须采用不同的循环控制变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//输出九九乘法表
#include <iostream>
using namespace std;
int main()
{
cout<<"\t 九九乘法表"<<endl;
cout<<"\t ----------"<<endl;
for(int i=1;i<=9;i++)
{
for(int j=1;j<=i;j++)
cout<<i<<"*"<<j<<"="<<i*j<<'\t';
cout<<endl;
}
system("pause");
return 0;
}

//输出上三角
#include <iostream>
using namespace std;
int main()
{
cout<<"\t 九九乘法表"<<endl;
cout<<"\t ----------"<<endl;
for(int i=1;i<=9;i++)
{
for(int j=1;j<i;j++)
cout<<'\t'; //细化j的范围,下三角部分用空格替代
for(int j=i;j<=9;j++)
cout<<i<<"*"<<j<<"="<<i*j<<'\t';
cout<<endl;
}
system("pause");
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//输出2~100的所有素数,要求每行输出5个
#include <iostream>
using namespace std;
int main()
{
int i,m,countm(0);
cout<<"\t 2~100素数"<<endl;
cout<<"\t ----------"<<endl;
for (m=2;m<=100;m++)
{
for(i=2;i<m;i++)
if (m%i==0)
break;
if (i==m) //此if在for循环外
{
cout<<m<<"\t";
countm++;
if (countm%5==0)
cout<<endl;
}
}
system("pause");
return 0;
}

注意区分内循环和外循环

4.4 辅助控制语句

注意对比区分break和continue

break语句

作用:

  • 用于跳出switch语句,保证多分支的正确执行
  • 用于循环语句,强制跳出循环体(终止本层循环)

notice:

  • 只能跳出/终止最近一层结构
  • 不能用于switch和循环以外的结构
  • 用于循环语句时,一般与if一起使用
1
2
3
4
5
6
for(m=10;m>0;m--)
{
if (m%3==0)
break;
cout<<m<<" ";
}

continue语句

作用

  • (绕过本次循环)结束本次循环,跳过循环体中未执行的语句,进行下一次是否执行循环体的判断

notice:

只能用于循环语句时,一般与if一起使用

1
2
3
4
5
6
for(m=10;m>0;m--)
{
if (m%3==0)
continue;
cout<<m<<" ";
}

例题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
int main()
{
int k, m,n;
for (k = 0, m = 1; m < 4; m++)
{
for (n = 1; n < 5; n++)
{
cout <<m<<"*"<<n<<"%3="<< m * n % 3 <<" ,k="<<k<< endl;
if (m * n % 3 == 0)continue;
}
k++;
}
cout << k << endl;
system("pause");
return 0;
}

k=3

goto语句

慎用,会使结构化设计风格遭到破坏。

例题

  1. 辗转相除求最大公约数
    1. 普通方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "iostream"
#include<math.h>
using namespace std;
int main()
{
int m, n, r, t;
cin>>m>>n;
/*if(m<n)
{
t=m;m=n;n=t;
}*/
//以上提高循环效率
for(r=n;r>1;r--)
{
if (m%r==0&&n%r==0)
break;
}
cout<<"r="<<r<<endl;
system("pause");
return 0;
}
  1. 辗转相除法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "iostream"
using namespace std;
int main()
{
int m, n, r, t;
cin>>m>>n;
/*if(m<n)
{
t=m;m=n;n=t;
}
r=m%n;*/
//少做一次而已
while(r!=0)
{
m=n;n=r;
r=m%n;
}
//while((r=m%n)!=0)
cout<<"r="<< n<<endl;
system("pause");
return 0;
}

附:辗转相减法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream> 
using namespace std;
int main()
{
int m, n;
cin>>m>>n;
while(m-n!=0)
if(m>n)
m=m-n;
else
n=n-m;
cout<<"gcd(m,n)="<<m<<endl;
system("pause");
return 0;
}
  1. 质数判别–>2~100输出,逢8换行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "iostream"
#include<math.h>
using namespace std;
int main()
{
int m, k, num(0);
for(m=2;m<100;m++)
{
for(k=2;k<=sqrt(m);k++)
{
if (m%k==0)
break;
}
if (k>sqrt(m))
{
cout<<m<<" ";
num++;
}
if(num%8==0)
cout<<endl;
}
system("pause");
return 0;
}
1
2
3
4
5
6
7
8
9
i=0;
sinx=0;
t-x;
while(fabs(t)>=1e=5)
{
sinx+=t;
t=t*x*x/((i+1)*(i+2);
i=i+2;
}
  1. 输入一串字符,分类统计其中单词个数、字母个数、数字个数、其他字符个数。单词之间以一个空白符分开(空格符' '、水平制表符''\t'、换行符'\n'),以^z表示输入结束。

getchar()函数,逐一读取字符,#include <studio.h>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "iostream"
#include<math.h>
using namespace std;
int main()
{
int alpha(0), num(0),ch(0),word(0);
while(c=getchar()!=EOF) //EOF:文本结束符,对应^z
{
if (c==' 'c=='\t'c=='\n')
word++;
if (c>='a'&&c<='z'c>='A'&&c<='Z')
alpha++;
else if (c>=0&&c<=9)
num++;
else
ch++;
}
cout<<"word="<<word<<...
system("pause");
return 0;
}

习题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "iostream"
#include<math.h>
using namespace std;
int main()
{
int i(1);
double x, a,xp;
cin >> a;
x = a;
for (i = 1;; i++)
{
xp = 2 * x / 3 + a / (3 * x * x);
if (((xp - x > 0) ? xp - x : x - xp) < 0.00001)
break;
x = xp;
}
cout << xp << endl;
system("pause");
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "iostream"
#include<math.h>
using namespace std;
int main()
{
double k,i,s(0);
for (i = 1;; i++)
{
k = 1.0 / (1.0 + ((i * i - i) / 2.0));
s += k;
if (k < 0.0001)
break;
}
cout << s << endl;
system("pause");
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "iostream"
#include<math.h>
using namespace std;
int main()
{
int n,i,s(0);
cout << "输入一个十进制整数" << endl;
cin >> n;
int m(n);
int count = 0;
while (m != 0)
{
m=m / 10;
count++;
}
for (i = count; i > 0; i--)
{
s = s + (n /int( pow(10, i - 1)) * int(pow(10, count - i)));
n = n % (n / int(pow(10, i - 1)) * int(pow(10, i - 1)));
}
cout << s << endl;
system("pause");
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "iostream"
#include<math.h>
using namespace std;
int main()
{
int i,m,n,p,q;
for (i = 100; i < 1000; i++)
{
m = i / 100; n = (i % 100) / 10; p = i % 100 % 10;
q = pow(m, 3) + pow(n, 3) + pow(p, 3);
if (q == i)
cout << i<<'\t';
}
cout << endl;
system("pause");
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<math.h>
#include<time.h>
using namespace std;
int main()
{
int a,n,k,s(0);
//void srand(unsigned int seed);
srand(time(NULL));
a = rand()%9+1;
srand(time(NULL));
n = 5 + rand() % 5;
int temp = 0;
for (k = 1; k <= n; k++)
{
temp = temp * 10 + a;
s+=temp;
}
cout << "with a= " <<a<<" and n= "<< n<<", s= "<<s<<endl;
system("pause");
return 0;
}

习题经验总结:随机数生成(重要)

  • 随机数生成:

a + rand() % n

其中的a是起始值,n是整数的范围。   

记得生成随机数种子:

1
2
#include<time.h>
srand(time(NULL));

rand()的实际机理:

(S*M+N)%32768