分支语句和循环语句(下)

简介: 分支语句和循环语句(下)

contine介绍


//continue 代码实例1
#include <stdio.h>
int main()
{
  int i = 1;
  while (i <= 10)
  {
    if (i == 5)
      continue;
    printf("%d ", i);
    i++;
  }
  return 0;
}


输出结果:

db3789cfbcfd4930b857e1ca77bddf4e.png

代码分析:

8d59e5defed9407994e554027a6a7993.png

//continue 代码实例2
#include <stdio.h>
int main()
{
  int i = 0;
  while (i < 10)
  {
    i++;
    if (i == 5)
        continue;
    printf("%d ", i);
  }
  return 0;
}


输出结果:


d30c3fd75d384b8894edfe11a2ec2526.png


代码分析:


a16f42026a644e35ab9763b647c9e4b4.png


总结:


continue在while循环中的作用就是:continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,而是直接跳转到while语句的判断部分。进行下一次循环的入口判断。


  再来看一个代码:


#include <stdio.h>
int main()
{
  int ch = 0;
  while ((ch = getchar()) != EOF)
    putchar(ch);
  return 0;
}


getchar的函数原型:

e3b31ab45bbb4aae84443504a75877e7.png


这段代码可以连续地输出我们输入的字符,直至遇到Ctrl+z为止。知道这些之后,我们来编写一个程序输入密码的过程。


代码示例:


#include <stdio.h>
int main()
{
  char password[20] = { 0 };
  printf("请输入密码:>");
  scanf("%s", password);
  printf("请确认密码(Y/N)");
  int ch = getchar();
  if (ch == 'Y')
    printf("确认成功\n");
  else
    printf("确认失败\n");
  return 0;
}


 我们随便输入一个字符串作为密码,看一下这段代码的输出结果。


输出结果:

49631a9957ff42999ea2363d2de1fcb1.png


我们可以看到,我们还要输入Y或者N,程序就直接输出确认失败了,为什么会这样呢?接下来,我就给大家解释一下。


scanf函数的原型:

d66282c4b6e4454fa2e7c5b9b56b3d40.png


 scanf函数是从第一个非空白字符开始读入的(scanf根本不读入空格当然是从第一个非空格读入),详细地说,当我们输入数据时,在按下回车键前输入的数据都储存在缓冲区,按下回车键后,会把数据及换行符一起传送到标准输入流中,scanf就是从标准输入流中读取数据,它会在其中查找,跳过空白符(空格 换行符 制表符)(scanf不能读取空白符的原因也是如此)。scanf读到空白符为止,除非格式化输入中要求输入空白符。

de17f6467d154f3faf0c449f1f2d4ee2.png


代码优化:


#include <stdio.h>
int main()
{
  char password[20] = { 0 };
  printf("请输入密码:>");
  scanf("%s", password);
  //清空输入缓存区,确保ch接收的字符为Y或者N
  while (getchar() != '\n')
  {
    ;
  }
  printf("请确认密码(Y/N):>");
  int ch = getchar();
  if (ch == 'Y')
    printf("确认成功\n");
  else
    printf("确认失败\n");
  return 0;
}


输出结果:

ea41d715cb8542d09c6f8ea428807a2d.png


 为了更加直观地看到scanf函数跳过空白符,博主编写了一段代码,见下图:

6e29c4b7f2ee4efb91876833537ea3ed.png


e43d19cece954dca94eaf0501a998771.png


 相信大家现在已经非常了解scanf函数了,那么接下来我们学习for循环。


二.for循环


 我们已经知道了while循环,但是我们为什么还要一个for循环呢?首先来看看for循环的语法:


1.for循环语法


1. for(表达式1; 表达式2; 表达式3)
2.   循环语句;


表达式1

表达式1为初始化部分,用于初始化循环变量的。

表达式2

表达式2为条件判断部分,用于判断循环时候终止。

表达式3

表达式3为调整部分,用于循环条件的调整。


 借助for循环编写在屏幕上打印数字1-10的程序:


#include <stdio.h>
int main()
{
  int i = 0;
  //for(i=1/*初始化*/; i<=10/*判断部分*/; i++/*调整部分*/)
  for (i = 1; i <= 10; i++)
  {
    printf("%d ", i);
  }
  return 0;
}


for循环的执行流程图:

7750bcfa903b45a79e6b700a69955ca2.png


 现在我们对比一下for循环和while循环。

int i = 0;
//实现相同的功能,使用while
i=1;//初始化部分
while(i<=10)//判断部分
{
   printf("hehe\n");
   i++;//调整部分
}
//实现相同的功能,使用while
for(i=1; i<=10; i++)
{
   printf("hehe\n");
}


 可以发现在while循环中依然存在循环的三个必须条件,但是由于风格的问题使得三个部分很可能偏离较远,这样查找修改就不够集中和方便。所以,for循环的风格更胜一筹;for循环使用的频率也最高。


 执行完循环语句会跳到for循环的for循环的调整部分,调整后再看是否满足循环判断条件。符合就进入循环,不符合就退出循环。


2.break和continue在for循环中


 我们发现在for循环中也可以出现break和continue,他们的意义和在while循环中是一样的,但是还是有些差异。


break介绍


//代码1
#include <stdio.h>
int main()
{
  int i = 0;
  for (i = 1; i <= 10; i++)
  {
    if (i == 5)
      break;
    printf("%d ", i);
  }
  return 0;
}

输出结果:


4c95c3d89b164cfea3c1cb021a7d5546.png


continue介绍


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


3d57d29badfc4253a54da5a04ba8a7f6.png


 这两个代码就自己分析一下,博主就不带着大家一起来分析了。


3.for语句的循环控制变量


建议:


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

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


int i = 0;
//前闭后开的写法
for(i=0; i<10; i++)
{}
//两边都是闭区间
for(i=0; i<=9; i++)
{}


 因为前闭后开区间的写法是有一些实际意义的,看循环的上界,我们就可以知道它的循环次数了。


4.一些for循环的变种


 for循环中的初始化部分,判断部分,调整部分都是可以省略的,但是不建议初学时省略,容易导致问题。现在我们看一下下面的代码示例。


代码示例1:


#include <stdio.h>
int main()
{
  for (;;)
  {
    printf("hehe\n");
  }
  return 0;
}


输出结果:


2733d064ad7741959078f5a8e2e3b58b.png


代码示例2:


#include <stdio.h>
int main()
{
  //代码2
  int i = 0;
  int j = 0;
  //这里打印多少个hehe?
  for (i = 0; i < 10; i++)
  {
    for (j = 0; j < 10; j++)
    {
      printf("hehe\n");
    }
  }
  return 0;
}


输出结果:


9637ec2b49b24a1eb7ea9b822ef5313b.png


代码示例3:


#include <stdio.h>
int main()
{
  //代码3
  int i = 0;
  int j = 0;
  //如果省略掉初始化部分,这里打印多少个hehe?
  for (; i < 10; i++)
  {
    for (; j < 10; j++)
    {
      printf("hehe\n");
    }
  }
  return 0;
}


输出结果:


0406e8cc98754ac48fd3d50c332652a6.png


代码示例4:


#include <stdio.h>
int main()
{
  //代码4-使用多于一个变量控制循环
  int x, y;
  for (x = 0, y = 0; x < 2 && y < 5; ++x, y++)
  {
    printf("hehe\n");
  }
  return 0;
}


输出结果:


11bf285061654a69b71361578e60dd0a.png


温馨提示:在初学的时候,要不for循环的三个部分都要写全,不要省略,省略的话有可能就会出问题。


5.一道笔试题


//请问循环要循环多少次?
#include <stdio.h>
int main()
{
  int i = 0;
  int k = 0;
  int count = 0;//count计算循环次数
  for (i = 0, k = 0; k = 0; i++, k++)
  {
    k++;
    count++;
    printf("%d\n", count);
  }
  return 0;
}


 我相信,很多人会说循环执行了一次。但其实,这个循环一次也没有执行。为什么呢?见下图代码分析:


代码分析:

8459717a037b4f359ca3ec9fb8e7d767.png


 这段代码就是为了告诉我们:一定要看清楚是一个等号还是两个等号!!!很多笔试题会在这个地方设坑,大家就不要着急往下跳啦。


三.do-while循环


1.do-while循环的语法


1. 
do
2.    循环语句;
3. while(表达式);


do-while循环的执行流程

323d66a242f8489fa582ec8fe549c59a.png


2.do-while循环的特点


 循环至少执行一次,使用的场景有限,所以不是经常使用。


代码示例:


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


3.do-while循环中的break和continue


break介绍

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


contine介绍


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


上面的两端代码,就不带着大家分析了,其实和前面的内容是一样的。


4.编程题


例:1!+2!+3!+……+10!


#include <stdio.h>
int main()
{
  int n = 0;
  int ret = 1;
  int sum = 0;
  //1+2+6 = 9
  //3!
  //4!=3!*4
  //n!=(n-1)!*n
  for (n = 1; n <= 10; n++)
  {
    ret = ret * n;
    sum = sum + ret;
  }
  printf("%d\n", sum);
  return 0;
}


例:利用二分查找找有序数组中具体的某个数字n


#include <stdio.h>
int main()
{
  int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
  int sz = sizeof(arr) / sizeof(arr[0]);//元素个数
  int i = 0;
  int left = 0;
  int right = sz - 1;
  int mid = 0;
  int k = 7;//要查找的数
  while (left <= right)
  {
    mid = left + (right - left) / 2;
    if (arr[mid] > k)
    {
      right = mid - 1;
    }
    else if (arr[mid] < k)
    {
      left = mid + 1;
    }
    else
    {
      printf("找到了,下标是%d\n", mid);
      break;
    }
  }
  if (left > right)
    printf("没找到\n");
  return 0;
}


/*
二分查找:
 在一个有序的序列中,找某个数据是否在该集合中,如果在打印该数据在集合中的下标,否则打印找不到
 具体找的方式:
  1. 找到数组的中间位置
  2. 检测中间位置的数据是否与要查找的数据key相等
    a: 相等,找到,打印下标,跳出循环
    b: key < arr[mid], 则key可能在arr[mid]的左半侧,继续到左半侧进行二分查找
    c: key > arr[mid], 则key可能在arr[mid]的右半侧,继续到右半侧进行二分查找
    如果找到返回下标,否则继续,直到区间中没有元素时,说明key不在集合中,打印找不到
 易错点:
 1. right的右半侧区间取值,该值决定了后序的写法
 2. while循环的条件是否有等号
 3. 求中间位置的方法,直接相加除2容易造成溢出
 4. 更改left和right的边界时,不确定是否要+1和-1
*/


例: 编写代码,演示多个字符从两端移动,向中间汇聚


#include <windows.h>
#include <stdio.h>
int main()
{
  char arr1[] = "welcome to SZTU!!!";
  char arr2[] = "##################";
  int left = 0;
  int right = strlen(arr1)-1;
  while (left<=right)
  {
    arr2[left] = arr1[left];
    arr2[right] = arr1[right];
    printf("%s\n", arr2);
    Sleep(1000);//window下Sleep函数参数的单位是毫秒
    system("cls");
    left++;
    right--;
  }
  printf("%s\n", arr2);
  return 0;
}


例:编写代码实现,模拟用户登录情景,并且只能登录三次。


#include <stdio.h>
#include <string.h>
int main()
{
  int i = 0;
  char password[20] = { 0 };
  for (i = 0; i < 3; i++)
  {
    printf("请输入密码:>");
    scanf("%s", password);
    //判断密码正确性
    if (strcmp(password, "bitbit") == 0)
    {
      printf("密码正确,登陆成功\n");
      break;
    }
    else
    {
      printf("密码错误\n");
    }
  }
  if (i == 3)
  {
    printf("三次密码错误,登录失败\n");
  }
  return 0;
}


