抽丝剥茧C语言(中阶)分支与循环练习

简介: 抽丝剥茧C语言(中阶)分支与循环练习

导语

这一篇主要讲解一下关于分支与循环的一些练习,好记性不如烂笔头,虽然我们不用笔,但是我们需要自己动手写代码,你记性再好都不如自己动手写一下代码,多写代码你才能成为大牛!

判断一个数是否为奇数

这道题我们的思路是什么?

首先先让代码灵活起来,肯定不能是你去创建一个变量然后去反复修改,这时候当然要利用好我们的scanf这个函数,我们输入任何值都可以判断了。

然后就是我们如果去分辨是否为奇数,这就需要用到我们的分支语句了。

参考代码如下:

#include <stdio.h>
int main()
{
  int a = 0;
  scanf("%d", &a);//你要输入任意值的地方
  if (a % 2 == 1)//这里为判断,代码核心的地方,奇数除2余数为1,偶数能整除2
  {
    printf("YES");//这里是结果1
  }
  else
  {
    printf("NO");//这里是结果2.如果第一个结果不成立就会执行这个代码
  }
  return 0;
}

各位老铁可以复制到自己的编译器测试一下,我试过了,没问题。

输出1-100之间的奇数

上一道题,已经知道如何判断奇数了,这道题也很简单,首先思路是生成1到100的数字,然后每一个数字进行判断,是就打印,不是就不打印。

参考代码如下:

#include <stdio.h>
int main()
{
  int i = 0;
  for (i = 1; i <= 100; i++)//生成1到100数字
  {
    if (i % 2 == 1)//判断是否为奇数
    {
      printf("%d ", i);//打印奇数
    }
  }
  return 0;
}

这段代码输出是:

代码没问题。

我们学习了for循环,那么就要巧妙利用for循环,我们不可能定义100个变量然后赋值1到100,所以就用循环去生成。

虽然我们的变量 i 初始化为0,不符合我们从1开始,但是for循环可以赋值 i ,也就是说,i 被赋值等于1,先判断 i 是否<=100,成立就进入循环,然后到i++的部分进行调整,也就等于i+1,这时变量i 就变成了2。

如上循环,等i=101时就会跳出循环,所以就生成了1到100之间的数。

判断我们只需要一个if就可以了,因为只是让我们打印奇数,不是让你判断是不是奇数,所以没用else。

盲盒!

给家人们康一个好康的~

#include <stdio.h>
int main()
{
    int n = 1;
    int m = 2;
    switch (n)
   {
    case 1:
            m++;
    case 2:
            n++;
    case 3:
            switch (n)
           {//switch允许嵌套使用
             case 1:
                    n++;
             case 2:
                    m++;
                    n++;
                    break;
           }
    case 4:
            m++;
            break;
    default:
            break;
   }
    printf("m = %d, n = %d\n", m, n);
    return 0; 
}

猜一猜结果是神魔~

我们来慢慢看,代码是从上往下运行的,我们知道这里有两个变量,n=1,m=2,进入switch语句之后,判断条件是n等于1,为真,进入之后进入对应的case 1的这个语句,然后从上往下运行,直到case 3然后判断第二个switch语句,因为经过上面的计算,n=2,m=3,所以进入第二个switch语句中的case 2,,计算完之后break跳出第二个switch语句,到第一个switch语句的case 4进行计算,计算完之后跳出第一个switch语句。

输出结果为:

m=5 n=3

一道笔试题

没错,这是一道去公司应聘,笔试部分的真题。让我们一起看一看

请问循环要循环多少次?

#include <stdio.h>
int main()
{
 int i = 0;
 int k = 0;
 for(i =0,k=0; k=0; i++,k++)
        k++;
 return 0; 
}

这里家人们的答案应该五花八门,但是注意,我们看这个for循环的判断条件部分,它是把k赋值成了0,也就是说判断条件部分等于放了一个0进去,这说明条件为假,他和 == 不一样, == 是判断两端是否相等,就算是k == 0也没问题,因为条件是k == 0,这个条件成立就会进入循环,而这道题是赋值,别看少了一个等号,可是缺天差地别!

经过上面的分析我们就知道正确答案了,循环0次。

计算 n的阶乘

数学里的阶乘是1*2*3*…*n。

C语言里我们又应该如何实现呢?

我们首先分析一下,无论你算谁的阶乘,开头都是1*多少多少,然后在观察一下其他规律,2的阶乘是1*2,3的阶乘是1*2*3,4的阶乘是1*2*3*4。

