Skip to content

L1-13 for循环

for循环语句

格式

c++
for(表达式1;表达式2;表达式3)
{
    循环体;
}

以上是 for 循环的模板,我们来看一个具体的例子

c++
for(int i = 0; i < 10; i=i+1)
{
    cout << "Hello world" << endl;
}

执行这段程序,将会输出 10 行 Hello world 。结合上面给出的模板,我们来分析一下这段程序:

int i = 0 为表达式 1 。

i < 10 为表达式 2 。

i=i+1 为表达式 3 。

cout<<"Hello world"<<endl 为循环体。

循环到第 10 次后,不满足 i<10 的条件,所以循环结束。

表达式1

表达式 1 作用是初始化,或者定义循环临时变量(这个变量只在循环内有效,出了循环就被销毁),所以表达式 1 的内容也可以写在循环外,并且可以为空,省略不写。

表达式2

表达式 2 的内容就是循环条件,用于循环判断,一般不省略。但是当它被省略的时候,那么这个空的表达式相当于一个永真式,意味着死循环,要跳出循环需要在循环体内用 break 语句跳出(后面会提到) 。

表达式3

表达式 3 用于循环变量的修改,或者是一个简单的表达式,当循环体只有一个语句的时候,并且没有特别的变量修改需要写到表达式 3 中,可以省略循环体为一个分号,

把循环体语句写到表达式 3 中。同样的,表达式 3 也是可以省略的。

循环体

循环体就是被循环执行的部分。在 for 循环中,会被花括号 {} 包裹起来,在上面的例子中,就是输出 Hello world 。

循环流程

for 循环的流程图如右图所示:

单选题

下面的 for 循环会执行多少次?

c++
#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, cnt = 0;
    cin >> n;
    for (int i = 0; i < n; i++)
        cnt++;

    cout << cnt << endl;
    return 0;
}

A. n = 10的时候会执行9次

B. n = 100的时候会执行100次

C. n = 1000的时候会执行1001次

D. 不论n等于多少,都会执行n次

题解

B

n 等于负数时只会执行 0 次。

单选题

下列选项中,与 cnt 的值最接近的是?

c++
#include <bits/stdc++.h>
using namespace std;

int main() {
    int cnt = 0;
    for (int i = 1; i < 1000000; i *= 2)
        cnt++;

    cout << cnt << endl;
    return 0;
}

A. 2

B. 20

C. 200

D. 2000

题解

B

赋值代码去运行看结果

for循环实例

在之前的内容中,我们讲解了如何输出 10 次 Hello world 。如果改为输出 100100 行也很简单,只需要修改一下循环的条件:

c++
for(int i = 0; i < 100; i++)
{
    cout << "Hello world" << endl;
}

这段程序中, 变量 i 的值,经历了从 0−99 的变化过程,所以输出了 100 个 Hello world ,我们可以修改一下程序,观察一下 i 的数值变化。

c++
#include<bits/stdc++.h>
using namespace std;
int main() {
    for(int i = 0; i < 100; i++)
    {
        cout << i << endl;
    }
}
text
0
1
2
...
98
99

这是上面程序输出的结果。最后一次循环中, i 的值为 100 ,不满足 i<100 的循环条件,因此没有执行 cout<<i<<endl 部分。

这个循环中, cout<<i<<endl 被执行了 100 次。

我们对程序稍加改进,将 i++ 变为 i+=3 。

c++
#include<bits/stdc++.h>
using namespace std;
int main() {
    for(int i = 0; i < 100; i+=3)
    {
        cout << i << endl;
    }
}
text
0
3
6
...
96
99

这个循环只会执行 34 次,输出 100 以内所有 3 的倍数。

c++
#include<bits/stdc++.h>
using namespace std;
int main() {
    for(int i = 0; i * i <= 100; i++)
    {
        cout << i * i << endl;
    }
}
text
0
1
4
9
16
25
36
49
64
81
100

这个循环会执行 10 次,输出 100 以内所有完全平方数。

c++
#include<bits/stdc++.h>
using namespace std;
int main() {
    for(int i = 100; i > 0; i--)
    {
        cout << i << endl;
    }
}
text
100
99
98
...
3
2
1

除了 ++ , −− 也可以被用于循环,上面这段程序 i 初始值为 100 , 然后逐个递减到 0 后,不满足循环条件,所以这个程序会倒序输出 100−1 。

c++
#include<bits/stdc++.h>
using namespace std;
int main() {
    int n, sum = 0;
    
    for(int i = 0; i < 100; i++)
    {
        cin >> n;
        sum += n;
    }
    
    cout << n << sum;
}

循环除了可以处理基础计算,还可以用来处理输入。上面这段程序,将会读取输入的 100 个数,并对他们进行求和。

单选题

以下 for 循环代码,最终会输出()?