5.猜数字游戏的实现


#include <stdlib.h>
#include <time.h>
#include <stdio.h>
void menu()
{
  printf("*********************************\n");
  printf("**********  1. play  ************\n");
  printf("**********  0. exit  ************\n");
  printf("*********************************\n\n");
}
//rand函数可以生成随机数
//返回一个0~RAND_MAX(32767)
void game()
{
  int guess = 0;
  //1. 生成随机数
  int ret = rand()%100+1;//0~99-->1~100
  //printf("%d\n", ret);
  //2. 猜数字
  while (1)
  {
    printf("请猜数字:>");
    scanf("%d", &guess);
    if (guess < ret)
    {
      printf("猜小了\n");
    }
    else if (guess > ret)
    {
      printf("猜大了\n");
    }
    else
    {
      printf("恭喜你,猜对了\n\n");
      break;
    }
  }
}
int main()
{
  int input = 0;
  //设置随机数的生成器
  //使用rand函数前,先使用srand函数
  srand((unsigned int)time(NULL));
  //时间戳
  do
  {
    menu();
    printf("请选择:>");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
      game();
      break;
    case 0:
      printf("退出游戏\n");
      break;
    default:
      printf("选择错误,重新选择!\n");
      break;
    }
  } while (input);
  return 0;
}


goto语句


C语言中提供了可以随意滥用的 goto语句和标记跳转的标号。从理论上 goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。例如:一次跳出两层或多层循环。多层循环这种情况使用break是达不到目的的。它只能从最内层循环退出到上一层的循环。


goto语言真正适合的场景如下:


for(...)
  for(...)
 {
    for(...)
   {
      if(disaster)
        goto error;
   }
 }
error:
if(disaster)
    // 处理错误情况


下面是使用goto语句的一个例子,然后使用循环的实现方式替换goto语句:


关机程序


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
  char input[10] = { 0 };
  system("shutdown -s -t 60");
    again:
  printf("电脑将在1分钟内关机,如果输入:我是猪,就取消关机!\n请输入:>");
  scanf("%s", input);
    if (0 == strcmp(input, "我是猪"))
    {
      system("shutdown -a");
    }
    else
    {
      goto again;
    }
  return 0;
}


 而如果不适用goto语句,则可以使用循环:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
  char input[10] = {0};
  system("shutdown -s -t 60");
  while(1)
 {
    printf("电脑将在1分钟内关机,如果输入:我是猪,就取消关机!\n请输入:>");
    scanf("%s", input);
    if(0 == strcmp(input, "我是猪"))
   {
      system("shutdown -a");
      break;
   }
 }
  return 0;
}


 以上就是本篇博客的全部内容了,如果大家觉得有收获的话,可以点个赞支持一下!

相关文章
|
6月前
|
Go C语言
分支语句与循环语句,详细讲解
分支语句与循环语句,详细讲解
|
7月前
|
C语言
分支和循环语句
分支和循环语句
38 1
|
6月前
|
C语言
分支和循环语句(3)
分支和循环语句(3)
35 0
分支和循环语句(3)
|
6月前
|
C语言
分支和循环语句(1)
分支和循环语句(1)
45 0
|
7月前
|
存储 缓存 Linux
分支与循环语句1
分支与循环语句1
43 0
|
7月前
|
缓存 编译器 Go
分支语句和循环语句
分支语句和循环语句
71 0
|
编译器 C语言 C++
分支语句和循环语句上
分支语句和循环语句
59 0
分支语句和循环语句上
|
数据安全/隐私保护 C语言
分支语句与循环语句(2)
分支语句与循环语句(2)
60 0
|
C语言
分支语句和循环语句(1)
分支语句和循环语句(1)
51 0
|
算法 数据安全/隐私保护
分支语句与循环语句——练习
分支语句与循环语句——练习
51 0