【重学C语言】六、循环结构

【重学C语言】六、循环结构

  • 基本循环结构
    • `while` 循环
    • `do...while` 循环
    • `for` 循环
    • 死循环
  • 应用场景
  • 循环嵌套
    • 1. 处理二维数组
    • 2. 打印图案或文本
    • 3. 矩阵运算
    • 4. 复杂逻辑和算法
  • 两个简单算法
    • 拆分数字
    • 统计大写小写数字其他字符个数
  • 跳转语句
    • 1. `break` 语句
    • 2. `continue` 语句
    • 3. `goto` 语句(不推荐使用)

基本循环结构

while 循环

while循环是一种控制结构,它重复执行一段代码,只要给定的条件为真(非零)。一旦条件变为假(零),循环就停止执行。

while循环的基本语法如下:

while (condition) {// 循环体:要重复执行的代码
}

这里,condition是一个表达式,每次循环迭代前都会评估这个表达式。如果condition的值为真(非零),那么循环体内的代码就会执行。如果condition的值为假(零),那么循环就会终止,程序会继续执行while循环之后的代码。

下面是一个简单的例子,展示了如何使用while循环来打印从1到5的数字:

#include <stdio.h>int main() {int i = 1;while (i <= 5) {printf("%d\n", i);i++; // 更新循环变量}return 0;
}

在这个例子中,我们初始化了一个变量i为1,然后使用while循环来检查i是否小于或等于5。如果是,我们就打印i的值,并将i增加1。这样,每次循环迭代时,i的值都会增加,直到它不再小于或等于5,循环就会终止。

注意,在使用while循环时,确保循环有一个明确的终止条件,否则你可能会创建一个无限循环,这会导致程序永远运行下去,直到系统资源耗尽。此外,通常还需要在循环体内更新循环条件中使用的变量,以确保循环最终会终止。

do...while 循环

do-while循环与while循环类似,但有一个关键的区别:do-while循环至少会执行一次循环体,然后再检查条件。这意味着,即使条件在第一次检查时就为假,do-while循环体中的代码也至少会被执行一次。

do-while循环的基本语法如下:

do {  // 循环体:要重复执行的代码  
} while (condition);

这里,condition是一个表达式,在每次循环迭代结束后都会评估这个表达式。如果condition的值为真(非零),那么循环体内的代码会再次执行。如果condition的值为假(零),那么循环就会终止,程序会继续执行do-while循环之后的代码。

下面是一个简单的例子,展示了如何使用do-while循环来打印从1到5的数字:

#include <stdio.h>  int main() {  int i = 1;  do {  printf("%d\n", i);  i++; // 更新循环变量  } while (i <= 5);  return 0;  
}

在这个例子中,我们初始化了一个变量i为1,然后使用do-while循环来打印i的值,并将i增加1。与while循环不同,即使i的初始值就大于5,do-while循环体中的代码也至少会被执行一次(在这个例子中,这种情况不会发生,因为i的初始值是1)。然后,每次循环迭代结束后,都会检查i是否小于或等于5。如果是,循环继续;如果不是,循环终止。

请注意,do-while循环末尾的分号(;)是必须的,它标志着循环语句的结束。同时,确保循环体中有适当的更新逻辑,以便循环条件最终能够变为假,从而避免无限循环。

for 循环

for循环是一种非常常用的控制结构,用于重复执行一段代码块指定的次数。for循环提供了一个简洁的方式来初始化循环变量、检查循环条件和更新循环变量。

for循环的基本语法如下:

for (initialization; condition; update) {// 循环体:要重复执行的代码
}
  • initialization:在循环开始之前执行的初始化表达式,不仅仅是简单表达式,通常用于设置循环变量的初始值。
  • condition:在每次循环迭代之前检查的表达式。如果条件为真(非零),则执行循环体;如果为假(零),则终止循环。
  • update:在每次循环迭代之后执行的表达式,通常用于更新循环变量。

下面是一个简单的例子,展示了如何使用for循环来打印从1到5的数字:

#include <stdio.h>int main() {int i;for (i = 1; i <= 5; i++) {printf("%d\n", i);}return 0;
}

