for循环

for格式除了看上去很像while,更像是进阶版的while循环

说是功能等价while循环,倒不如说for循环是计数循环,当你设定一个计数器,初始化数值,在数值到达你设定的某个值之前,不断循环执行循环体内的表达式,而每循环一轮,计数器数值都会按你的设定进行调整

通俗易懂一点就是:对于一开始的初始化条件,每当循环条件成立时,重复循环体内的语句,每轮执行完循环体后,执行每轮的动作,调整计数器的数值

当掌握这三种循环语句后,如何选择它们倒是成了个问题

  • 如果有固定次数,使用for
  • 如果必须执行一次用do_while
  • 其他情况才用while

for循环格式

每个表达式都是可以省略的

for ( ;循环条件; ) == while ( 循环条件 )

1
2
3
for ( 初始化条件; 循环条件; 每轮的动作 ){
循环体
}

代码示例

  1. 阶乘

    所谓阶乘就是n!,其结果是1*2*3*4*5*...*n

    使用代码实现这一过程,让用户输入n的值,然后计算出n!的结果

    (需要注意的是,在做求和的程序时,初始化变量为0,而在做求积的变量时,初始化变量应该为1)

    首先使用while来实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    /*
    * 定义变量n,i,fact
    * n的值是用户自行输入的
    * i不断的从1递增到n
    * fact保存计算结果
    * 当i小于或等于用户输入值n后结束循环
    * 循环体内fact的值就是1*2*3*...*n的算法
    * 每循环一次i++*/
    #include <stdio.h>

    int main() {
    int n;
    int fact = 1 ;
    int i = 1;
    scanf("%d", &n);
    while ( i <= n ){
    fact *= i;
    i ++;
    }
    printf("%d!=%d", n, fact);
    return 0;
    }

    我们改成for循环

    循环控制变量i只在for循环表达式中被使用,所以能将定义变量i写在for循环中,但要注意的是,在初始化条件处定义变量只有C99才能使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    /*
    * 定义变量n,fact
    * n的值是用户自行输入的
    * fact保存计算结果
    * 定义变量i并初始化
    * 当i小于或等于n时进入循环体
    * 每进行一轮循环让i++
    * 直到循环条件不满足i小于或等于n*/
    #include <stdio.h>

    int main() {
    int n;
    int fact = 1 ;
    scanf("%d", &n);
    for ( int i = 2; i <= n; i++ ) {
    fact *= i;
    }
    printf("%d!=%d", n, fact);
    return 0;
    }

    换个思路想,如果从n乘到1还能实现该功能吗?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /* 一:
    * 定义变量n,i,fact
    * n的值是用户自行输入的
    * i的值保存用户输入的n
    * fact保存计算结果
    * 循环体内fact的值就是n*n-1...的算法
    * 每循环一次n--
    * 当n的值小于或等于1就结束循环*/
    #include <stdio.h>

    int main() {
    int n;
    int fact = 1 ;
    scanf("%d", &n);
    int i = n;
    for ( ; n > 1; n--) {
    fact *= n;
    }
    printf("%d!=%d", i, fact);
    return 0;
    }
  2. 素数

    • 当用户输入一个数时,判断其是否为素数
  • 仅输出1到100范围内的前20个素数

    所谓素数即只能被1或自己整除的数,例如2,3,5,7,11,13,17,19...

    1在狭义的范围中不算是素数,所以在此不列举1为素数

    break的作用是跳出整个循环,另一个其他的用法是continue,但是它的意义只是跳过后续的循环体,回到for循环开头

    ||意为或者,用于多个条件判断时,只要满足其一即true,任一条件不满足即false

    &&意为且,用于多个条件判断时,当所有条件同时满足时即true,否则false

    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    /*
    * 定义用户输入变量x
    * 定义判断条件变量isPrime
    * 定义并初始化i的值为2
    * 当i的值小于用户输入x时进行循环判断
    * 每当循环结束就让i的值自增
    * i < x 可以理解成i的值永远都是x - 1
    * 如果x余i的值为0的话就将isPrime的值变成0
    * 并跳出整个循环
    * 判断isPrime的值是1还是0
    * 如果为0或者x为1,就输出不是素数
    * 否则输出是素数*/
    #include <stdio.h>

    int main() {
    int x;
    int isPrime = 1;
    scanf("%d", &x);
    for (int i = 2; i < x; i++) {
    if (x % i == 0) {
    isPrime = 0;
    break;
    }
    }
    if (isPrime == 0 || x == 1) {
    printf("%d不是素数", x);
    } else {
    printf("%d是素数", x);
    }
    printf("\n\n在100以内的前50个素数有:\n");
    secondary();
    return 0;
    }

    /*
    * 定义变量x,使用循环实现x的值是从1到100
    * 定义变量time,限制time为20
    * 定义变量isPrime,用于记录是否为素数
    * 定义变量i,用于判断是否为素数
    * 初始化x的值为1,初始化计数器time为0
    * 在1到100中当计数器小于20时,执行循环体内的语句
    * 每当有一个素数产生时,让计数器的数+1
    * 每五个素数换行显示,并让所有数都对齐*/
    int secondary() {
    for (int x = 1, time = 0; x <= 100 && time < 20; x++) {
    int isPrime = 1;
    for (int i = 2; i < x; i++) {
    if (x % i == 0) {
    isPrime = 0;
    }
    }
    if (isPrime == 1 && x != 1) {
    time++;
    printf("%d\t", x);
    if (time % 5 == 0) {
    printf("\n");
    }
    }
    }
    return 0;
    }
  1. 枚举硬币

    用1角,2角,五角的硬币凑出10元以下的金额

    我看到这题愣了半天没想明白应该怎么实现,无奈看完整个视频才缕清思路

    04-22_00:30

    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
    /*
    * 变量x为用户输入值
    * one为一角,two为二角,five为五角
    * one至多循环x*10-1次,two至多循环x*10\2-1次,five至多循环x*10/5-1次
    * 当循环的过程中,满足了one+two*2+five*5等于x*10
    * 就输出结果,否则就继续循环
    * goto可以指定跳转到任意处*/
    #include <stdio.h>

    int main() {
    int x;
    scanf("%d", &x);
    for (int one = 1; one < x * 10; one++) {
    for (int two = 1; two < x * 10 / 2; two++) {
    for (int five = 1; five < x * 10 / 5; five++) {
    if (one + two * 2 + five * 5 == x * 10) {
    printf("%d个1角加%d个2角加%d个5角可以得到%d元", one, two, five, x);
    goto exit;
    }
    }
    }
    }
    exit:
    return 0;
    }
  2. f(n)

    f(n) = 1+1/2+1/3+1/4+…+1/n

    计算出1/1~1/n所有数的和

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /*
    * 定义整型变量n,用户输入值
    * 定义浮点变量sum。求和记录数
    * 定义整型变量x,循环计数器
    * 当x小于等于用户输入数时,x的值从1开始
    * sum的值等于sum加上1/x
    * 每轮循环结束x的值都会加1*/
    #include <stdio.h>

    int main() {
    int n;
    scanf("%d", &n);
    double sum = 0.0;
    for (int x = 1; x <= n ; x++) {
    sum += 1.0 / x ;
    }
    printf("f(%d)=%f", n, sum);
    return 0;
    }

    如果f(n)=1-1/2+1/3-1/4+1/5…+1/n呢?

    实现方式也很简单的,只需要定义一个浮点类型的变量,初始值等于1,当每次循环结束前,将这个浮点类型的变量变成负数,修改分母为这个变量即可

    1
    2
    3
    double z = 1.0;
    sum += z / x;
    z = -z;

评论