c语言习题---(循环语句)

这里写目录标题

  • 前言
  • 题目目录
    • 非编程题
    • 编程题
  • 第一题解析
  • 第二题解析
  • 第三题解析
  • 第一题解析
  • 第二题解析
  • 第三题解析
  • 第四题详解
  • 第五题解析
  • 第六题解析
  • 第七题解析
  • 第八题解析
  • 第九题解析
  • 第十题解析

前言

从这一章开始我们的题就多起来了,因为前面的分支语句,啊不管怎么出类型就那样,但是我们的循环语句就复杂一些,我们就多来点题目好吧废话不多说先看题。

题目目录

非编程题

第一题:

#include
int main()
{
	int n = 0;
	while (n++ <= 2);
	printf("%d\n", n);
	return 0;
}

第二题:

#include
int main()
{
	int x = 0;
	int y = 0;
	for (y = 1; y < 10;)
	{
		y = ((x = 3 * y, x + 1), x - 1);
		printf("x=%d,y=%d", x, y);
	}

	return 0;
}

第三题:

#include
int main()
{
	int n = 2;
	int k = 0;
	while (k++ && n++ > 2);
	{
		printf("%d %d\n", k, n);
	}	
	return 0;
}

编程题

第1题:
c语言习题---(循环语句)_第1张图片
第2题:
c语言习题---(循环语句)_第2张图片
第3题:
请添加图片描述
第4题:
请添加图片描述
第5题:
请添加图片描述
第6题:请添加图片描述
第7题:
c语言习题---(循环语句)_第3张图片
第8题:

c语言习题---(循环语句)_第4张图片
第9题:
c语言习题---(循环语句)_第5张图片
第十题:
c语言习题---(循环语句)_第6张图片

第一题解析

#include
int main()
{
	int n = 0;
	while (n++ <= 2);
	printf("%d\n", n);
	return 0;
}

我们来这段代码,我们这道题的目的就是提醒大家n++的区别,首先可以看到我们一开始将n初始化为0,然后我们就进入了while循环的判断部分,我们来看这个判断部分的内容是n++<=2,那么这里我就有个问题来问大家,我们是将n之前的值跟2进行比较?还是将n++之后的值来跟2比较?这里我就直接跟大家说,因为这里的++是后置++,所以我们是先将n之前的值来跟2进行比较,比完之后再将n的值再加上1 ,如果我们这里改一下改成++n的话,那么我们这里就是将n加1之后的值·,再来跟2进行比较。好这时候可能就有小伙伴们放松警惕了给出了类似1 2 3 4 这样的答案,但是小伙伴发现了没,我们这里的while语句后面是直接加一个分号的,这说明了什么我们这里是空语句也就是while循环里面的循环体什么都没有,所以我们这里的printf语句是等while循环结束之后再执行的,所以这里的printf语句就只会执行一次,那么来看while循环结束之后我们的n等于多少,首先我们来看当n等于2的时候我们来执行判断语句,首先这里的2==2判断为真,就会执行了下面的循环体于此同时n的值也就会变成3,因为循环体为空,所以我们就又来到了while循环的判断部分,因为这里的n等于3 所以我们就会判断为假,所以就会跳出循环,但是因为这里为n++,所以跳出循环的同时n的值会再加上1 ,所以这里的n就变成了4,所以再执行下面的printf语句的时候就会打印出4 。

第二题解析

#include
int main()
{
	int x = 0;
	int y = 0;
	for (y = 1; y < 10;)
	{
		y = ((x = 3 * y, x + 1), x - 1);
		printf("x=%d,y=%d", x, y);
	}

	return 0;
}