在这个例子中,我们初始化了一个变量i为1,然后在for循环中检查i是否小于或等于5。如果是,就打印i的值,并将i增加1(通过i++)。这个过程会一直重复,直到i不再小于或等于5,循环就会终止。

for循环的初始化、条件和更新部分都是可选的,但通常情况下,你会看到所有这些部分都被使用。这允许你在一个紧凑的结构中控制循环的各个方面。

下面是一个更复杂的例子,展示了for循环的所有部分都可以如何使用:

#include <stdio.h>int main() {int i, sum = 0;for (i = 1, sum = 0; i <= 10; i++, sum += i) {// 循环体为空,因为所有的工作都在初始化和更新部分完成}printf("Sum of numbers from 1 to 10: %d\n", sum);return 0;
}

在这个例子中,我们在初始化部分同时初始化了两个变量isum。在条件部分,我们检查i是否小于或等于10。在更新部分,我们同时增加了i的值和sum的值(通过将i的值加到sum上)。循环体是空的,因为所有的计算都在初始化和更新部分完成了。最后,我们打印出1到10之间所有数字的和。

死循环

死循环是一个无限循环,即循环永远不会自然终止,除非被外部因素(如用户中断或程序崩溃)所打断。这通常是由于循环条件永远为真,或者循环体内没有包含任何能改变循环条件的代码。

以下是一个死循环的例子:

#include <stdio.h>int main() {while (1) { // 这里的条件永远为真// 循环体:这里的代码会无限次地重复执行printf("This is an infinite loop.\n");}return 0; // 这行代码实际上永远不会被执行到,因为循环永远不会结束
}

在这个例子中,while循环的条件是常量表达式1,它永远为真(非零)。因此,循环体会无限次地执行,打印出消息"This is an infinite loop."。由于循环条件永远不会变为假,所以return 0;语句永远不会被执行到。

另一个常见的死循环例子是使用for循环:

#include <stdio.h>int main() {for (;;) { // 这里没有条件,所以默认为真// 循环体:这里的代码会无限次地重复执行printf("This is also an infinite loop.\n");}return 0; // 这行代码同样永远不会被执行到
}

在这个例子中,for循环没有提供任何条件,这意味着循环条件默认为真。因此,这也是一个死循环。

在实际编程中,死循环通常是不希望出现的,因为它们会导致程序无法正常终止,消耗系统资源,甚至可能导致系统崩溃。因此,在编写循环时,应确保循环条件能够在某一点变为假,以便循环能够自然终止。如果确实需要实现某种形式的永久运行(例如服务器程序),则应提供外部机制(如信号处理)来安全地停止程序。

应用场景

  1. 重复执行特定任务
    当需要重复执行某个任务多次时,可以使用循环结构。例如,计算一个数的累加和、打印某个模式的多个副本,或者重复读取用户输入直到满足特定条件。

  2. 遍历数组或集合
    对于数组、链表或其他集合类型的数据结构,经常需要遍历其中的每个元素以执行某种操作。循环结构可以方便地实现这一点。

  3. 数值计算
    在科学计算、物理模拟或其他数值计算任务中,经常需要执行大量的重复计算。循环结构使得这些计算变得高效且易于管理。

  4. 文件处理
    当处理大量数据时,例如从文件中读取或写入数据,循环结构可以帮助逐行或逐个元素地处理数据。

  5. 游戏和图形编程
    在编写游戏或图形程序时,循环结构常用于更新游戏状态、渲染图形或处理用户输入。

  6. 事件驱动编程
    在某些情况下,程序可能需要根据特定事件(如定时器事件、中断或用户输入)重复执行代码。循环结构可以与事件处理机制结合使用,以实现这一功能。

  7. 算法实现
    许多算法(如排序、搜索、递归等)都涉及到重复执行某些步骤,这些步骤通常通过循环结构来实现。

  8. 模拟和仿真
    在模拟或仿真系统中,可能需要模拟一系列时间步长或迭代来观察系统的行为。循环结构使得这种模拟变得简单且高效。

下面是一个简单的例子,展示了如何在C语言中使用for循环来计算一个数的阶乘:

