C语言 - 分支与循环 下

简介: C语言 - 分支与循环

四、循环语句

1.while

while(表达式)

{

  循环语句;

}

看代码:在屏幕上打印1-10

#include<stdio.h>
//硬核输出
int main01()
{
  printf("1 2 3 4 5 6 7 8 9 10");//如果要打印1-100,甚至更多 - 那太麻烦了
  return 0;
}
//循环输出
int main02()
{
  //循环的起始是1,终止是10
  int i = 1;//初始化部分
  while (i <= 10)//判断部分
  {
    printf("%d ", i);
    i++;//调整部分
  }
  //三个部分任何一个部分发生变化,都会影响到循环
  return 0;
} 

while循环中的break和continue

#include<stdio.h>
int main01()
{
  int i = 1;
  while (i <= 10)
  {
    if (5 == i)
    {
      break;
    }
    printf("%d ", i);
    i++;
  }
  //结果是1 2 3 4 - 一旦满足条件break就永久跳出循环
  return 0;
}
int main02()
{
  int i = 1;
  while (i <= 10)
  {
    if (5 == i)
    {
      continue;
    }
    printf("%d ", i);
    i++;
  }
  //结果是1 2 3 4 ... ...  - 死循环  - continue的作用是跳过本次循环continue后面的代码,直接去while循环判断部分,进行下一次循环入口的判断
  //这里造成死循环的原因是一旦5==5成立,则会跳过下面的代码(跳过了i++),回到while(i<=10) 
  return 0;
}

getchar和putchar

int main01()
{
  //getchar可以从键盘读取一个字符 - 它的返回值是字符(所对应的ASCII码值);如果读取时遇到了错误或文件结束,则返回EOF
  //putchar可以输出一个字符
  //EOF - end of file - 文件结束标志 - 右击可以对EOF转到定义,发现EOF的值是-1 
  int ch = getchar();
  printf("%c\n", ch);
  putchar(ch);
  //发现它不管输入多少字符,只能输出一个
  return 0;
}
//使用循环的方式让putchar能输出多个字符
int main02()
{
  int ch = 0;
  while ((ch = getchar()) != EOF)
  {
    putchar(ch);
  }
  //事实上getchar不是直接从键盘上读,而是在getchar与键盘之间的缓冲区读
  //当输入"A回车"后 - 缓冲区其实存在两个字符 - 'A','\n'
  //CTRL+Z - getchar就读取结束
  return 0;
}

getchar所应用的场景:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main01()
{
  char password[20] = { 0 };
  printf("请输入密码:>");
  //对于数组的数组名本身就是一个地址 - 所以可以不用&
  scanf("%s", &password);//123456\n
  printf("请确认密码(Y/N):>");
  int ch = getchar();
  if (ch == 'Y')
  {
    printf("确认成功\n");
  }
  else
  {
    printf("确认失败\n");
  }
  //发现我们在输入密码回车后 - 程序并没有等待我们确认密码 - 而是直接确认失败
  //我们都知道:scanf和getchar在读取数据时,是在输入缓冲区里读
  //当我们输入123456\n时,scanf只会读取除\n以外的数据;这时输入缓冲区里还剩1个\n,getchar一看输入缓冲区里有内容,就直接拿走了;'\n'=='Y'为假,执行else
  return 0;
}
//改正后:
int main02()
{
  char password[20] = { 0 };
  printf("请输入密码:>");
  scanf("%s", &password);//123456 abcdef\n
  printf("请确认密码(Y/N):>");
  getchar();//清理缓冲区 - 把\n拿走
  int ch = getchar();
  if (ch == 'Y')
  {
    printf("确认成功\n");
  }
  else
  {
    printf("确认失败\n");
  }
  //这里我们输入123456 abcdef\n时发现它又停不下来了
  //scanf这里只会把空格前面的字符读走,此时在缓冲区里还剩很多的字符
  return 0;
}
//改正后的改正:
int main03()
{
  char password[20] = { 0 };
  printf("请输入密码:>");
  scanf("%s", &password);//123456 abcdef\n
  printf("请确认密码(Y/N):>");
  int temp = 0;
  while ((temp = getchar()) != '\n')//使用循环清理缓冲区里的多个字符
  {
    ;
  }
  int ch = getchar();
  if (ch == 'Y')
  {
    printf("确认成功\n");
  }
  else
  {
    printf("确认失败\n");
  }
  return 0;
}