我们这题主要是来带大家看看逗号表达式在这里的运算,首先我们来回顾一下逗号表达式的知识点:1.逗号表达式的运算顺序是从做向右计算2.逗号表达式的值为逗号最右边表达式的指。那我们再来看这道题首先y的值初始化为1 ,然后判断部分判断为真就进入for循环的循环体里面,好我们来看这个循环体的内容为y = ((x = 3 * y, x + 1), x - 1);我们首先来看右边的内容他是一个逗号表达式因为逗号表达式是从最左边开始吧,那么我们就来看最左边,这时候我们就发现这个最左边的表达式它也是一个逗号表达式,那么这里就是一个逗号表达式里面嵌套一个逗号表达式,那我们就看最里面的逗号表达式:首先最左边的表达式意思是将y的值乘以3然后再赋值给x,那么我们这里的y是1 乘以3就变成了3所以我们这里的x就变成了3,然后我们再来看下一个表达式x+1,那么我们这里就变成了4,所以我们里面的逗号表达式的结果就变成了4,然后就执行外层的逗号表达式的表达式2 ,它是x-1,又因为x的值为3所以这个外层的逗号表达式的结果就为2 ,然后赋值给y,那么我们第一层循环下来我们的y=2,x=3,进入for循环的判断部分,判断为真,那么继续执行下面的循环体部分,有了第一次循环的经验我们发现这里的两个逗号表达式可以将其化简为先x=3y然后y=x-1,大家可以想想是不是这个意思,那么这样的话我们这里就简单了,因为第一次循环之后y的值变成了2,所以第二次循环x就等于6,y就等于5,进入第三循环x就等于3y等于15,然后x就等于了14,进入判断部分发现不成立就跳出循环执行printf语句,那么我们这里打印的结果就变成了x=15 y=14,看到这里大家应该能够明白这里的意思,然后大家发现了没有我们这里的for循环的表达式3是省略了的,因为我们下面的循环体可以改变y的值,所以我们这里的表达式3也就可以省略,而且也不会造成死循环。

第三题解析

#include
int main()
{
	int n = 2;
	int k = 0;
	while (k++ && n++ > 2);
	printf("%d %d\n", k, n);
	return 0;
}

其实我们的第三题和第一题有 那么点相似,啊这时候就有小伙伴们会说啦,啊叶超凡啊你这是在水文章吧,搞两个相似的文章上来,啊大家千万别误会了,我们这里还是有个地方值得大家学习的,首先我们这里将n初始化为2,k初始化为0,然后就进入了while语句的判断部分,首先我们看到这里有个&&操作符它的两边的表达式都为真的时候整个表达式才能判断为真,首先会判断左边的表达式,这时我们发现它是k++这是一个后置++,那我们这里是先判断k再来++,因为我们的k一开始为0所以我们左边就判断为假,然后k再++,但是我们这里是&&它的左边为假的话,那么不管右边的表达式判断结果如何整个表达式都会为假,所以我们的编译器就不会执行右边的表达式,所以这里的n++就不会执行,所以n的值就不会改变,又因为while后面有分号所以就会执行下面的printf语句,所以我们这里打印出来的值为1 2 .同理哈我们还有个操作符||这个跟&&是同样的道理,当||左边的表达式判断为真的时候就不会执行右边的表达式,大家这里要注意别搞错了。看到没没水文章吧。

第一题解析

第1题:
c语言习题---(循环语句)_第7张图片
首先我们这里求解的是n的阶乘,那么我们这里肯定是先得输入一个n的值的,然后再来计算这个值的阶乘,那么这里就来看如何计算这个值的阶乘,其实我们之前做个一个类似的题,就是计算累加从1一直加到n,我们当时的代码时长这样的:

#include
int main()
{
	int i = 1;
	int sum = 0;
	int n = 0;
	scanf("%d", &n);
	while (i <= n)
	{
		sum = sum + i;
		i++;
	}
	printf("%d", sum);
	return 0;
}

我们是先创建一个变量i,并且将其初始化为1,表示的是从1开始一直往后加,然后每次循环都会使得i的值加上1 ,然后我们还创建了一个变量n,表示该循环要循环的次数,那么我们这里也就表示的从1开始累加,累加到n为止,这些都完成了那么我们这里就还剩下一个问题就是,如何把这些累加给储存下来?那么我们这里就可以这样,再创建一个变量sum,将其初始化为0,每次循环之后将sum的值加上i的值再赋值给sum,这样我们就可以将每次累加的值储存起来,这里我们可以梳理一下一开始sum的值为0,i的值为1 ,那么经过第一次循环sum的值就等于0+1=1,i++,i就等于2,再经历一次循环,因为在上一次循环之后sum的值就变成了1,所以在第二次循环的时候sum的值就变成了1+2=3,同理第三次循环sum的值就等于1+2+3=6,第四次循环sum的值就变成了1+2+3+4=10后面就以此类推。我们就可以得到任何一个数累加的值,那么我们看这里是累加的,那我们的阶乘是累乘,所以我们这里就可以照葫芦画瓢,我们将变量sum改成变量multiply,并且将其初始化为1,然后每次循环的循环体改成multiply=multiply*i,这样我们就可以将每次相乘的值存储下来,这里我们可以推一下,一开始multiply的值为1 ,i的值也为1,那么相乘再赋值可以得到multiply还是1,然后i++,i就变成了2,再经历一次循环,相乘再赋值multiply的值就变成了12=2,i的值也就变成了3,再经历一次循环,相乘再赋值multiply的值就变成了了123=6,i的值就变成了4,再经历一次循环,相乘再赋值multiply的值就变成了1234=24然后我们后面就可以依次类推,我们更具这个循环体就可以得到n的阶乘的值。代码如下:

#include
int main()
{
	int i = 1;
	int multiply = 1;
	int n = 0;
	scanf("%d", &n);
	while (i <= n)
	{
		multiply = multiply * i;
		i++;
	}
	printf("%d", multiply);
	return 0;
}

第二题解析

第2题:
c语言习题---(循环语句)_第8张图片
我们上一题讲到了n的阶乘如何求解,那么我们这道题讲解如何将这些阶乘求和,那么我们这里能否将其看成两个问题,一个是得到不同的阶乘的值,另一个就是将这些值进行累加,并且将其放到循环里面进行实现,这里我们可以使用一个内部嵌套的循环的形式,外层循环用于计算阶乘的相加,内部的循环用于计算阶乘的值,并且内部的循环是放到实现阶乘相加的前面,那么这里每一次外部循环就是先计算出阶乘的值,再将其相加,这时候我们就有小伙伴们就反应特别块一下子写出了代码这里我们为了方便一点就改成计算到3的阶乘:

#include
int main()
{
	int i = 0;
	int multiply = 1;
	int n = 0;
	int sum = 0;
	for (n = 1; n <= 3; n++)
	{
		for (i = 1; i <= n; i++)
		{
			multiply = multiply * i;
		}
		sum = sum + multiply;
	}
	printf("%d", sum);
	return 0;
}

其实大家可以运行一下这段代码,大家就会发现在这段代码是有问题的,答案等于15,可能很多的小伙伴都不是很能理解哈,因为这个代码很清楚很有道理,咋就出错了呢?对吧每次循环先计算阶乘再把就阶乘相加,这不是靠谱他妈给靠谱开门靠谱到了家吗?咋就错了呢?好这里我就给大家详细的一个一个的分析首先我们看阶乘的概念是从1乘到指定数,大家记住是从1开始
那我们我们就从循环开始一开始进入for循环将n赋值为1,然后就进入内部的for循环将i赋值为1,因为这里的判断条件为i<=n所以我们这里就只会循环一次multiply就等于11=1,然后就跳出来内部的循环,sum就等于0+1,好这里外部循环就执行完了一次,n的值就变成了2 ,再继续执行内部的for循环,一开始将i初始化为1 ,然后根据判断条件这里会循环两次,第一次multiply=11 第二次multiply=12=2,然后就跳出了内部循环下面的sum=1+2=3,好这时外部的for循环第二次就执行完了,开始执行第三次我们的n就变成了3,再进入内部的for循环将i初始化为1 ,根据判断条件这里会循环三次,那我们来看第一次循环,因为根据我们第二次外部循环的结果我们这里的multiply为2 ,我们并没将其初始化为其他的值,所以在外部第三次循环的内部第一次循环我们的multiply=multiplyi=21=2,第二次multiply=22=4,第三次就是multiply=43=12,因为我们上面说了阶乘是从1开始的,而我们的第三次外部循环求3的阶乘就变成了从2 开始也就是说从123变成了22*3=12所以这里就是我们造成错误的原因,那我们如何进行修改呢?我们可以在外部循环里面讲multiply进行一次赋值使得每次循环的开始都能保证multiply是从1开始的,那么我们的代码如下:

#include
int main()
{
	int i = 0;
	int multiply = 1;
	int n = 0;
	int sum = 0;
	for (n = 1; n <= 3; n++)//计算阶乘
	{
		int multiply = 1;
		for (i = 1; i <= n; i++)
		{
			multiply = multiply * i;
		}
		sum = sum + multiply;//阶乘相加
	}
	printf("%d", sum);
	return 0;
}

这样我们的结果就是对的了。当然有些小伙伴们可能觉得这里嵌套的循环不是很好的想,那么我们这里就可以改一下代码如下:

#include
int main()
{
	int sum = 0;
	int multiply = 1;
	int i = 1;
	int n = 0;
	scanf("%d", &n);
	while (i <= n)
	{
		multiply = multiply * i;//计算阶乘
		sum = sum + multiply;//阶乘相加
		i++;
	}
	printf("%d", sum);
	return 0;
}

那么这段代码的运行原理就是:我们3的阶乘变成4的阶乘的时候,我们是没有必要再从1开始相乘的,我们可以直接在3的阶乘基础上直接乘以4 ,所以我们的代码就可以这么写。

第三题解析

第3题:
请添加图片描述
这题我也来给大家讲两个写法好吧,啊有些小伙伴看到这个题的时候一下子就慌了,啊这是算出来的结果是小数啊,这我们怎么能得到小数啊,而且这里的循环一下子是正数,一下子是负数这咋搞啊。大家不要慌哈,首先我们来解决小数的问题,我们之前在讲初始c语言的时候说过这么一句话,叫当我们这个(/)操作符的左右两端只要有一个是小数的时候,我们得到的结果就是小数,所以我们可以把这里的1改成1.0这样得到的结果就是小数,好这个问题解决了我们再来看如何解决这个减号的问题,我们这里就分为两种解决的办法
第一种:虽然这里有加号和减号,但是这里的加减都是有规律的分母为偶数的话就为减,分母为奇数就为+,但是我们知道一件事就是偶数之间相差为2 ,奇数之间相差也为2 ,那么我们这里可以先计算出都是相加的情况就是1/1+1/2+1/3+1/4…+1/100,然后再减去两倍的1/2+1/4+1/6+…1/100,如果是这样的话,那就很简单了嘛这不就是两个循环吗,而且第二个循环不就是讲将i++改成i+=2嘛,那我们的代码实现如下:

#include
int main()
{
	int i = 1;
	double sum1 = 0;
	double sum2 = 0;
	for (i = 1; i <= 100; i++)
	{
		sum1 = sum1 + 1.0 / i;
		
	}
	for (i = 2; i <= 100; i += 2)
	{
		sum2 = sum2 + 1.0 / i;
	}
	printf("%f", (sum1 - 2 * sum2));
	return 0;
}

解法2
因为这里是一个正数接一个负数,而且之前我们在讲操作符的时候提到过(-)这个操作符,可以使正数变成负数,还可以使得负数变成正数,那么我们这里可以创建一个变量signed并且将其初始化为1,每次计算的时候可以将它乘以变量i,在计算完之后在下面执行signed=-signed这个操作,这样就可以使得在下一次循环的时候signed变成负数,他变成了负数也就表明这里变成了减号,而且在下下次循环他又会变成正数,那也就又变成了加号那么我们的代码如下:

#include
int main()
{
	int i = 0;
	double sum = 0;
	int sign = 1;
	for (i = 1; i <= 100; i++)
	{
		sum = sum + sign*1.0 / i;
		 sign = -sign;
	}
	printf("%f", sum);
	return 0;
}

第四题详解

第4题:
请添加图片描述
这题要我们求两个数的最小公倍数,那我们先来看看最小公倍数的概念是什么?首先创建两个正整数a,b然后我们a和b的公倍数设为c,那么这个c%a是等于0的并且c%b也是等于0的,那么我们称这个c为a和 b的公倍数,其实c是有非常多的值的,比如说a*b这就是一个非常容易得到值,但是这只是其中一个我们这里要求这所有公倍数中最小的一个,那么我们这里就将这个数称为最小公倍数。这里我们给出两种方法来球这个数
第一种:
其实大家可以在生活中发现这么一个规律就是:如果求解一个问题有多种方法的话,那么越是简单的方法他的计算量越大,越是难以理解的方法他的计算量就越小,那么我们这里的第一种方法就是最简单最容易想到的方法我们将他称为穷举法,首先我们要想的一个问题就是这个最小公倍数会不会比那两个数都小肯定不会,那么这个数会不会比这两个数中的较大的数小,也不会那么这个数一定是比这两个数都要大,那么我们就可以创建一个变量将他的值附值为最大的值,然后将这个变量%a和b,只要有一个%出来的值不等于0那么这个数就不是a和b的公倍数,那么我们就将这个值加1,再继续尝试直到%a和b的值都等于0的时候,我们就可以找到公倍数,并且那个数还是最小的,因为前面的数都不是公倍数,那么我们这里就可以使用while循环后面表达式写成(x%a!=0||x%b!=0)然后循环体里面就可以直接写成x++来表示验证下一个数是不是最小公倍数:

#include
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d", &a);
	scanf("%d", &b);
	int i = a > b ? a : b;//找到最大的数
	while (i % a || i % b)//判断该数是否为最小公倍数
	{
		i++;
	}
	printf("%d", i);

	return 0;
}

第二种方法:
其实大家可以感觉的到,我们的第一种方法十分的无脑,这不就是一个一个的找嘛,而且这个方法的效率也非常的低,那我们来看这个有没有非常快的解决办法,首先我们想啊,我们先创建一个变量n将其赋值为这两个数的最大的一个数,这里我们假设较大的数是a,较小的数是b,然后我们上一个方法是每次循环都加1 ,但是大家发现没有其实这个1,他加的有点多余的,或者说加的有点小,那我们试着能不能加一个更大的数呢?每次都加一个更大的数,是不是就可以更快的到达目的地,那这个更大的数如何来找呢?好我们一开始是将n赋值为啊a,那么这时候这个n%a是不是一定等于0,但是n%b就不一定吧,那么我们这个时候再让n的值加a的话,是不是%上a还是等于0,两倍嘛!但是%b的话是不是也不一定,但是我们这里是循环嘛,我们可以一直重复直到找到为止,那么这里可能有小伙伴感到疑惑为什么每次都加这个最大的数呢?加一个小一点的不行吗?或者加个更大的不行吗?大家这里可以这么想,我们之所以每次都加最大的数是因为我们要保证这个数首先得是a的倍数,然后再来测试是否为b的倍数,我们本来一开始就是a的倍数你加一个比a小的数他还能是a的倍数吗?肯定就不是了嘛,好这时候有小伙伴们说那更大的呢?我一下子不能加2a吗?它也可以保证是a的整数倍啊。那么这里确实是a的整数倍,我们不停的循环下去也确实是可以找到b的整数倍的数,但是大家要记住我们这里要求的是最小公倍数,一下子加两倍的a的话很可能会导致找到了公倍数但不是最小的,所以大家这里要注意一下,看到这里大家应该能够明白这道题的做法了,我们来看一下代码。

#include
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d", &a);
	scanf("%d", &b);
	int n = a > b ? a : b;//将n赋值为最大的数
	while (n % (a < b ? a : b) != 0)//判断%上最小的数是否等于0
	{
		n = n + (a > b ? a : b);//每次加上最大的值
	}
	printf("%d", n);


	return 0;
}

这里大家看的可能有点难受,这里主要是想让大家熟悉一下条件操作符。

第五题解析

第5题:
请添加图片描述
上面讲了如何求得最小公倍数,那么我们这里来讲讲如何求得最大公约数,大家感觉我这里的设计是不是还挺合理的。我们先来看看最大公约数的概念:这里我们就简述一下:我们假设一个为x,如果m能整除x,并且n也能整除x,那么我们就称x为m和n的公约数。当然这个x有好多个数,我们要求最大的,那么我们这里同样有两个方法来求解:
第一个方法:
首先创建一个变量x,那么我们首先可以知道的是x的值一定不会大于这两个数的最小值的,那么我们就可以将这个数赋值为这个较小的数,那么这样我们就可以确定了x这个最大公约数的范围,那么我们这里就可以一个一个的将其试出来,这里我们可以使用while循环,且后面括号里面的表达式为
(a % i != 0 || b % i != 0)这个就可以来判断是否为最大公约数,并且每次循环都让i的值减一,如果i的值等于1 的话,我们这里就用break跳出循环,因为1就是下线了,这里跟上面的例子差不多这里大家可以参考上面的步骤照葫芦画瓢其代码如下:

#include
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d", &a);
	scanf("%d", &b);
	int i = (a < b ? a : b);//让i的值等于两个数中较小的值
	while (a % i != 0 || b % i != 0)//判断是否为最小公约数
	{
		if (1 == i)//如果i为1的话那么就最小公约数就为1了
		{
			break;//跳出循环
		}
		i--;
	}
	printf("%d", i);

	return 0;
}