#include <stdio.h>int main() {int n, factorial = 1;printf("Enter a positive integer: ");scanf("%d", &n);for (int i = 1; i <= n; i++) {factorial *= i;}printf("Factorial of %d is %d\n", n, factorial);return 0;
}

在这个例子中,用户输入一个正整数n,程序使用一个for循环来计算n的阶乘(即n!),并将结果打印出来。这个循环从1迭代到n,并在每次迭代中将当前的循环变量i乘以factorial。最终,factorial变量将包含n的阶乘。

循环嵌套

循环嵌套是编程中一种常见的结构,指的是在一个循环体内部又包含另一个或多个循环。可以使用whiledo-whilefor循环来创建嵌套循环。嵌套循环在处理二维数组、矩阵运算、打印图案或执行需要多次迭代的复杂任务时非常有用。

1. 处理二维数组

当你需要遍历一个二维数组(例如矩阵)时,通常会使用嵌套循环。外层循环遍历行,内层循环遍历列。

#include <stdio.h>int main() {int matrix[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};int i, j;for (i = 0; i < 3; i++) {for (j = 0; j < 3; j++) {printf("%d ", matrix[i][j]);}printf("\n"); // 换行,以便每行数据单独显示}return 0;
}

2. 打印图案或文本

嵌套循环常用于在控制台上打印出特定的图案或文本格式。

#include <stdio.h>int main() {int i, j, n = 5;for (i = 1; i <= n; i++) {for (j = 1; j <= i; j++) {printf("* ");}printf("\n");}for (i = n - 1; i >= 1; i--) {for (j = 1; j <= i; j++) {printf("* ");}printf("\n");}return 0;
}

这段代码会打印出一个由星号组成的菱形图案。

3. 矩阵运算

嵌套循环常用于执行矩阵加法、乘法或其他运算。

#include <stdio.h>#define SIZE 3void matrixAddition(int a[SIZE][SIZE], int b[SIZE][SIZE], int result[SIZE][SIZE]) {int i, j;for (i = 0; i < SIZE; i++) {for (j = 0; j < SIZE; j++) {result[i][j] = a[i][j] + b[i][j];}}
}int main() {int matrixA[SIZE][SIZE] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};int matrixB[SIZE][SIZE] = {{9, 8, 7}, {6, 5, 4}, {3, 2, 1}};int result[SIZE][SIZE];int i, j;matrixAddition(matrixA, matrixB, result);for (i = 0; i < SIZE; i++) {for (j = 0; j < SIZE; j++) {printf("%d ", result[i][j]);}printf("\n");}return 0;
}

这段代码定义了一个函数matrixAddition,它接受两个矩阵作为输入,并返回它们的和。主函数main中初始化了两个矩阵,调用了matrixAddition函数,并打印出结果矩阵。

4. 复杂逻辑和算法

嵌套循环还常用于实现更复杂的逻辑和算法,例如搜索、排序或其他涉及多维数据结构的操作。

在使用嵌套循环时,务必注意循环的终止条件,以避免无限循环或意外的行为。同时,优化嵌套循环的性能也是编程中的一个重要考虑因素,特别是在处理大量数据时。

两个简单算法

拆分数字

如果你想要拆分一个数字(例如,将一个整数拆分为其各个位上的数字),你可以通过不断地除以10并取余数来实现。以下是一个简单的示例,它演示了如何将一个整数拆分为其个位、十位、百位等上的数字:

#include <stdio.h>int main() {int number, originalNumber, remainder, position = 1;printf("请输入一个整数:");scanf("%d", &number);originalNumber = number; // 保存原始数字以便后续输出printf("数字的各位分别为:\n");while (number != 0) {remainder = number % 10; // 取最后一位数字printf("第%d位:%d\n", position, remainder);number /= 10; // 去掉最后一位数字position++; // 增加位数}printf("原始数字是:%d\n", originalNumber);return 0;
}

在这个程序中,我们首先让用户输入一个整数。然后,我们使用一个while循环来不断地除以10并取余数,直到数字变为0。在每次循环中,我们都打印出当前位上的数字,并增加位数计数器。最后,我们打印出原始的输入数字。