看代码:结果是什么

#include<stdio.h>
int main()
{
  int ch = 0;
  while ((ch = getchar()) != EOF)
  {
    if (ch<'0' || ch>'9')//如果是非数字字符则执行continue跳过本次循环,再次判断;否则就输出
    {
      continue;
    }
    else
    {
      putchar(ch);
    }
  }
  //这段程序的功能是只打印数字
  return 0;
}

2.for

for (表达式; 表达式; 表达式)

{

   循环语句;

}

已经学习了while循环了,为什么还要学习for循环?或者说while循环有什么缺陷?

#include<stdio.h>
int main01()
{
  int i = 1;//初始化部分
  //...
  //...
  while (i <= 10)//判断
  {
    printf("%d ", i);
  }
  //...
  //...
  i++;//调整
  //在未来写的代码越来越多的时候,这三个部分可能会隔的比较远,导致更改或阅读不方便
  return 0;
}
//for循环很好的规避了这个问题 - 它把初始化、判断、调整三个部分放到了一个括号里
//for(表达式; 表达式; 表达式)
//for(初始化; 判断; 调整)
//看代码:使用for循环打印1-10
int main02()
{
  int i = 0;
  for (i = 1; i <= 10; i++)
  {
    printf("%d ", i);
  }
  return 0;
}

for循环中的break和continue

#include<stdio.h>
int main01()
{
  int i = 0;
  for (i = 1; i <= 10; i++)
  {
    if (5 == i)
      break;
    printf("%d ", i);//1 2 3 4
  }
  //5==5为真,终止所在的for循环
  return 0;
}
int main02()
{
  int i = 0;
  for (i = 1; i <= 10; i++)
  {
    if (5 == i)
      continue;
    printf("%d ", i);//1 2 3 4 6 7 8 9 10
  }
  //这里并没有跳过调整部分i++,所以不会死循环;而while循环中的continue很可能会跳过调整部分,造成死循环
  return 0;
}

使用for循环的建议及注意

1.不可在for循环内修改循环变量,防止for循环失去控制

#include<stdio.h>
int main()
{
  int i = 0;
  for (i = 1; i <= 10; i++)
  {
    printf("%d ", i);
    i = 5;// - err:死循环的原因
  }
  return 0;
}

2.建议for语句的循环控制变量的取值采用“前闭后开区间的写法”

#include<stdio.h>
int main()
{
  int arr[10] = { 0 };
  int i = 0;
  //不建议写成for(i=0;i<=9;i++) - 前闭后闭区间 - 并不是这种写法是错的 - 而是说可读性相对来说较差
  for (i = 0; i < 10; i++)
  {
    printf("%d ", arr[i]);
  }
  return 0;
}

3.for循环中关于定义初始化问题

#include<stdio.h>
int main()
{
  //这里是把i定义到了for循环内部
  for (int i = 0; i < 10; i++)
  {
    printf("%d ", i);
  }
  //发现在VS2017中运行没有问题,其实这种写法是C++的语法。虽然可以运行,但是在其它平台上可能会造成跨平台的问题
  return 0;
}

for循环的一些其它形式

1.

#includ<stdio.h>
int main()  
{
  //for循环的初始化、判断、调整都可以省略,语法是支持的 - 但不建议
  //判断部分的省略 - 恒为真 - 死循环
  for (;;)
  {
    printf("hehe\n");
  }
  return 0;
}

先看代码:共输出了多少“hehe”

#include<stdio.h>
int main01()
{
  int i = 0;
  int j = 0;
  for (i = 0; i < 3; i++)
  {
    for (j = 0; j < 3; j++)
    {
      printf("hehe\n");//共打印9个"hehe"
    }
  }
  return 0;
}
//拿上面的代码来说:因为已经定义了i和j,所以将for循环里的i=0和j=0省略?
int main02()
{
  int i = 0;
  int j = 0;
  for (; i < 3; i++)
  {
    for (; j < 3; j++)
    {
      printf("hehe\n");//共打印3个"hehe"
    }
  }
  //这里当i=0时,在内层循环输出3个“hehe”后;i=1,此时这里的j=3,并没有被重新初始化为0
  return 0;
}

