C语言:分支和循环语句(2)

目录

●getchar\putchar

​​​​​​● for 循环

●do while 循环

●折半查找(二分查找)



●getchar\putchar

在开始之前先介绍一下 getchar\putchar ,意思与 scanf 和 printf 相近,看名字就知道。不过有所不同的是前者一次只能操作一个字符。

我们先来看一段代码:

int main()
{
	char input[20] = { 0 };
	printf("输入密码: ");
	scanf("%s", input);

	printf("请确认密码(Y/N):");
	int ch = getchar();

	if (ch == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}
	return 0;
}

可以看到 如果输入 abcde 会直接显示else的结果C语言:分支和循环语句(2)

注意:此时输入abcde后,按下回车键会输入一个\n,此时getchar却只能识别到从键盘输入的abcde,而\n却留在了缓存区,\n进入if语句直接识别为else,代码没有达到我们想要的效果。

那该怎么做呢?我们可以把\n再用一个getchar给输入,那么代码就变成了这样子:

int main()
{
	char input[20] = { 0 };
	printf("输入密码: ");
	scanf("%s", input);

	getchar();

	printf("请确认密码(Y/N):");
	int ch = getchar();

	if (ch == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}
	return 0;
}

此时输入abcde就可以正常输出Y/N,但如果输入abcde hehe,此时一个getchar只能把空格输入,缓存区中仍然有其他的字符。

此时,我们在其中加入一个while循环,将缓存区中所有的字符都输入,一直到\n才停止。这样子就能够使不论输入什么,都能保证ch输入的都是Y/N。 

int main()
{
	char input[20] = { 0 };
	pri*/ntf("输入密码: ");
	scanf("%s", input);

	int a = 0;
	while ((a = getchar()) != '\n')
	{
		;
	}

	printf("请确认密码(Y/N):");
	int ch = getchar();

	if (ch == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}
	return 0;
}

whlie循环在此十分重要!!!

补充:EOF的意思是,end of file.

​​​​​​● for 循环

先来看最简单的for循环:

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

可以看到 for 后面的括号中用;隔开每一个条件,这样在修改循坏的内容时会比while循环更加方便简洁。

1)for循环中break的用法:

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

可以看到打印出来只有1 2 3 4,break直接就跳出了for循环。

2)for循环中continue的用法:

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

可以看到5==i,continue后并没有直接跳出for循环,而是跳出了if循环,再次进入for循环。

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

2.建议for语句的循环控制变量的取值采用“前闭后开区间”写法。如i<10优于i<=9。

特殊情况:1.for的初始化,判断,调整三个部分可以省略

2.但默认三个部分都为真,构成死循环

●do while 循环

int main()
{
	int i = 0;
	do {
		printf("%d ", i);
		i++;
	} while;

	return 0;
}

这就是 do while 的基本形式。break和continue与用法for相似。

我们接下来看一道题目:输入一个数,打印该数的阶乘

int main()
{
	int i = 0;
	int ret = 1;
	int n = 0;
	scanf("%d", &n);
		for (i = 1; i <= n; i++)//在此用了一个for循环
		{
			ret = ret * i;//新的ret会等于老的ret乘以i,这样就能保证得出的结果是一个阶乘
		}
	printf("%d\n", ret);
	return 0;
}

难度升级:打印1!+2!+3!+......+9!+10!

int main()
{
	int i = 0;
	int ret = 1;
	int n = 0;
	int sum = 0;
	for (n = 1; n<=3; n++)
	{
		for (i = 1; i <= n; i++)
		{
			ret = ret * i;
		}
		sum =sum+ret;//这句代码等价于sum+=ret;
	}
	printf("%d\n", sum);
	return 0;
}

结果应该是9. 

C语言:分支和循环语句(2)

 为了验证代码的正误,我们先试一下打印1!+2!+3!,但是结果并不是9而是15,为什么会这样呢?我们再打开调试。

C语言:分支和循环语句(2)

 发现了什么?ret的值按理来说应该是6=3*2*1,可是这里为什么会出现12呢?我们推测是出现了12=3*4的结果,那么可以推断上一次ret的值保留到了这一次的运算中去。该如何做呢?只需要每一次重置ret的值就行了,于是我们修改成为如下代码:

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

这样子,我们就能够成功的打印题目所需。

可是有人就会说了:你用了两个for循环是不是太麻烦了?

行直接放代码:

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

 大家自己理解一下哈.

折半查找(二分查找)

二分查找难度较大!!!

一组数组,1,2,3,4,5,6,7,8,9,10,若要找出数字7的下标该如何找呢?首先要知道,数组的下标是从0开始的,如1对应数组的下标为0。

//首先先定义一组数组
int main()
{
  int arr[] = {1,2,3,4,5,6,7,8,9,10};

//如果数组比较长怎样操作呢?可以采如下方法:
  int sz = sizeof(arr)/sizeof(arr[0]);//其中前者是整个数组的长度,后者是一个数字的长度,两者相除就是这个数组有多少个数。

int k = 7;//先定义要找的数字为7,目标是打印7的下标6。
int left = 0;
int right = sz-1;
//这里是找出最左边的数字和最右边的数字的下标,定义为left和right。

//此时定义一个中值,为每次二分过后的值
int mid = (left + right)/2;

//此时就可以开始一步步的进行了
//if(arr[mid]<k)
//{
//left = mid+1;
//}
//
//else if(arr[mid]>k)
//{
//right = mid - 1;
//}
//
//else
//{
//printf("找到了,下标是%d\n",mid);
//}
//在这一个条件语句中,第一步就是让下标为mid的元素(arr[mid]指下标为mid的元素)跟k相比较,如果小于k,那么left就变成mid,但是mid已经比较过了所以就向右移动一个单位,即left = mid + 1,else if也同理。但如果直接就比较出来了,便执行else语句。这样子就完成了一次比较。

//要完成多次比较,那么就需要while循环(for循环也可以),此时代码就变成了如下:

while (left <= right)
	{
		int mid = (left + right) / 2;

		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			printf("找到了,下标是%d\n",mid);
			break;
		}
	}
//至此,已经完成了绝大部分了。那这个代码如果找不到k的下标呢,直接加入如下代码即可:
  if (left > right)
	{
		printf("找不到了\n");
	}
  return 0;
}

这就是二分法的所有过程,怎么样呢?现在理解了吗?这个算法对于新手来说还是相当有难度的,希望大家好好体会其中的精髓。

上一篇:[考试总结]ZROI-21-NOIP冲刺-TEST17 总结


下一篇:8.29 正睿 NOIP 十连测 Day1 题解