例如,如果用户输入数字12345,程序将输出:

请输入一个整数:12345
数字的各位分别为:
第1位:5
第2位:4
第3位:3
第4位:2
第5位:1
原始数字是:12345

注意,这个程序假设用户输入的是一个正整数。如果用户输入了0或负数,程序仍然可以工作,但输出可能会有些不同(例如,对于0,不会有任何位被打印出来)。如果需要处理负数或0的特殊情况,你需要在代码中添加额外的逻辑来处理这些情况。

统计大写小写数字其他字符个数

不使用数组、字符串、函数和指针来统计大写字母、小写字母、数字和其他字符的个数是一项挑战,因为通常字符串操作都是通过指针和数组进行的。但是,如果我们假设输入是通过逐个字符的方式提供的,而不是作为字符串,那么我们可以使用变量来直接处理每个输入的字符。

以下是一个简单的示例,该示例通过逐个字符的输入来统计大写字母、小写字母、数字和其他字符的个数:

#include <stdio.h>int main() {char ch;int uppercase = 0, lowercase = 0, digit = 0, other = 0;printf("请输入字符(输入'q'退出):\n");// 循环读取字符直到输入'q'while (1) {ch = getchar(); // 从标准输入读取一个字符if (ch == 'q') { // 如果输入是'q',则退出循环break;}if (ch >= 'A' && ch <= 'Z') { // 大写字母uppercase++;} else if (ch >= 'a' && ch <= 'z') { // 小写字母lowercase++;} else if (ch >= '0' && ch <= '9') { // 数字digit++;} else { // 其他字符other++;}}// 打印统计结果printf("大写字母个数: %d\n", uppercase);printf("小写字母个数: %d\n", lowercase);printf("数字个数: %d\n", digit);printf("其他字符个数: %d\n", other);return 0;
}

在这个程序中,我们使用getchar()函数从标准输入读取一个字符,然后检查该字符是否是大写字母、小写字母、数字或其他字符,并相应地增加计数器。当用户输入字符’q’时,程序退出循环并打印统计结果。

需要注意的是,这个示例仅适用于从标准输入逐个读取字符的情况。如果你有一个预先定义好的字符串并且不能使用指针或数组来访问它,那么在不使用这些工具的情况下进行字符统计是不可能的,因为你需要某种方式来遍历字符串中的字符。在C语言中,遍历字符串通常是通过指针或数组索引实现的。

跳转语句

跳转语句用于改变程序的正常执行流程,即跳过某些语句或提前结束循环。这些跳转语句主要包括breakcontinuegoto

1. break 语句

break语句用于提前终止循环或switch语句的执行。当break语句被执行时,程序会立即跳出包含它的最内层循环或switch语句,并继续执行后面的语句。

示例

#include <stdio.h>int main() {int i;for (i = 0; i < 10; i++) {if (i == 5) {break; // 当 i 等于 5 时,跳出循环}printf("%d ", i);}return 0;
}

在这个例子中,当i等于5时,break语句会被执行,循环会被提前终止,因此输出只会是0 1 2 3 4

2. continue 语句

continue语句用于跳过循环体中剩余的语句,并立即开始下一次循环迭代。

示例

#include <stdio.h>int main() {int i;for (i = 0; i < 10; i++) {if (i == 5) {continue; // 当 i 等于 5 时,跳过本次循环的剩余部分}printf("%d ", i);}return 0;
}

在这个例子中,当i等于5时,continue语句会被执行,跳过printf语句,直接开始下一次循环迭代。因此,输出会是0 1 2 3 4 6 7 8 9

3. goto 语句(不推荐使用)

goto语句用于无条件地跳转到程序中标记的位置。尽管goto在某些情况下可能有用,但通常不建议使用它,因为它会使程序流程变得难以理解和维护。现代编程风格更倾向于使用结构化编程方法,如循环和条件语句,来组织代码。

示例(尽管不推荐使用):

#include <stdio.h>int main() {int i = 0;if (i == 0) {goto skip; // 跳转到标记为 skip 的位置}printf("This will not be printed.\n");
skip:printf("This will be printed.\n");return 0;
}