c++
#include <bits/stdc++.h>
using namespace std;

int main() {
    int cnt = 0;
    for (int i = 0; i < 10; i++) {
        if (i % 3 == 0)
            i--;
        cnt++;
    }
    cout << cnt << endl;
    return 0;
}

A. 会输出 10

B. 会输出 11

C. 会输出 9

D. 死循环,没有输出

题解

D

i的初始值为0;控制条件i<10;表示当i<10就执行循环里面的内容; 因为循环里面:if(i%3==0)i--; for里面是:for (int i = 0; i < 10; i++) 所有循环里面i的值就会:0变为-1 ,-1变为0,一直重复循环,一直满足i<10,从而形成死循环,不能跳出循环,没有输出。

填空题

运行下面的程序,会输出()?

c++
#include <bits/stdc++.h>
using namespace std;

int main() {
    int cnt = 0;
    for (int i = 1; i < 100; i += 5)
        cnt += i;

    cout << cnt << endl;
    return 0;
}

题解

970

看代码可知:这一个代码的功能是1加上1到100中间,所有5的倍数1的数字之和,(1、6、11、16、21、26、31、36、41、46、51、56、61、66、71、76、81、86、91、96)的和等于970

习题

课堂练习:启蒙练习-阶乘

给定一个整数n,求它的阶乘,n小于等于10。

输入格式

输入一个数n(1<=n<=10)

输出格式

输出一个数,表示n的阶乘

输入样例

text
5

输出样例

text
120
c++
#include <bits/stdc++.h>
using namespace std;
int main() {
  int n, sum = 1;
  cin >> n;
  for (int i = 1; i <= n; i++) {
    sum *= i;
  }
  cout << sum << endl;
  return 0;
}

题解

首先我们知道阶乘的定义就是:

n!=n×(n−1)×(n−2)×...×2×1

那么我们只需要定义一个整数 fac 初始化为 1 ,然后循环 n 次,第一次乘以 1 ,第二次乘以 2 ,依此类推,最后 fac 的值就是 n! 。

课后作业:倒序输出

给出两个整数a和b,倒序输出a到b之间(包括a和b)的所有整数。

输入格式

第一行两个数a(0 <= a <= 100000)和b(0<= b <= 200000),保证a<=b。

输出格式

b - a + 1行,每行一个整数,表示倒序输出的第i个数。

输入样例

text
1 5

输出样例

text
5
4
3
2
1
c++
#include <bits/stdc++.h>
using namespace std;
int main() {
  int a, b;
  cin >> a >> b;
  for (int i = b; i >= a; i--) {
    cout << i << endl;
  }
  return 0;
}

题解

利用 for 循环倒序遍历 b−a 。

进阶习题:启蒙练习-倍数的个数

读入N,求出1..N的范围内所有2或3或5的倍数一共有多少个?

输入格式

输入一个数N(N <= 100000)

输出格式

输出一个数,表示这样的数的个数

输入样例

text
10

输出样例

text
8

数据范围

N <= 100000

c++
#include <bits/stdc++.h>
using namespace std;
int main() {
  int n, cnt = 0;
  cin >> n;
  for (int i = 1; i <= n; i++) {
    if(i % 2 == 0 || i % 3 == 0 || i % 5 == 0) {
      cnt++;
    }
  }
  cout << cnt << endl;
  return 0;
}

题解1

循环遍历 1−n ,对于每一个数判断其是否为 2,3,5 的倍数,判断条件之间为或的关系,如果是则计数加一。

c++
int cnt = 0;
for(int i = 2; i <= n; i+=2)
  cnt++;
for(int i = 3; i <= n; i+=3)
  cnt++;
for(int i = 5; i <= n; i+=5)
  cnt++;

同时思考一下这段代码错在哪里!

这段代码看起来记录了所有 2,3,5 的倍数,但其中所有 6,10,15,30 的倍数,会被统计多次。

题解2

本题如果不用循环来统计,还有更高效的数学方法,利用容斥原理,即:

2 的倍数有 n/2 个。 3 的倍数有 n/3 ​​​​​个。 5 的倍数有 n/5 ​​​​​个。

求和为: n/2+n/3+n/5

其中 6,10,15 的倍数被重复统计了,因此需要剪掉。

n/2+n/3+n/5−n/6−n/10−n/15

我们发现 30 的倍数在第一个式子中被统计了 3 次,在第二个式子中又被减掉了 3 次,因此还要再加回来。得到最终的计算公式:

n/2+n/3+n/5−n/6−n/10−n/15+n/30 。

c++
#include<bits/stdc++.h>
using namespace std;
 
int main() {
    int n;
    cin >> n;    
    cout << n/2 + n/3 + n/5 - n/6 - n/10- n/15 + n/30 << endl;
    return 0;
}