我们可不可以用这个思路,算3的阶乘时,就要用2的阶乘 * 和3的本身,4的阶乘就要用3的阶乘和 *4 的本身。

我们可以利用C语言变量可以存储的特性把你要算n阶乘前面n-1的阶乘存储进去。例如:

#include <stdio.h>
int main()
{
  int n;
  int i = 0;
  int ret = 1;
  scanf("%d", &n);//这里是我们要计算某个数的阶乘
  for (i = 1; i <= n; i++)//i变成了1,是因为都要从1开始乘起,循环次数是根据你想算n的阶乘中的n为界限
  {
    ret = ret * i;//ret是储存n-1的阶乘
  }
  printf("%d", ret);//打印的就是n的阶乘
  return 0;
}

我们输入4,结果是24。

我们声明了一个变量n,然后利用scanf函数改变n的值。这里n为3,第一次进入for循环,ret=1*1,然后再次进入for循环,上次因为i算的是1的阶乘,所以ret等于1,这次要算2的阶乘,也就等于1的阶乘乘以2等于2,ret就等于2,第三次进入循环,用ret也就是2的阶乘乘以3算出来3的阶乘,最后一次循环算出来4的阶乘了。

计算 1!+2!+3!+……+10!

上一道题算的是n 的阶乘,我们也明白了阶乘用改如何计算啊,如何存储到变量里面,这道题就利用上面的原理,然后把这写常量的阶乘给加起来,然后储存到一个变量里。

首先我们不可能将1到10用变量一一生成出来。

#include <stdio.h>
int main()
{
  int i = 0;//储存1到10的变量
  int j = 0;//储存要求n的阶乘变量
  int ret = 1;//依然是储存n的阶乘
  int sum = 0;//储存1到10的阶乘相加的变量
  for (i = 1; i <= 10; i++)
  {
    ret = 1;//重新给变量ret赋值为1
    for (j = 1; j <= i; j++)
    {
      ret = ret * j;//1到j阶乘的数
    }
    sum = sum + ret;//1到i阶乘的和
  }
  printf("%d", ret);//打印的是1到10的阶乘的和
  return 0;
}

我们这里的结果是

3628800

这里需要注意的是什么?ret在每一次第一层for循环进入的时候重新给ret赋值为1,这是为什么?因为ret在第二层循环算的是1到变量 j 的阶乘,但是,出来之后,ret并不是1,也就是说再次进入时候,ret是上次 j 的阶乘,我们从新进入第二层for循环的时候ret不是1,也就是说算的已经不是 j 的阶乘了。

在一个有序数组中查找具体的某个数字n。

我们这里要求在一个有序的数组里找一个数字,利用C语言的方法最普遍的方法就是从后往前直找或者是从后往前找,那么,如果有100个数呢,1000个数呢,10000个数呢,你需要找多久呢?

在现实生活中,比如我买了一双鞋,你好奇问我多少钱,我说不超过300元。你还是好奇,你想知道到底多少,我就让你猜,你会怎么猜?

当然是每次从猜中间数。

我们怎么利用C语言来实现这个算法呢?

首先我们创建一个数组,在里面找一个数怎么表达?当然是数组的下标,然后通过下标实现这种算法,叫做折半查找法。

例如:

#include <stdio.h>
int main()
{
 int arr[] = {1,2,3,4,5,6,7,8,9,10};//创建数组
 int left = 0;//数组最左边的下标
 int right = sizeof(arr)/sizeof(arr[0])-1;//数组最右边的下标,减一前面算的是数组的大小,原理是数组的长度除以数组里面第一个元素的长度
 int key = 7;//要查找的数
 int mid = 0;//两个数组下标和的平均数,也是二分查找的核心
 while(left<=right)//判断条件是因为左下标和右下标如果跑到了相反的方向,就说明数组中没有这个数
 {
 mid = (left+right)/2;//这是查找的中间数
 if(arr[mid]>key)//重新定义要查找的范围
 {
 right = mid-1;
 }
 else if(arr[mid] < key)//重新定义要查找的范围
 {
 left = mid+1;
 }
 else
 break;//这个地方代表是找到了
 }
 if(left <= right)
 printf("找到了,下标是%d\n", mid);//打印要查找数的下标
 else
 printf("找不到\n");
}

因为查找是一个重复动作,所以利用while循环。

这个代码看起来有些抽象,我画个图给大家看看!

