分支、循环语句小练1

 好的,简单介绍完C语言分支、循环知识点以后,让我们来编写代码,动手实践一下。这里我粗略列举一些与分支、循环有关的题目,大家可以跟着一起做一做。(功能的实现不只有一种方法,代码可能有多种写法,大家可以根据自己的想法来。)

目录

Test1:选择题

1.1

1.2 

1.3

1.4

Test2:编程题

判断两个数的大小关系

判断整数的奇偶性

计算n的阶乘

计算1!+2!+3!+...+n!

输入一个班级5个学生各5科成绩,输出5个学生各5科成绩及总分。

打印线段图案

给定秒数 seconds ,把秒转化成小时、分钟和秒

单位阶跃函数

 写一个代码打印1 - 100之间所有3的倍数的数字

 写一个代码:打印100~200之间的素数

打印1000年到2000年之间的闰年

 给定两个数,求这两个数的最大公约数


Test1:选择题

1.1

#include <stdio.h>
int sum(int a)
{
    int c = 0;
    static int b = 3;
    c += 1;
    b += 2;
    return (a + b + c);
}
int main()
{
    int i;
    int a = 2;
    for (i = 0; i < 5; i++) 
    { 
        printf("%d,", sum(a)); 
    } 
} 

A. 6,8,10,12,14

B.8,10,12,14,16

C.10,12,14,16,18

D.12,14,16,18,20

正确答案:B

解析:关键字static,static可以修饰局部变量、static可以修全局变量、static可以修饰函数。(个人理解是保存上一次的值,不被初始化。)例如:此程序sum(a)自定义函数,传参数a=2,执行for循环,i=0时,a=2,c+1=1,b+=2使得b=5,return(a+b+c)=return(2+5+1),函数返回类型为整型,返回8;当i=1时,a=2,c初始化为0,c+1=1,由于上次循环b=5,所以b+=2使得b=7,return(a+b+c)=return(2+7+1),返回10;当i=2时,a=2,c初始化为0,c+1=1,由于上次循环b=7,所以b+=2使得b=9,return(a+b+c)=return(2+9+1),返回12;当i=3时,a=2,c初始化为0,c+1=1,由于上次循环b=9,所以b+=2使得b=11,return(a+b+c)=return(2+11+1),返回14;当i=4时,a=2,c初始化为0,c+1=1,由于上次循环b=11,所以b+=2使得b=13,return(a+b+c)=return(2+13+1),返回16;当i=5时,i不小于5,不满足循环判断条件,结束循环,所以最后打印8,10,12,14,16。

1.2 

下列代码执行结果为:

#include <stdio.h>

int main()
{
	int i = 0;
	for (i = 0; i<10; i++)
	{
		if (i = 5)
			printf("%d ", i);
	}
	return 0;
}

A.1 2 3 4 5 6 7 8 9 10

B.5 5 5 5 5 5 5 5 5 5

C.死循环的打印5

D.0 1 2 3 4 5 6 7 8 9

正确答案是C

解析:当A初始化等于0,进入循环,注意这里的if(i=5),==是表示判断,=是赋值,所以当i进入循环后,被赋值等于5,打印5;i++,i=6,进入循环,又被赋值为5,打印5......所以这个程序会一直循环打印5。(这里也告诉我们,尽量不要在for循环体内部改变变量的值,变量容易失控。)

1.3

int func(int a)
{
    int b;
    switch (a)
    {
        case 1: b = 30;
        case 2: b = 20;
        case 3: b = 16;
        default: b = 0;
    }
    return b;
}

则func(1) = (      )

A.30

B.20

C.16

D.0

正确答案:D

解析:func(1),当a等于1时,switch分支由case1进入,b等于30,没有break(结束标志),所以程序一直执行,直到出现break或者程序结束,所以func(1)=0。

1.4

switch(c)语句中,c不可以是什么类型( )

A.int

B.long

C.char

D.float

