10. C语言 -- 循环结构:for 语句和嵌套循环

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dugudaibo/article/details/82885109

本博客主要内容为 “小甲鱼” 视频课程《带你学C带你飞》【第一季】 学习笔记,文章的主题内容均来自该课程,在这里仅作学习交流。在文章中可能出现一些错误或者不准确的地方,如发现请积极指出,十分感谢。
也欢迎大家一起讨论交流,如果你觉得这篇文章对你有所帮助,记得评论、点赞哦 ~(。・∀・)ノ゙

1. 循环的基本结构

  循环的基本结构一般如下图所示

通常一个循环都将涉及到三个动作,初始化计数器、判断循环条件是否满足和更新计数器。但是这种方式导致我们书写一个 while 循环至少需要三个语句,为了简化可以使用 for 循环。

2. for 语句

  for 语句的用法如下所示

for (表达式1; 表达式2; 表达式3)
        循环体

在 for 语句中三个表达式用分号隔开,其中表达式1是循环初始化表达式(对应上面的 “初始化计数器”),表达式2是循环条件表达式(对应上面的 “循环条件”),表达式3是循环调整表达式(对应上面的 “更新计数器”)。

  这样一来,for 语句将初始化计数器、循环条件判断、更新计数器三个动作组织到了在一起,那么以后如果要修改循环的次数,每次递进的跨度,或者循环结束条件,只需要在 for 语句后边的小括号内统一修改即可。

3. 灵活的 for 语句

3.1 表达式的省略

  for 语句的表达式1,表达式2和表达式3都可以按照需要进行省略,但分号不能省,其中可以是包括但不限以下的任何一种形式

for ( ; 表达式2; 表达式3)
for (表达式1; 表达式2; )
for (表达式1; ; )
for ( ; ; )

其中需要注意的是最后一个表达式,他实际上代表的是一个死循环。在程序中有死循环的存在并不代表着程序一定出现了错误,因为有的情境下需要死循环,如一个服务不停地向用户发送一个请求之类的。

3.1.1 举例说明

  下面是一个 for 语句使用的示例说明,通过 for 循环将一句话打印十遍。

#include <stdio.h>

int main()
{
        int count;
        for (count = 0; count < 10; count ++)
        {
                printf ("a line ~~~\n");
        }
        return 0;
}

  下面考虑上面所说的出现省略的情况,如下是省略表达式 1 的情况

#include <stdio.h>

int main()
{
        int count = 0;
        for (; count < 10; count ++)
        {
                printf ("a line ~~~\n");
        }
        return 0;
}

在上面的代码中,因为初始化的过程已经在之前的部分完成,所以可以在 for 语句简化这部分;当让我们还可以省略 count ++ ,将其放在循环体中,但是这种代码与 while 循环的差别也就不打了。所以除非有较为特殊的需求,否则过多的省略 for 语句,一方面使得程序较为难懂,另外也有可能降低程序的效率。

3.1.2 判断一个数字是否为素数

  素数指在大于 1 的自然数中,除了 1 和此数自身外,无法被其他自然数整除的数。关于素数的求法有很多,这里我们用比较朴素暴力的方式:迭代测试从2到num/2所有整数是否能被整除(num为待测试的整数),如果没有出现能被整除的整数,那么它就是素数。

  具体代码如下所示

#include <stdio.h>

int main()
{
        int input_num, i;
        int flag = 0;

        printf("%s: ", "input a number");
        scanf("%d", &input_num);

        for (i = 2;i <= input_num/2; i++)
        {
                if (input_num%1 == 0)
                {
                        flag = 1;
                }
        }
        if (flag == 1)
        {
                printf("It is a prime number\n");
        }
        else{
                printf("It is not a prime number\n");
        }
        return 0;
}

执行上面的程序可以根据输入判断其是否为一个素数,这种判断方式较为麻烦,只是对本节课 for 循环的一个联系,在后面会介绍更为简单的方法。

3.2 逗号表达式

  表达式1和表达式3可以是一个简单的表达式,也可以是逗号表达式,即用逗号分隔多个表达式,如下所示

#include <stdio.h>

int main()
{
        int i,  j;
        for ( i=0,  j=10; i < j; i++, j--)
        {
                printf("%d\n", i);
        }

        return 0;
}

在表达式 1 中,同时对 i j 两个变量进行初始化,同样的,在表达式 3 中同时对两个变量的值进行调整。

3.3 在表达式 1 中定义变量

  在 C99 的新标准中允许在 for 语句的表达式 1 中定义变量,如下所示

#include <stdio.h>

int main()
{
        for (int i=0, int j=10; i < j; i++, j--)
        {
                printf("%d\n", i);
        }

        return 0;
}

使用 gcc 进行编译的时候需要加上 –std=c99,否则可能会出错。因此在编译的时候在终端中输入

gcc –std=c99 test.c && ./a.out

其中的 test.c 为上述代码所对应的 C 文件。

  增加这个新特性的原因主要是考虑到循环通常需要一个计数器,而这个计数器出了循环就没什么用了。所以在表达式1的位置定义的变量,活动范围仅限于循环中,出了循环,它就无效了。这个从原理上涉及到变量的生命周期,具体的将会在后面的函数的部分讲述。

4. 循环嵌套

  循环结构跟分支结构一样,都可以实现嵌套。对于嵌套的循环结构,执行顺序是从内到外:先执行内层循环,再执行外层循环。

4.1 举例说明

  在下面的双层循环中,我们打印出变量 i j 来看看是否先执行内层循环,再执行外层循环。

#include <stdio.h>

int main()
{
	int i, j;

	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 3; j++)
		{
			printf("i = %d, j = %d\n", i, j);
		}
	}

	return 0;
}

执行这个程序的结果可以看到
在这里插入图片描述
很明显是先执行内层循环,在执行外层循环。

4.2 打印九九乘法表

  在这里我们将联系打印输出如下的一个九九乘法表
在这里插入图片描述

这个是一个很经典的 C 语言入门编程题,可以通过刚刚所讲的循环嵌套来实现,如果将每个表达式看成 i * j,那么第一行是 i = 1,j <= i,第二行是i = 2,j <= i,……所以可以得到如下所示代码

#include <stdio.h>

int main()
{
        for (int i = 1; i < 9; i++)
        {
                for (int j = 1; j <= i; j++)
                {
                        printf("%d*%d=%-4d", i, j,i*j);
                }
                printf("\n");
        }

        return 0;
}

  其中有两点需要注意,首先是 %-4d,这里的 - 表示左对齐,因为默认是右对齐,里面的 4 表示占 4 个字符;其次是在每一次循环结束之后会打印一个回车符号以换行。执行后的结果如下所示
在这里插入图片描述

参考

[1] “小甲鱼” 视频课程《带你学C带你飞》【第一季】P14

欢迎大家关注我的知乎号(左侧)和经常投稿的微信公众号(右侧)
在这里插入图片描述

没有更多推荐了,返回首页