我是靠谱客的博主 知性太阳,这篇文章主要介绍零基础玩转C语言系列第三章——循环语句一、while语句 二、for循环三、do...while()循环四、练习题,现在分享给大家,希望可以做个参考。

【前言】:循环语句补充的知识点都挺重要的哦,铁汁们要用点心记哦。

一、while语句

while语句

while(表达式)
{
    循环语句;
}

【敲黑板】:条件表达式的执行次数比循环体的执行次数多 1次。

循环中的break语句和continue语句:

break语句在循环中的作用:break是永久终止循环

continue语句在循环中的作用:continue是用于终止本次循环的,也就是说本次循环中continue后面的代码不会执行,而是直接跳转到while语句的判断部分 

补充1:getchar()

函数原型:

int getchar(void)

 功能:

在标准输入缓冲区中读取一个字符,返回读到的字符的ASCII码值,如果读取失败,则返回EOF(-1)

问:为什么getchar()返回的是字符的ASCII码值?函数返回值为什么要放到一个int类型的变量中呢?不是应该放在一个char类型的变量中吗?

如:

int ch = 0;
ch = getchar();

答:

  • getchar()返回了字符的ASCII码值,ASCII码值是整数,存放在整型变量中没有任何问题;
  • 这一点也是最重要的一点,getchar()读取失败的时候返回EOF,EOF本质是-1(#define EOF -1),是一个整型值,在一个char类型中,是存储不下的;
  • 再结合getchat()函数的原型,getchar()的返回类型被定义为int, 那么返回数据应该被存放在int变量中

getchar(): 获取/输入一个字符;

putchar(): 输出一个字符

注意哦,这两个函数一次只能操作一个字符,没有scanf(),printf()功能齐全 

补充2:输入缓冲区

引入:

#include<stdio.h>

int main()
{
	char input[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", input);//输入abcdef最后加上一个n
	printf("请确认密码:(Y / N):>");
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功n");
	}
	else
	{
		printf("确认失败n");
	}
	return 0;
}

此时输入缓冲区中放的是abcdefn,scanf()函数将abcdef读走了,留下了一个n,所以n直接被getchar()读取,所以此时ch里面放的是n,后面不会等到我们确认密码就直接输出确认失败了。 

存在的问题:本题输入abcdef,然后按回车键,还没有等到我们输入字符(Y/ N)就直接输出“确认失败”了,那怎么改才能成为我们想要的呢?

在scanf()下面加上一条语句:getchar();目的只有一个,拿走回车键('n'),

 

存在的问题:这样改只能保证输入“abcdef”时可以正常执行,但如果输入的是"abcdef hehe"时又会直接输出“确认失败”了,不信你看... 

我丢,这什么鬼,怎么又错了!?

注意:

scanf("%s", ...); //scanf()读取字符串的时候遇到空格时就停下来不再读取了 

分析上段代码:

#include<stdio.h>

int main()
{
	char input[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", input);//scanf()只读取了"abcdef"
	getchar();//getchar()读取了一个空格,所以这里就有问题了,这里的getchar()只能拿走一个字符,我们想要的是它能将缓冲区
	//里剩下字符全部拿走,直至拿走'n'
	printf("请确认密码:(Y / N):>");
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功n");
	}
	else
	{
		printf("确认失败n");
	}
	return 0;
}

是呀,这里的getchar()只能拿走一个字符,我们想要的是它能将缓冲区里剩下的全部拿走,直至拿走'n',该怎么改?

#include<stdio.h>

int main()
{
	char input[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", input);//scanf()只读取了"abcdef"
    
    //清理缓冲区
	int tmp = 0;
	while ((tmp = getchar()) != 'n')
	{
		;//空语句,什么事都不干,拿字符就行了
	}
	printf("请确认密码:(Y / N):>");
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功n");
	}
	else
	{
		printf("确认失败n");
	}
	return 0;
}

这样就可以了,注意实现上面清理缓冲区的功能哦。

 二、for循环

注意:

for循环的风格更胜一筹,使用的频率也最高。

建议:

  • 不可在for循环体内修改循环变量,防止for循环失去控制
  • 建议for语句的循环控制变量的取值采用“前闭后开”的写法

如:

for(i = 10; i < 10; i++)   //前闭后开

for(i = 10; i <= 10; i++)  //前闭后闭(不建议这样写法,但是为了更好地解读也可以用)

一些for循环的变种:

  • for的初始化、判断、调整三个部分都可以省略;
  • 中间的判断部分如果省略就意味着判断恒为真,构成了死循环

所以,如果条件允许,不建议省略哦。

笔试题:

//问:打印了多少次hehe?
#include<stdio.h>
int main()
{
	int i = 0;
	int j = 0;
	for (; i < 3; i++)
	{
		for (; j < 3; j++)
		{
			printf("hehen");
		}
	}
	return 0;
}

嘿嘿,想必铁汁心里已经有了自己的答案,看看是不是和正确答案一样呢?

 哈哈,说实话,我第一次做这道题目想的是9次,那为什么是3次呢?

 看到了吧,所以尽量不要省略for循环里面的表达式。

 再加一道笔试题:

int i = 0;
int k = 0;
for(i = 0, k = 0; k = 0; i++, k++)   //k = 0为赋值,0为假,判断表达式恒为假,所以循环执行了0次
{
    k++;
}

三、do...while()循环

do...while循环与前面两个循环不同的是,它的循环体至少执行一次!

do
    循环语句;
while(表达式);

注意:do...while语句使用的场景有限,所以不会经常使用。

四、练习题

练习1:计算n的阶乘

伪代码:

int ret = 1;
int i = 0;
for(i = 1; i <= n; i++)
{
    ret = ret * i;
}

练习2:计算1!+2!+3!+...+n!

在练习1中我们知道了计算n的阶乘的方法,所以计算1!+2!+3!+...+n!就简单多了。

来,先看一个错误示范:

//为了方便测试我在这里就简单计算到1!+2!+3!
#include<stdio.h>

int main()
{
	int i = 0;
	int ret = 1;
	int sum = 0;
	int n = 0;
	for (n = 1; n <= 3; n++)
	{
		for (i = 1; i <= n; i++)
		{
			ret = ret * i;
		}
		sum = sum + ret;
	}

	printf("%dn", sum);
	return 0;
}

实际上1!+2!+3! = 9, 但是实际上结果是...

结果却是15,这是为什么呢? 

因为第二层循环里面的ret是上次留下的值,而我们希望执行完一次计算某数的阶乘后,需要将ret重置为1,然后再计算下一个数的阶乘。

所以,改写代码如下:

//为了方便测试我在这里就简单计算到1!+2!+3!
#include<stdio.h>

int main()
{
	int i = 0;
	int ret = 1;
	int sum = 0;
	int n = 0;
	for (n = 1; n <= 3; n++)
	{
        ret = 1;//注意哦
		for (i = 1; i <= n; i++)
		{
			ret = ret * i;
		}
		sum = sum + ret;
	}

	printf("%dn", sum);
	return 0;
}

上面的代码虽然是对的但是依然不够高效,时间复杂度是O(N^2),那可不可以只利用一层循环就解决了呢?其实是可以的,因为上面进行了很多次重复计算。

如上面计算1!+2!+3!,就进行了很多次重复计算

//ret * 1
//ret * 1 * 2
//ret * 1 * 2 * 3

所以改写成高效的代码如下:

for(n = 1; n <= 3; n++)
{
    //n*(n-1)! = n!
    ret = ret * n;
    sum = sum + ret;
}

【敲黑板】:当我们写出一个算法的时候,千万不要骄傲,好好想想怎么样才可以更加精炼,所以要多学多练!

加油加油!! 

 

最后

以上就是知性太阳最近收集整理的关于零基础玩转C语言系列第三章——循环语句一、while语句 二、for循环三、do...while()循环四、练习题的全部内容,更多相关零基础玩转C语言系列第三章——循环语句一、while语句 二、for循环三、do内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(125)

评论列表共有 0 条评论

立即
投稿
返回
顶部