#include<stdio.h>
int main()
{
  int x, y;
  for (x = 0, y = 0; x < 2 && y < 5; ++x, y++)
  {
    printf("hehe\n");//输出2个“hehe”
  }
  return 0;
}

小试牛刀 - 问循环循环多少次

int main()
{
  int i = 0;
  int k = 0;
  for (i = 0, k = 0; k = 0; i++, k++)
  {
    k++;
  }
  //因为k=0为假,所以不会进入到循环内部
  return 0;
}

3.do while

do

{

  语句;

}while(表达式);

这个语句很有个性比较喜欢先斩后奏 - 先执行后判断

打印1-10

#include<stdio.h>
int main()
{
  int i = 1;
  do
  {
    printf("%d ", i);
    i++;
  } while (i <= 10);
  return 0;
}

do…while循环中的break和continue

#include<stdio.h>
int main01()
{
  int i = 1;
  do
  {
    if (5 == i)
      break;
    printf("%d ", i);//1 2 3 4
    i++;
  } while (i <= 10);
  return 0;
}
int main02()
{
  int i = 1;
  do
  {
    if (5 == i)
      continue;
    printf("%d ", i);//1 2 3 4...死循环
    i++;
  } while (i <= 10);
  //当5==5为真时,它会跳过调整部分i++,到判断部分
  return 0;
}

do…while循环的特点:循环至少执行1次,使用的场景有限,所以不是经常使用

五、跳转语句

1.goto

c语言提供了可以随意滥用的goto语句和标记跳转的标号;从理论上goto语句是没有必要的,但是在某些场合还是有用的着的地方

最常见的用法就是终止程序在某些深度嵌套的结构的处理过程,例如一次跳出两层或多层循环,这种情况break是不适合的。除此之外不建议使用goto

for (…)

{

  for (…)

 {

  for (…)

   {

    if (disaster)

     goto error;

   }

  }

}

注:goto语句只能在一个函数范围内跳转,不能跨函数

int main()
{
  flag:
  printf("hehe\n");
  printf("haha\n");
  goto flag;
  //结果是死循环 - 这里goto定义了flag;当每次走到goto语句时它都会跳转到与flag匹配的地方
  return 0;
}