在这个例子中,goto语句会使程序跳过printf("This will not be printed.\n");语句,直接跳转到标记为skip的位置,并输出This will be printed.

总的来说,breakcontinue是循环结构中常用的跳转语句,而goto则应当谨慎使用,并尽量避免在复杂的程序中使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/811657.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ETL结合飞书快速实现业务信息同步

一、ETL工具介绍 ETLCloud数据集成平台是一款针对IT以及数据工程师推出的全域数据集成平台产品。它是集实时数据集成和离线数据集成以及API发布为一体的数据集成平台。与其他开源数据集成工具相比&#xff0c;系统采用轻量化架构、具有更快的部署速度、更快的数据传输速度、更…

MS7336MA高清 HD/全高清 FHD 可选择视频运放与视频同轴线控解码

产品简述 MS7336MA 是一颗集成单通道视频放大器与视频同轴线控解 码为一体的芯片&#xff0c;它内部集成 6dB 增益轨到轨输出驱动器以及 10 阶滤波器&#xff0c;允许同一个输入信号在 -3dB 带宽 35MHz 和 55MHz 之间进行选择控制。视频同轴线控解码内部集成一颗高…

【数据解构】二叉搜索树

二叉查找树&#xff08;Binary Search Tree&#xff09;&#xff0c;&#xff08;又&#xff1a;二叉搜索树&#xff0c;二叉排序树&#xff09;它或者是一棵空树&#xff0c;或者是具有下列性质的二叉树&#xff1a; 若它的左子树不空&#xff0c;则左子树上所有结点的值均小于…

ChatGPT论文写作指南:写出引人注目的论文

ChatGPT无限次数:点击直达 ChatGPT论文写作指南&#xff1a;写出引人注目的论文 作为一名有着10年经验的专业CSDN网站原创文章优质创作者&#xff0c;在当今的信息爆炸时代&#xff0c;论文写作的重要性愈发显现。如何能够写出引人注目的论文&#xff0c;吸引读者的眼球并获得…

uniapp uview里面的u-navbar结合u-sticky组件的使用

导航栏自定义加需要吸顶产生的问题 如上图直接使用并不能出现tab栏吸顶效果&#xff0c;那是由于u-sticky组件吸顶时与顶部的距离默认为0 那么做如下处理 <u-sticky :offset-top"navbarHeight()"><u-tabs :list"helpTabList" active-color"…

SGI_STL空间配置器源码剖析(六)deallocate函数

deallocate函数是内存释放函数。源码及注释如下&#xff1a; /* __p may not be 0 */static void deallocate(void* __p, size_t __n) // __p指向要回收的内存起始地址&#xff0c;__n表示其大小{if (__n > (size_t) _MAX_BYTES)// 大于128字节&#xff0c;普通方式开辟和回…

电商技术揭秘22:智能仓储与物流优化(上)

相关系列文章 电商技术揭秘一&#xff1a;电商架构设计与核心技术 电商技术揭秘二&#xff1a;电商平台推荐系统的实现与优化 电商技术揭秘三&#xff1a;电商平台的支付与结算系统 电商技术揭秘四&#xff1a;电商平台的物流管理系统 电商技术揭秘五&#xff1a;电商平台…

AutoCAD之DWF三维信息提取---linux编译篇

1. 权限 1.1 给文件添加执行权限 chmod x autogen.sh1.2.给当前文件下的所有文件改变为读写执行权限 chmod 777 * -R 2.环境安装 2.1安装automake 1.4.1 安装链接 安装中遇到的问题及解决 2.2安装autoconf 2.3 安装libtool 2.4 安装Cmake(CMake包含) cmake安装在cent…

【IDEA】JRebel LS client not configured

主要原因就是因为 jrebel 的版本跟 idea的版本对不上&#xff0c;或者说jrebel的版本比idea的版本还高&#xff0c;导致出现该错误 查看idea版本 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a7ba43e6822947318cdb0d0e9d8d65e9.png 获取jrebel 版本 如何处理 …

java Web 中小企业门户网站用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 中小企业门户网站是一套完善的web设计系统&#xff0c;对理解JSP java 编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&#xff0c;使…