这里,红色是数组的下标,然后紫色的是最左边的下标,褐色的是最右边的下标,蓝色的变量left和变量right相加和的一半的下标变量mid,这个变量也是用于锁定你要查找数的量,如果mid等于你要找的数的下标,说明找到了。

我们要找的是7这个数字,下标是6,第一次mid为4,它对应的是数组里面的5,5小于7所以我们查找的范围就变成了下标5到下标9之间,因为i虽然mid等于4,可是我们排查mid下标对应的数小于要查找的数,所以说mid对应下标的数一定不是要查找的范围,所以需要加一。

然后就变成了这个样子。这次我们找到了下标为7的元素,发现大于要查找的元素,所以范围缩小到了:

这里要强调一下,因为分为浮点数和整数,储存方式也不一样,下标是整形,两个数的和除以2的结果会把小数点后面的几位给丢掉,也就是(5+6)/2=5。

这次是小了,继续再找:

这次终于找到了,下标为6。

打印结果是:

找到了,下标是6

这次大家也可以明白为什么是这样一个查找范围,如果left到了right的右边,数组里面没有我们要查找的数。

这就是二分查找法C语言的实现。

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

#include <windows.h>
#include <stdio.h>
int main()
{
  char arr1[] = "Welcome to League of Legends!";//要一点一点改变的内容
  char arr2[] = "#############################";//被改变的数组
  int left = 0;//最左边下标
  int right = strlen(arr1) - 1;//最右边下标
  printf("%s\n", arr2);
  //while循环实现
  while (left <= right)
  {
    Sleep(1000);//这个函数是等1000毫秒=1秒之后进行下面代码的运行
    arr2[left] = arr1[left];//这里实现arr1数组内容的转换
    arr2[right] = arr1[right];
    left++;
    right--;
    printf("%s\n", arr2);
  }
  return 0;
}

代码的运行(视频不太好使,只能传图片了)

这段代码主要是进行数组元素的改变,因为要将一点一点向中间汇聚,所以就从两端开始一元素一个元素的改变。

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

要求:只允许输入三次密码,如果密码正确则提示登录成,如果三次均输入错误,则退出程序。

当然我们经常用的登陆更加高级,这个只是模拟实现而已。

原理也就是通过循环制造三次条件,然后用if语句判断对错:

int main()
{
    char psw[10] = "" ;//这是储存你要输入字符串的空间。最多可以输入9个字节的字符串,因为还最后还有一个 \0 放在末尾
    int i = 0;
    int j = 0;
    for (i = 0; i < 3 ; ++i)//代表三次机会
   {
        printf( "please input:");
        scanf("%s", psw);//输入密码
        if (strcmp(psw, "password" ) == 0)//判断是否正确
            break;
   }
    if (i == 3)
        printf("exit\n");//代表三次机会都输入错误
    else
        printf( "log in\n");//代表输入成功
}

strcmp是个什么函数呢?是判断字符串是否相同,相同返回0,所以需要判断是否等于0。这里是判断是否等于0,并不是赋值给strcmp为0,大家不要搞混了。至于为什么不把两个字符串直接用 == 比较,这里后面会讲。

猜数字游戏

大家应该熟悉了我们上面的折半查找法,我们可以利用这个算法来玩个游戏。

我们来猜1到100数字的如何?

首先,我们要做一个游戏菜单,把它放在自定义函数里面,代码如下:

void menu()//函数名为menu,因为只需要调用一下这个函数打印游戏菜单,所以返回类型是void,不需要返回任何值,因为在menu函数就已经完成所有需要的内容了。
{
  printf("**********************\n");
  printf("*****1.猜数字游戏*****\n");
  printf("*****0.游戏结束  *****\n");
  printf("**********************\n");
}

游戏菜单出来了,那么,我们要做到玩完一次还想继续玩,那么应该怎么办?玩完某一次之后想退出怎么办?

我们可以利用学习过的语句来进行这个逻辑,我的方法只是其一。

#include <stdio.h>
void menu()//游戏菜单
{
  printf("**********************\n");
  printf("*****1.猜数字游戏*****\n");
  printf("*****0.游戏结束  *****\n");
  printf("**********************\n");
}
void game()//游戏要实现的内容,暂时没写
{
}
int main()
{
  int a = 0;
  while (1)//循环无数次
  {
    menu();//调用游戏菜单
    scanf("%d", &a);
    if (a == 0)
    {
      printf("退出游戏");
      break;
    }
    else if (a == 1)
    {
      printf("游戏开始\n");
      game();//调用game函数
    }
    else
    {
      printf("输入无效,请重新输入\n");
    }
  }
  return 0;
}