正确答案:D

 原因:字符型存储的是ASCII码值,所以返回的也是一个整型,本质上还是整型变量,因此也可以执行。但是浮点数(单精度float、双精度double...)不是整型,因此不能执行。

Test2:编程题

判断两个数的大小关系

题目有多组输入数据,每一行输入两个整数,用空格分隔。针对每行输入,输出两个整数及其大小关系,数字和关系运算符之间没有空格。

示例
输入输出
1 11=1
1 01>0
1 21<2

solution:

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

int main()
{
    int a = 0;
    int b = 0;
    while (scanf("%d %d", &a, &b) == 2)
    {
        if (a > b)
            printf("%d>%d\n", a, b);
        else if (a < b)
            printf("%d<%d\n", a, b);
        else
            printf("%d=%d\n", a, b);
    }
    return 0;
}

解析:scanf是格式化输入函数,属于C语言的库函数。(库函数—在后面的总结中会为大家讲解。Don't worry.)它的的本质是读到数据,返回数据的个数,例如这里的比较两数大小,这里读到两个数,它就会返回2。假如我这里不输入整数,输入字符类型的变量会怎么样呢?

 当我输入两个整型,后面即使有多余的数字或者是字符,它也只会读取前两个整数,返回前两个整数。如果未读到两个整数,那么while(scanf("%d %d",&a,&b)==2)不满足条件,循环结束。

特别注意(小编以前错过):当要读取一个变量时,scanf可以写在循环外。但是当要循环读取多个变量时,scanf不能写在外面。并且有的朋友为了追求代码的美观,会想要在scanf里面加\n(换行操作符,操作符后面也会为大家讲解。Don't worry.),那么这里就会出现问题,代码不会运行起来。

例如:

所以,当循环读取多组变量时,不能在循环前加scanf,相当于这里与while有冲突。在 C 语言中,scanf 函数是用于从标准输入流(stdin)中读取数据的函数,它的使用方式类似于 printf 函数。与 printf 函数不同的是,scanf 函数在读取数据时会忽略输入缓冲区(input buffer)中的空格、换行符等空白字符。因此,在 scanf 函数的参数字符串中添加回车符('\n')是没有意义的,也不会对程序的执行产生任何影响。实际上,当我们在 scanf 函数的参数字符串中添加回车符时,只会使程序多读取一个字符,并将其保留在输入缓冲区中,同时可能会导致后面的输入操作出现问题。这是因为,当输入缓冲区中有多余的字符时,下一次调用 scanf 函数时可能会读取到之前被忽略的字符,导致程序输出不正确的结果。所以scanf里面也不能加\n。

判断整数的奇偶性

KiKi想知道一个整数的奇偶性,请帮他判断。多组输入,每行输入包括一个整数。针对每行输入,输出该数是奇数(Odd)还是偶数(Even)。

输入输出
4Even
7

Odd

solution:

int main()
{
    int a = 0;
    while (scanf("%d", &a) != EOF)
    {
        if (a % 2 == 0)
            printf("Even\n");
        else
            printf("Odd\n");
    }
    return 0;
}

EOF全称End of File,是C语言标准库函数中表示文件结束符,通常在文本的最后表示资料结束。C语言中数据都是以字符ASCII代码值来存放的。ASCII代码值的范围是0~127,EOF作为文件结束标志,我们可以把它理解为“-1”。这里的!=EOF相当于==1。

 while (scanf("%d", &a) != EOF)
//while(scanf("%d",&a)==1)

计算n的阶乘

//计算n的阶乘
int main()
{
	int n = 0;
	scanf("%d", &n);
	int i = 0;
	int ret = 1;//ret=1,1乘以任何数没有影响
	for (i = 1; i <= n; i++)
	{
		ret=ret*i;
	}
	printf("%d\n",ret);
	return 0;
}

计算1!+2!+3!+...+n!

//计算1!+2!+3!+...+n!
int main()
{
	int n = 0;
	scanf("%d", &n);
	int i = 0;
	int sum = 0;
	int ret = 1;//ret=1,1乘以任何数没有影响
	for (i = 1; i <= n; i++)
	{
		ret = ret * i;
		sum = sum + ret;
	}
	printf("%d\n", sum);
	return 0;
}

这里是一层循环,利用上一次的阶乘ret算出下一个数的阶乘,然后求sum。 

输入一个班级5个学生各5科成绩,输出5个学生各5科成绩及总分。

五行,每行输入一个学生各5科成绩(浮点数表示,范围0.0~100.0),用空格分隔

输入:

98.5 96.0 100 99 88
60.5 77 88.5 99 60
80 80.5 89 91 92
93 94 95.5 96 97.5
100 98 88.5 88 78.5

输出:

98.5 96.0 100.0 99.0 88.0 481.5
60.5 77.0 88.5 99.0 60.0 385.0
80.0 80.5 89.0 91.0 92.0 432.5
93.0 94.0 95.5 96.0 97.5 476.0
100.0 98.0 88.5 88.0 78.5 453.0
//输出一个班、五个人的成绩及总分
int main()
{
	double score[5] = { 0.0 }; //float score[5]={0.0}也可
	int i = 0;//5个人
	//double sum = 0.0;//定义在这里逻辑有问题
	//如果定义在i的循环里面,当计算出一个学生的5门成绩以后,就是总成绩,当计算下一个学生成绩时,sum初始化又变为0.0
	//如果定义在外面,那么下一次计算学生成绩时,sum初始化就是上一个学生的总成绩
	while (i < 5)
	{
		double sum = 0.0;
		int j = 0;//每个人的五门成绩
		//输入
		while (j < 5)
		{
			scanf("%lf", &score[j]);
			sum += score[j];
			j++;
		}
		j = 0;//输出时,重新初始化为0,否则从5开始
		//输出
		while(j<5)
		{ 
			printf("%.1lf ", score[j]);
			j++;
		}
		printf("%.1lf ", sum);
		i++;
	}
	return 0;
}

打印线段图案

针对每行输入,输出占一行,用“*”组成的对应长度的线段。多组输入,一个整数(1~100),表示线段长度,即“*”的数量。

输入输出
7*******
2**
//打印线段图案
int main()
{
	int i = 0;
	while (scanf("%d", &i) == 1)
	{
		if (i >= 1 && i <= 100)
		{
			int n = 0;
			for (n = 1; n <= i; n++)
			{
				printf("*");
			}
			printf("\n");
		}
	}
	return 0;
}

给定秒数 seconds ,把秒转化成小时、分钟和秒

一行,包含三个整数,依次为输入整数对应的小时数、分钟数和秒数(可能为零),中间用一个空格隔开

输入输出
36611 1 1
//时间转换
int main()
{
	int times = 0;
	int h, m, s;
	scanf("%d", &times);
	h = times /3600;
	m = (times-h*3600) /60;
	s = times - h * 3600 - m * 60;
	printf("%d %d %d\n", h, m, s);
	return 0;
}

单位阶跃函数

卡卡最近学习了信号与系统课程,这门课里有一个非常有趣的函数,单位阶跃函数,其中一种定义方式为:

现在试求单位冲激函数在时域t上的值。题目有多组输入数据,每一行输入一个t。

//单位跃进函数
int main()
{
    int t = 0;
    while (scanf("%d", &t) == 1)
    {
        if (t > 0)
            printf("1\n");
        else if (t == 0)
            printf("0.5\n");
        else
            printf("0\n");
    }
    return 0;
}

 写一个代码打印1 - 100之间所有3的倍数的数字

int main()
{
	int i = 1;
	for (i = 1; i < 101; i++)
	{
		if (i % 3 == 0)
			printf("%d ", i);
	}
	return 0;
}

解决问题的办法是多样的,这里的代码也可以写别的方式。例如: 

int main()
{
	int i = 1;
	for (i = 1; i < 99; i++)//这里i<99,因为当99+2=101>100
	{
		i += 2;
		printf("%d ", i);
	}
	return 0;
}

这里我们已经知道i=1时,i+2=3是3的倍数,打印3,i++,i=4,4+2=6是3的倍数,所以直接执行加运算可以提升速度。i%3要从1执行到100,执行100次,而这里直接加2,直接干掉两个数,执行速度得到提升,后面也会为大家总结数据结构与算法分析。

 写一个代码:打印100~200之间的素数

//写一个代码:打印100~200之间的素数
int main()
{
	int i = 0;
	//int flag = 1;//为什么不能定义在这里?
	//如果定义在i的循环里面,当判断完一个i%j以后,如果不是素数,flag等于0,那么之后再判断一个i模j,flag的初始化依然是1,
	//但是定义在i循环外面,flag的值就变为0
	for (i = 100; i <= 200; i++)
	{
		int j = 0;
		int flag = 1;//标记-用来记录一个数是否是素数  flag=1是素数
		for (j = 2; j <=i-1; j++)
		{
			if (i % j == 0)//不是素数  比如这里判断100是不是素数,就应该是100除以2~99的数
			{
				flag = 0;//flag=0代表不是素数
				break;
			}
		//	else printf("%d ",i)   这里不能加else
		//加上else,意思变为如果一个数,比如9除以2,不等于0,那么它就是素数,这里9还没有除以3以及后面的数
		//并且我们知道9/3=0,9不是素数。
		}
		//break跳出一层循环,这里指跳出j的循环,来到这里
		if (1 == flag)
		{
			printf("%d ", i);
		}
	}
	return 0;
}

另一种节省时间的方法是:

#include<math.h>
int main()
{
	int i = 0;
	for (i = 100; i <=200; i++)
	{
		int j = 0;
		int flag = 1;
		for (j = 2; j <= sqrt(i); j++)//sqrt()开平方函数,包含在math.h这个头文件里,所以要include<math.h>这个头文件
			/*这是一种数学方法求素数,意思是判断一个数是不是素数时,如果在2到这个数的开平方之间找不到一个能整除的数,
			那么在这个数的开平方到这个数的前一位n-1之间也找不到一个数能被n整除。
			如果能在2~sqrt(n)之间找到一个数能被n整除,那么sqrt(n)~n-1之间也能找到一个数被n整除。
			*/
		{
			if (i % j == 0)
			{
				flag = 0;
				break;
			}
		}
		if (1 == flag)
			printf("%d ", i);
	}
	return 0;
}

 这两种方法都是试除法,属于数学方法,感兴趣的可以在网上看一篇文章-《素数求解的N种境界》。

打印1000年到2000年之间的闰年

//打印1000年到2000年之间的闰年
//闰年的两种判断方法(两种方法都可以)
//1.能整除4,不能整除100
//2.能整除400
int main()
{
	int year = 0;
	for (year = 1000; year <= 2000; year++)
	{
		if ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0))
         //逻辑操作符&&(逻辑与)、||(逻辑或)
		{
			printf("%d ", year);
		}
	}
	return 0;
}

 给定两个数,求这两个数的最大公约数

//求两数的最大公约数
int main()
{
	int m = 0;
	int n = 0;
	//输入
	scanf("%d %d", &m, &n);
	int k = (m<n?m:n);//最大公约数肯定最大只能是两数中最小的一个
	//因为我不知道求两数的最大公约数要除以多少次,所以我让循环条件一直为真,如果是最大公约数就跳出循环
	while (1)
	{
		if ((m % k == 0) && (n % k == 0))
		{
			break;//求出最大公约数,跳出循环
		}
		k--;
	}
	printf("%d", k);
	return 0;
}

另一种求最大公约数的方法:

思想是:

//辗转相除法
int main()
{
	int m = 0;
	int n = 0;
	int k = 0;
	while (k = m % n)
	{
		m = n;//把n的值赋给m
		n = k;//把k的值赋给n
	}
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值