Fortnite与Roblox的市场竞争力分析

很多媒体大肆宣扬Fortnite和Roblox是元宇宙UGC平台巨头的竞争对手,但实际上它们似乎各自占据了UGC游戏市场的不同部分。对于Fortnite来说,主要是射击游戏;而对于Roblox来说,则是其他所有类型的游戏。 至少在目前,这两个平台在市场定位和用户群体上有着明显的差异,它们的…

【论文研读】Geometric Deep Learning on Molecular Representations

Geometric Deep Learning on Molecular Representationshttps://arxiv.org/pdf/2107.12375.pdf 一、Background 随着网络时代的发展&#xff0c;生活中产生的数据量越来越多&#xff0c;但数据大体分为两类&#xff1a;欧氏数据、非欧氏数据。如图为两类常见的数据&#xff0c…

视频秒播优化实践

本文字数&#xff1a;2259字 预计阅读时间&#xff1a;10分钟 视频起播时间&#xff0c;即首帧时间&#xff0c;是视频类应用的一个重要核心指标&#xff0c;也是影响用户观看体验的核心因素之一。如果视频要加载很久才能开始播放&#xff0c;用户放弃播放甚至离开 App 的概率都…

采集某新闻网资讯网站保存PDF

网址&#xff1a;融资总额近3亿美元、药明康德押注&#xff0c;这家抗衰老明星公司有何过人之处-36氪 想要抓取文章内容&#xff0c;但是找不到啊&#xff0c;可能是文字格式的问题&#xff0c;也可能文章内容进行了加密。 在元素中查看&#xff0c;window.initialState返回的就…

QQ 邮箱使用 SMTP 发送邮件报错:550 The From header is missing or invalid

文章目录 场景描述问题排查根据提示查看原因查看封装的 message 个人简介 场景描述 QQ 邮箱使用 SMTP 发送邮件报错&#xff1a;550 The From header is missing or invalid&#xff1a; 失败原因&#xff1a;(550, bThe "From" header is missing or invalid. Ple…

数据仓库—主数据管理

在当今信息爆炸的时代&#xff0c;数据已经成为企业最重要的资产之一。然而&#xff0c;许多企业在管理数据时面临着挑战&#xff0c;其中之一就是处理不同系统中的数据不一致问题。主数据管理&#xff08;Master Data Management&#xff0c;MDM&#xff09;就是为了解决这一问…

JVM修炼之路【11】- 解决内存溢出、内存泄漏 以及相关案例

前面的10篇 都是基础的知识&#xff0c;包括类加载的过程 类加载的细节&#xff0c;jvm内存模型 垃圾回收 等等&#xff0c; 这一篇我们开始实战了解一下 各种疑难杂症&#xff1a;怎么监控 怎么发现 怎么解决 内存溢出 内存泄漏 这两个概念在垃圾回收器里面已经讲过了&#…

云原生(八)、Kubernetes基础(一)

K8S 基础 # 获取登录令牌 kubectl create token admin --namespace kubernetes-dashboard1、 NameSpace Kubernetes 启动时会创建四个初始名字空间 default:Kubernetes 包含这个名字空间&#xff0c;以便于你无需创建新的名字空间即可开始使用新集群。 kube-node-lease: 该…

【学习】VScode修改侧边栏大小。

侧边栏不可以直接更改&#xff0c;所以先缩放整体界面&#xff0c;再改变工作区大小。 缩放整体界面&#xff1a; Ctrl 或 Ctrl - 。 也可以直接使用如下代码&#xff1a; Ctrl Shifit p 打开搜索 settings &#xff0c;选择下图第一个。 然后嵌入如下代码&#xff1a…

股票价格预测 | Python使用GAN预测股票价格

文章目录 效果一览文章概述代码设计效果一览 文章概述 生成对抗网络(GAN)是一种强大的机器学习模型,用于生成以假乱真的数据。然而,使用GAN来预测股票价格可能会面临以下挑战: 数据可用性:GAN需要大量的数据进行训练,以便生成准确的输出。对于股票价格预测,历史股票价…