输出结果三种分别是:

这就完成了我们的上一个逻辑,我们最好是写完一个逻辑的代码就运行一次试一试,因为你很可能就会写出来BUG,如果现在不测试一下你的这一段代码,那么你就会越写越多。

我们要完成一个也是最复杂的逻辑,生成随机数

我来介绍一些函数:

rand

这个是用于生成随机数的函数,将返回值储存进变量ret中,但是值是固定的,虽然每个数都很随机,范围是0~32767。但是我们运行发现

每一次开始游戏,我们需要猜的值都是固定一样的,所以仅仅这一个函数是不够用的。

srand

这个函数是设置随机数起点的,这个函数需要你传进去不同的值生成随机数。

假如说我们先这么写:

srand(10);

int ret =rand();

printf(“%d”,ret);

输出:71

srand(100);

int ret =rand();

printf(“%d”,ret);

输出:365

也就是说我们在srand(随机整形数字)就可以生成一个随机数,但这是固定的,也就是说我们这里需要能变化的数字,我们电脑里面什么是可以变化的呢?答案:时间。

time

我们有一个东西叫做时间戳.

这里是时间戳转换的工具,有兴趣可以研究一下时间戳转换工具.

时间戳这个东西就像我们在某个时间段给盖章一样,每一串数字都代表着一个时间。

在C语言我们就有这个东西,他的格式是这样的

time(传进去一个指针)返回的值是unsigned int类型

也就是说我们可以这么写:

srand((unsigned int)time(NULL));

int ret = rand();

printf(“%d\n”, ret);

但是我们又发现一个问题:

我们每一次的随机值都很接近对吗,原因是我们设置随机数起点一直在重复,如果按快了都可能数值重复,起点的数是根据时间戳,过了几秒就重新定制起点,肯定数值差不多。

这里我们放在不循环的地方,选择一开始设置起点就好,一次就行,不用重复设置:

void game()
{
  int ret = rand();
  printf("%d\n", ret);//打印猜测的数检测是否有问题
}
int main()
{
  int a = 0;
  srand((unsigned int)time(NULL));//我们把随机数的起点设置到了这里
  while (1)
  {
    menu();
    scanf("%d", &a);
    if (a == 0)
    {
      printf("退出游戏");
      break;
    }
    else if (a == 1)
    {
      printf("游戏开始\n");
      game();
    }
    else
    {
      printf("输入无效,请重新输入\n");
    }
  }
  return 0;
}

这样就结果正常了:

因为time函数太过于复杂,这里就不进行具体了解了。

最后一步,我们只需要进行玩家猜测的逻辑部分就写好了。

#include <stdio.h>
#include <time.h>//时间戳的头文件
#include <stdlib.h>//随机数的头文件
void menu()
{
  printf("**********************\n");
  printf("*****1.猜数字游戏*****\n");
  printf("*****0.游戏结束  *****\n");
  printf("**********************\n");
}
void game()
{
  int b;
  int ret = rand()%100+1;//因为我们要猜测的是1到100之间的数,任何数模100都是0到99,加一就是1到100
  while (1)//猜数字不可能只是一次,所以循环
  {
    printf("请输入你要猜测的数值:\n");
    scanf("%d", &b);
    if (b < ret)
    {
      printf("猜小了\n");
    }
    else if (b > ret)
    {
      printf("猜大了\n");
    }
    else
    {
      printf("猜对了\n");
      break;
    }
  }
}
int main()
{
  int a = 0;
  srand((unsigned int)time(NULL));
  while (1)
  {
    menu();
    scanf("%d", &a);
    if (a == 0)
    {
      printf("退出游戏");
      break;
    }
    else if (a == 1)
    {
      printf("游戏开始\n");
      game();
    }
    else
    {
      printf("输入无效,请重新输入\n");
    }
  }
  return 0;
}

这里我们开始一局试一下:

没啥问题。

本篇完

我的参考代码不一定是非常好的,但是绝对没什么大问题!家人们放心看就好了,主要是一起学习怎么分析任务,任务目的是什么,先想想用正常思维怎么解决这个任务,然后再用C语言的语法和特点来去完成思维代码。

分支与循环的练习题到此完结,相信大家对分支与循环有了一个更加深刻的理解,和学会如何应用。那么请路过的关注一波,顺便点点赞,如果哪里有错误请大佬指点,谢谢!

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