相关文章
|
3月前
|
C语言
C语言分支和循环语句
分支语句由`if-else`构成,用于根据不同条件执行相应代码。`else`会与最近未配对的`if`结合,多个条件可用`else if`实现。若连续使用`if`,各条件互不影响。嵌套结构可在`if`中再加入`if-else`。此外,`switch`语句适用于多分支选择(注意表达式不能为浮点数,`case`后需加`break`)。循环语句包括`for`、`while`和`do...while`,注意`do...while`末尾需加分号。循环中,`break`直接终止循环,`continue`跳过当前循环剩余部分,但`for`的语句三仍会执行,而`while`中位置影响效果。
45 0
|
11月前
|
C语言
初识C语言2——分支语句和循环语句
初识C语言2——分支语句和循环语句
210 5
|
7月前
|
人工智能 Java 程序员
一文彻底搞清楚C语言的循环语句
本文介绍了C语言中的三种循环语句:`while`、`do-while`和`for`,并详细解释了它们的语法格式、执行流程及应用场景。此外,还讲解了循环控制语句`break`和`continue`的使用方法。希望这些内容能帮助你在编程道路上不断进步,共同成长!
421 0
一文彻底搞清楚C语言的循环语句
|
8月前
|
C语言
【C语言程序设计——循环程序设计】枚举法换硬币(头歌实践教学平台习题)【合集】
本文档介绍了编程任务的详细内容,旨在运用枚举法求解硬币等额 - 循环控制语句(`for`、`while`)及跳转语句(`break`、`continue`)的使用。 - 循环嵌套语句的基本概念和应用,如双重`for`循环、`while`嵌套等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台将对编写的代码进行测试,并给出预期输出结果。 5. **通关代码**:提供完整的代码示例,帮助理解并完成任务。 6. **测试结果**:展示代码运行后的实际输出,验证正确性。 文档结构清晰,逐步引导读者掌握循环结构与嵌套的应用,最终实现硬币兑换的程序设计。
126 19
|
8月前
|
算法 C语言
【C语言程序设计——循环程序设计】求解最大公约数(头歌实践教学平台习题)【合集】
采用欧几里得算法(EuclideanAlgorithm)求解两个正整数的最大公约数。的最大公约数,然后检查最大公约数是否大于1。如果是,就返回1,表示。根据提示,在右侧编辑器Begin--End之间的区域内补充必要的代码。作为新的参数传递进去。这个递归过程会不断进行,直到。有除1以外的公约数;变为0,此时就找到了最大公约数。开始你的任务吧,祝你成功!是否为0,如果是,那么。就是最大公约数,直接返回。
203 18
|
8月前
|
Serverless C语言
【C语言程序设计——循环程序设计】利用循环求数值 x 的平方根(头歌实践教学平台习题)【合集】
根据提示在右侧编辑器Begin--End之间的区域内补充必要的代码,求解出数值x的平方根;运用迭代公式,编写一个循环程序,求解出数值x的平方根。注意:不能直接用平方根公式/函数求解本题!开始你的任务吧,祝你成功!​ 相关知识 求平方根的迭代公式 绝对值函数fabs() 循环语句 一、求平方根的迭代公式 1.原理 在C语言中,求一个数的平方根可以使用牛顿迭代法。对于方程(为要求平方根的数),设是的第n次近似值,牛顿迭代公式为。 其基本思想是从一个初始近似值开始,通过不断迭代这个公式,使得越来越接近。
166 18
|
8月前
|
C语言
【C语言程序设计——循环程序设计】统计海军鸣放礼炮声数量(头歌实践教学平台习题)【合集】
有A、B、C三艘军舰同时开始鸣放礼炮各21响。已知A舰每隔5秒1次,B舰每隔6秒放1次,C舰每隔7秒放1次。编程计算观众总共听到几次礼炮声。根据提示,在右侧编辑器Begin--End之间的区域内补充必要的代码。开始你的任务吧,祝你成功!
166 13
|
8月前
|
存储 C语言
【C语言程序设计——循环程序设计】利用数列的累加和求 sinx(头歌实践教学平台习题)【合集】
项的累加和,一般会使用循环结构,在每次循环中计算出当前项的值(可能基于通项公式或者递推关系),然后累加到一个用于存储累加和的变量中。在C语言中推导数列中的某一项,通常需要依据数列给定的通项公式或者前后项之间的递推关系来实现。例如,对于一个简单的等差数列,其通项公式为。的级数,其每一项之间存在特定的递推关系(后项的分子是其前项的分子乘上。,计算sinx的值,直到最后一项的绝对值小于。为项数),就可以通过代码来计算出指定项的值。对于更复杂的数列,像题目中涉及的用于近似计算。开始你的任务吧,祝你成功!
197 6
|
8月前
|
C语言
【C语言程序设计——循环程序设计】鸡兔同笼问题(头歌实践教学平台习题)【合集】
本教程介绍了循环控制和跳转语句的使用,包括 `for`、`while` 和 `do-while` 循环,以及 `break` 和 `continue` 语句。通过示例代码详细讲解了这些语句的应用场景,并展示了如何使用循环嵌套解决复杂问题,如计算最大公因数和模拟游戏关卡选择。最后,通过鸡兔同笼问题演示了穷举法编程的实际应用。文中还提供了编程要求、测试说明及通关代码,帮助读者掌握相关知识并完成任务。 任务描述:根据给定条件,编写程序计算鸡和兔的数量。鸡有1个头2只脚,兔子有1个头4只脚。
403 5
|
11月前
|
C语言
【c语言】分支语句
C语言通过三种基本结构——顺序、选择和循环,构建复杂的程序逻辑。本文主要介绍了C语言的选择结构,即if-else语句及其变体,包括简单的if语句、if-else组合、else if多分支判断、嵌套if以及解决悬空else问题的方法。此外,还详细讲解了逻辑运算符和关系运算符的使用,以及如何利用条件操作符简化逻辑判断。最后,文章对比了if-else与switch语句在实现多分支逻辑时的应用,并解释了switch语句中的break和default关键字的作用。
158 8