【C语言】入门必看之循环练习(含二分查找动图)

文章介绍了良好的C语言编程风格,如避免布尔变量与TRUE/FALSE比较,以及使用0=num和num=0来防止赋值错误。接着讲解了二分查找算法的实现,提供了一个示例代码。然后讨论了如何计算阶乘和阶乘的和,优化了计算过程以提高效率。最后展示了一个实现字符从两端汇聚的效果的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

🚩纸上得来终觉浅, 绝知此事要躬行。
🌟主页:June-Frost
🚀专栏:C语言
⚡注:此篇文章的 代码风格部分 将根据《高质量 C++/C 编程指南》 —— 林锐 进行说明。该部分将用紫色表示
Alt

该篇将对循环语句进行简单练习。


一个小tip:if的风格

if 中与零值的比较:
📙布尔变量:

不可将布尔变量直接与 TRUE、FALSE 或者 1、0 进行比较

因为TURE的值没有统一的标准,所以对于布尔变量好的书写风格为:

if(num) 这里表示num为真
if(!num)这里表示num为假
📙整形变量
较好的书写风格:
if(num == 0)
if(num != 0)
📙指针变量
较好的书写风格:
if(num == NULL)
if(num != NULL)
尽管 NULL的值和0相同,但是意义不同。
这样的风格不会让别人误解变量的类型。

另外,有时为了防止将 if(num == 0) 写成if(num = 0) ,可以将变量放在后面,即if(0 == num) ,就算写成了if(0 = num),因为0是常量,不能被赋值,当程序运行起来后,编译器会报错,可以很快发现问题。

大家如果有兴趣,可以在 《高质量 C++/C 编程指南》 —— 林锐 里了解。


二分查找

以下为二分查找的思维动图:
查找有序数组 元素 7 的下标

所以我们可以将核心分为3步:

  1. 确定查找范围的左右下标,left和right
  2. 根据左右下标(left 和 right),求出中间元素的下标;
  3. 根据mid指定的元素,进行比较,如果相同返回mid,不同就调整left和right,确定最新的范围。

代码如下:

#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 0;
	scanf("%d", &k);
	int sz = sizeof(arr) / sizeof(arr[0]);
	int left = 0;
	int right = sz - 1;
	int flag = 0;//作为查找标志
	while (left <= right)
	{
		int mid = (right + left) / 2;
		if (arr[mid] < k)
		{
			left = mid + 1;//调整范围
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;//调整范围
		}
		else
		{
			flag = 1;
			printf("下标为:%d\n", mid);
			break;
		}
	}
	if (flag == 0)
	{
		printf("不存在该元素,无法找到该下标\n");
	}
	return 0;
}

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

在这道题中,首先要考虑如何计算一个阶乘,对于n!,其实就是将1~ n累计乘在一起就可以了,对于1~ n的数值,直接用循环就可以产生。
计算阶乘:

int main()
{
	int n = 0;
	scanf("%d", &n);
	int i = 0;
	int ret = 1; //用来保存累乘的值 
	for (i = 1; i <= n; i++)
	{
		ret *= i;
	}
	printf("%d\n", ret);
	return 0;
}

既然现在可以计算阶乘了,要计算阶乘的和,只需要用一个循环让n可以变动,再进行求和即可。

int main()
{
	int n = 0;
	scanf("%d", &n);
	int i = 0;
	int sum = 0;
	int j = 0;
	for (j = 1; j <= n; j++)
	{
		int ret = 1; //保证上次阶乘的结果不会在循环中累乘起来
		for (i = 1; i <= j; i++)
		{
			ret *= i;
		}
		sum += ret;
	}
	printf("%d\n", sum);
	return 0;
}

但是在过程中出现了大量的重复计算,都需要重新从1开始累乘,导致效率不是很高。所以我们将重复计算规避。因为 (n-1)! * n 就是 n! ,根据此,改写代码。

#include<stdio.h>
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = 1;
	int i = 0;
	int sum = 0;
	for (i = 1; i <= n; i++)
	{
		ret *= i;
		sum += ret;
	}
	printf("%d\n", sum);
	return 0;
}

实现多个字符从两边向中间汇聚

实现效果如下:


这个问题我们可以通过两个相同大小的数组,用循环将一个数组的内容覆盖到另一个数组上。

#include<stdio.h>
#include<windows.h>
int main()
{
	char arr1[] = "Welcome to the world";
	char arr2[] = "####################";
	int left = 0;
	int right = strlen(arr1) - 1;
	 while(left<=right)
	{
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\n", arr2);
		left++;
		right--;
		Sleep(1000);//1000毫秒
		system("cls"); 
	}
	 printf("%s\n", arr2);
	return 0;
}

用system函数可以执行系统命令,通过“cls” 来清空屏幕产生一个好的效果。


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值