第二个方法:
这里我们就用辗转相除法来写这个题,但是我们这里就不介绍这个辗转相除法的原理了,因为我们这里主要是要大家体会循环的运用,那么辗转相除法的运算过程是:第一步:对于两个整数m和n,使得m>n 。第二步:取余数r=m%n。第三步:若r=0,则n为取得的最大公约数,否则执行m=n;n=r;r=m%n。我们来举一个例子吧,我们求24和18的最大公约数,那么这里就m等于24,n等于18,r=24%18=6不等于0,那么就让m=18,n等于6,再计算r的值r=18%6=0,所以我们这里的最大公约数就为n=6 。 那么我们这里就可以发现其实这里是有一个循环的,而且跳出循环的条件就是r=0,那么我们这里就可以使用while循环,因为当r不等于0的时候我们会继续辗转相除,所以我们这个循环继续的条件就是r!=0,那么我们就可以将这个表达式放到while后面的括号里面,那么这道题的思路也就非常的清楚了,首先输入两个值,然后再找到这两个值的最大值,再用循环实现辗转相除法,那么这道题的代码如下:

#include
int main()
{
	int m = 0;
	int n = 0;
	int r = 0;
	int t = 0;
	scanf("%d", &n);
	scanf("%d", &m);
	if (m < n)//交换值使得m为最大值
	{
		t = m;
		m = n; 
		n = t;
	}
	r = m % n;
	while (r != 0)//辗转相除法的实现
	{
		m = n;
		n = r;
		r = m % n;
	}
	printf("最大公约数为:%d\n", n);

	return 0;
}

这个方法是不是就比我们一个一个试来的快的多啊,那么我们这道题就说到这。

第六题解析

第6题:请添加图片描述
我们来解个方程,这里我们根据高中的知识其实可以知道这里是个⚪,但是我们发现在这个园还非常的大,那么我们这里是很明显不能将其一个一个的列出来的,但是我们这里可以使用循环结构呀,我一个一个的尝试很麻烦,但是电脑就很快啊,而且我们的方法还十分的简单题目已经告诉了我们计算的公式,首先我们知道这里是x方,和y方,然后要求的还是正整数的解,那么我们这里可以知道的是x的值肯定是小于45的,因为45*45等于2025它已经大于了1989,而且同理可得我们的y值它也是要小于45的,并且还是正整数,那么x和y的值就是从1开始,那么我们这里是不是可以将所有的可能全部列出x是从1到45,y是从1到45,我们是不是就可以使用循环的嵌套将所有的坐标到原点的距离全部算出来然后再与1989进行比较如果等于的话就将其写出来那么这里我们就可以使用循环的嵌套实现,代码详细如下:

#include
int main()
{
	int x = 0;
	int y = 0;
	for (x = 0; x < 45; x++)
	{
		for (y = 0; y < 45; y++)//循环嵌套用穷举法尝试x和y的坐标
		{
			if (x * x + y * y == 1989)//判断坐标是否在圆上
			{
				printf("x的值为%d,y的值为%d\n", x, y);
			}
		}
	}
	return 0;
}

第七题解析

第7题:
c语言习题---(循环语句)_第9张图片

首先我们来看看素数的概念:数学上指在大于1的整数中只能被1和它本身整除的数。如2、3、5、7、11、43、109,那我们如何求解素数呢?这里我们也可以使用穷举法,比如说一个数n,我们要判断他是不是素数,那么我们是不是可以用循环的方法将他除以大于1小于n-1的所有数,如果发现其中只要有一个数能够将他整除,那么说明这个一定不是素数,如果所有的数都试完了,还是不能整除的话,就说明他是素数,那么我们的代码如下:

#include
int main()
{
	int n = 0;
	int i = 2;
	scanf("%d", &n);
	for (i = 2; i < n; i++)//一个一个的检查是否为素数
	{
		if (n % i == 0)//判断是否可以整除
		{
			printf("%d不是素数\n", n);
			break;
		}
	}
	if (i == n)//判断为素数
	{
		printf("%d是素数", n);
	}
	
	return 0;
}

好一个数是否为素数我们判断完了,那么接下来我们就要将这些数全部都加起来,那么这里我们是不是可以在外面再加上一个循环,这个循环就是产生2到n的各个值,并且外面这个外部循环还可以将所有的素数加起来,那我们这里可以类比之前的题的做法,但是我们这里要加的数是素数,那么我们的代码实现如下:

#include
int main()
{
	int n = 0;
	int i = 2;
	int j = 0;
	int sum = 0;
	scanf("%d",&n);
	for (j = 2; j <= n; j++)//该循环的作用是产生2~n的数
	{
		for (i = 2; i <j; i++)//该循环用于判断是否为素数
		{
			if (j % i == 0)
			{
				break;
			}
		}
		if (i==j)//判断为素数则将其相加
		{
			sum = sum +j;
		}
	}
	printf("%d", sum);
	return 0;
}

大家可以自己多多尝试

第八题解析

第8题:

c语言习题---(循环语句)_第10张图片我们看到这道题,首先他给出了完数的概念,首先我们是不是得得出一个数的所有的因子,那么我们这里是不是就可以用到穷举法,将这个数%上除了他自己本身以外的所有数,如果%之后等于0那么就说明这个数是因子,那么我们这里求的是所有的因子,那么我们是不是得要一个循环来得出所有的因子,然后将所有的因子加起来,那么我们的代码如下:

#include
int main()
{
	int i = 0;
	int j = 0;
	int sum = 0;
	scanf("%d", &j);
	for (i = 1; i < j; i++)//列出所有的初速
	{
		if (j % i == 0)//判断死否是因子
		{
			sum = sum + i;//将所有的因子相加
		}
	}
	if (sum == j)//判断是否是完数
	{
		printf("%d是完数\n", j);
	}
	else
	{
		printf("不是完数\n");
	}
	return 0;
}

好这里我们知道了如何判断一个数是否为完数,那么我们的题目的要求是将所有1000以内的完数的和,那么我们这里就需要一个外层循环来列出所有的数,再通过内部循环筛选出完数,再将他们全部打印出来,大家这里要注意一下,因为我们这里是循环的嵌套,所以我们每次外部循环执行一次之后记得要将sum的值赋值为0,以确保下面的判断能继续执行,那么我们的代码如下:

#include
int main()
{
	int i = 0;
	int j = 0;
	int sum = 0;
	for (j = 2; j <= 1000; j++)
	{
		sum = 0;//大家注意这里要初始化
		for (i = 1; i < j; i++)//列出所有的初速
		{
			if (j % i == 0)//判断死否是因子
			{
				sum = sum + i;//将所有的因子相加
			}
		}
		if (sum == j)//判断是否是完数
		{

		printf("%d是完数\n", j);
		}
	}
	return 0;
}

第九题解析

第9题:
c语言习题---(循环语句)_第11张图片
我们再来看一下这个题:首先我们可以看到这个题首先我们可以知道,每一项的分子为前一项的分子和分母的和,然后每一项的分母为前一项的分子,首先这个规则是从第二项开始的,那么我们这里的第一项是2/1,所以我们这里是不是就可以创建三个变量一个用来储存分子,一个用来储存分母,一个用来储存相加的值,假设分母为y分子为x,那么下一项的分母就等于x,下一项的分子就等于x+y,但是大家在写代码的时候要注意一点的是我们要先赋值分母再来赋值分子,大家可以自行思考一下为什么,那么我们一开始将x初始化为2,将y初始化为1 ,再通过循环来实现累加sum=sum+x/y,因为我们这里要得到小数所以我们在x的前面乘以1.0,用来得到小数那我们的代码实现如下:

#include
int main()
{
	int x = 2.0;//分子
	int y = 1;//分母
	int t = 0;//创建临时变量来得到新的分母分子的值
	int i = 0;
	double sum = 0.0;//和
	int n = 0;
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
	{
		sum = sum + 1.0 * x / y;
		t = x;
		x = x + y;
		y = t;
	}
	printf("sum=%f\n", sum);
	return 0;
}

第十题解析

第十题:
c语言习题---(循环语句)_第12张图片
这里我们来看一下这个题怎么来做哈,这里我们讲两个方法:
第一种:
首先我们可以得到这是一个数组,我们要在一个数组里面找到一个数字n,那么首先我们要知晓的一件事情就是我们这个数字很可能是找不到的,我们这里就得分两种情况一个是找的到,另一个就是找不到,因为这里是一个数组,数组里面装的数肯定是有限的,那么我们这里就可以用循环来一个一个的找,我每一个数组的元素都对比一下,是不是就可以找到了,那么我们这里假设一个数组有十个元素,数组的元素为1 2 3 4 5 6 7 8 9 10我们要找7这个元素,如果找到的话我们就返回这个元素的下标,那么我们这里通过循环用一个一个比较的方法来实现这个功能代码如下:

#include
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	int k = 0;
	scanf("%d", &k);
	int n = sizeof(arr) /sizeof( arr[0]);
	for (i = 0; i < n; i++)
	{
		if (k == arr[i])
		{
			break;
		}
	}
	if (i < n)
	{
		printf("找到了下标为:%d", i);
	}
	else
	{
		printf("没找到\n");
	}

	return 0;
}

第二种方法:
其实大家可以发现我们上面的方法在做题的时候其实效率是非常的低的,因为我要从头开始寻找,如果我们要找的那个数在末尾的话,那么我们这个方法就非常的吃亏,如果这个数组的数据还非常的多的话,那么我们这个查找的效率其实是非常的低的,那么这里大家在读题的时候是否发现了这个点没?我们的数组其实是一个有序的数组,也就是说我们的数组里面的元素其实是按由小到大的规律递增的,那么我们是不是就可以使用这个规律呢?好这里我们先创建三个变量一个是left表示最左边的数,一个是最右边的数表示right,一个是mid表示中间的数,那么我们这个mid就等于(left+right)/2,然后我们假设我们要找的数大小为k,那么这里我们就用下标为mid所对应的数来和k进行比较,如果k大于下标为mid所对应的数,那么这里我们就可以知道k的值所对应的下标其实是在mid和right之间,那么我们这里就要缩小范围我们就将left等于mid+1,那么我们这里的mid就等于新的(right+left)/2,然后继续进行比较,那么如果k的值小于下标为mid所对应的数呢?那么我们这里就将right等于mid-1;来缩小范围然后继续用新的mid来继续进行判断,那么这里大家其实可以看的出来这里是一个循环,那么既然是循环的话,我们就得要有让循环停止下来的条件,这里我们可以将条件分为两种:第一种就是找到了,那么这个条件就非常好的得出来,我们可以使用if语句如果arr[mid]=k我们就可以通过break语句来跳出循环,另外一个循环终止的条件就是当我们这样不停的求出mid再将mid-1的值赋给right或mid的时候我们肯定会出现一种情况就是left的值大于right出现这样的情况就表明这个数在我们的数组里面是不存在的,我们来看个例子假设数组的元素为0 1 2 3 4 5 6 8 9 10,我们要找7这个数所对应的下标,那么我们这里一开始left的值等于0 ,right等于9,所以根据计算我们这里的mid就等于了4,下标4所对应的数组的元素就为4,4的值是小于7的,那么我们这里就将left的值赋值为4+1=5,所以这里我们再计算以下mid的值就等于(5+9)/2=6,而下标为6所对应的值为6,而6还是小于7,所以left就等于6+1=7,mid就等于(7+9)/2=8,下标为8对应的值为9,这时9是大于7的,所及我们就将right的值改为8-1=7,而mid就等于(7+7)/2=7,但是下标7所对应的值为8,还是大于7,所以right就等于7-1=6,好这时候就出现了right小于left的情况就说明了这里是找不到该值的下标的,那么希望大家能够理解这个方法我们的代码实现如下:

#include
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,11 };
	int left = 0;
	int right = sizeof(arr) / sizeof(arr[0])-1;
	int k = 0;
	int mid = 0;
	scanf("%d", &k);
	while (left <= right)
	{
		 mid = (left + right) / 2;;
		if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else if(arr[mid] < k)
		{
			left = mid + 1;
		}
		else
		{
			break;
		}

	}
	if (left <= right)
	{
		printf("找到了,下标为%d", mid);
	}
	else
		printf("找不到\n");
	return 0;
}

其实看到这里我们上面有个地方可能会出现错误不知道大家发现没,我们的mid=(left+right)/2,但是这里的相加之和的值超出了int的范围的话,是不是就会出现问题呢?我们在除以2的话得到的结果视乎就不一样了吧,那么我们这里就可以将他改一下改成(left+(right-left)/2)就不会出现这样的情况我们将right相较于left多出来的一部分切一半再加到left的头上是不是就不会产生超出范围的情况了,这里大家好好体会一下。那么本篇文章就结束了大家好好体会一下,这里为了大家更好的学习本篇文章的所有代码点击下面链接可以查看:
点击此处查看

你可能感兴趣的:(c语言习题,c语言)