C语言循环语句经典练习实例详解
C语言循环结构是掌握算法逻辑的基础,本文通过阶乘计算、二分查找、字符汇聚及登录模拟五个经典案例,深入解析 for 与 while 循环的具体应用场景。内容涵盖从基础的数值运算到涉及指针与内存处理的字符串操作,并对常见误区如浮点精度、数组边界及头文件依赖进行了详细标注。
计算 n 的阶乘
这是一个基础的双重目标场景:首先获取输入,然后执行累乘。需要特别注意循环控制变量的重置与乘法初始值的设定(通常为 1),以及数据类型对于大数阶乘的限制。
第1步:定义变量并获取输入
- 目的:声明用于存储结果
ret和计数i的整型变量,并通过scanf读取用户输入的n。 - 入口:标准输入流。
- 动作:初始化
ret = 1,注意不能用 0 否则乘积恒为 0。 - 完成状态:控制台等待输入一个整数。
#include <stdio.h>
int main()
{
int n = 0;
int i = 0;
int ret = 1; // 初始值必须为1
printf("请输入要计算的数字 n: ");
scanf("%d", &n);
if (n < 0) {
printf("阶乘不支持负数\n");
return 1;
}
for (i = 1; i <= n; i++)
{
ret = ret * i;
}
printf("%d 的阶乘结果是: %d\n", n, ret);
return 0;
}
计算 1! + 2! + ... + 10! 的和
此题考察嵌套循环或状态保持的思想。直接的方法是使用双重循环,但每次计算新阶乘时重置计数器效率较低;优化方法是在一次遍历中保留上一次迭代的结果(即当前的阶乘值)进行累乘。
第2步:使用单次循环优化求解
- 目的:避免重复计算前缀阶乘,利用数学规律
n! = (n-1)! * n提升效率。 - 参数:
sum用于累加总和,ret用于暂存当前n!的值。 - 关键操作:在循环体内,先更新
ret为新的阶乘值,再将其加入sum。
// 高效解法:时间复杂度 O(n)
int main()
{
int sum = 0;
int ret = 1;
for (int n = 1; n <= 10; n++)
{
ret *= n; // 累积计算阶乘:ret = 1*2*...*n
sum += ret; // 将当前阶乘值加入总和
}
printf("1!+...+10! = %d\n", sum);
return 0;
}
注:若使用双重循环,内层需从 1 遍历至 i 重新计算阶乘,会导致大量冗余运算。
在有序数组中查找特定数字(二分查找)
当数组有序时,二分查找(Binary Search)能将对分搜索的时间复杂度降至 $O( ext{log} n)$。核心在于维护左闭右开的区间或者左闭右闭区间,并安全地计算中间索引以防止溢出。
第3步:实现安全的二分查找逻辑
- 前提:数组必须是有序的(升序或降序)。
- 入口:已排序的数组
arr,目标值k,数组长度sz。 - 动作:使用
while (left <= right)确保覆盖整个区间。中间点计算推荐使用left + (right - left) / 2而非(left + right) / 2,以防两整数相加溢出。 - 判断:若中间值大于目标值,缩小右边界
right = mid - 1;反之扩大左边界。
#include <stdio.h>
int main()
{
// 假设这是一个已经排好序的数组
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int k = 7; // 我们要查找的数字
int sz = sizeof(arr) / sizeof(arr[0]);
int left = 0;
int right = sz - 1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] < k)
{
left = mid + 1;
}
else if (arr[mid] > k)
{
right = mid - 1;
}
else
{
printf("找到了,下标是: %d\n", mid);
break;
}
}
if (left > right)
{
printf("找不到该元素\n");
}
return 0;
}
演示多个字符从两端向中间汇聚
这是一个涉及字符串操作与系统调用的趣味案例。通常利用 Windows API 提供的屏幕清除与休眠函数来制造动态效果,模拟进度条或加载动画。
第4步:构建字符交互与动态刷新
- 包含头文件:需要
<string.h>用于获取字符串长度,<windows.h>用于Sleep和system("cls")。 - 左右指针:设置
left = 0和right = strlen(src_str) - 1。注意源字符串末尾有 '\0',因此有效字符数是长度减 1。 - 渲染循环:将源字符串对应位置的字拷贝至目标显示数组,打印后暂停并清屏。当
left > right时停止。
#include <stdio.h>
#include <string.h>
#include <windows.h>
int main()
{
char src[] = "welcome to bit!!!!!!";
// 初始化目标字符串,填充占位符以便观察变化
char dest[20];
strcpy(dest, src);
// 也可以手动填充其他符号如 '#'
memset(dest, '#', strlen(src));
dest[strlen(src)] = '\0';
int left = 0;
int right = strlen(src) - 1; // 去除末尾 \0 的位置
while (left <= right)
{
dest[left] = src[left];
dest[right] = src[right];
printf("%s\n", dest);
Sleep(500); // 暂停500毫秒
system("cls"); // 清屏
left++;
right--;
}
return 0;
}
模拟用户登录情景(限制次数)
实际开发中常见的业务逻辑。涉及循环控制退出条件和字符串内容的比较方式。严禁对 char 数组使用 == 进行比较,而应调用库函数 strcmp。
第5步:实现受限次数的权限验证
- 规则:用户最多输入 3 次密码。若匹配则中断循环并提示成功;若循环完整执行完未匹配,则判定失败。
- 陷阱提醒:
scanf读取字符串时不需要取地址符&,因为数组名本身就是首地址。另外原代码中变量名拼写错误需修正(如passsword→password)。 - 比较逻辑:使用
strcmp(str1, str2) == 0表示相等。
#include <stdio.h>
#include <string.h>
int main()
{
int i = 0;
char password[20] = {0};
const char *correct_pwd = "123456"; // 预设正确密码
for(i = 0; i < 3; i++)
{
printf("请输入密码: ");
scanf("%s", password);
if(strcmp(password, correct_pwd) == 0)
{
printf("密码正确,登录成功!\n");
break; // 登录成功,跳出循环
}
else
{
printf("密码错误,剩余机会: %d\n", 2 - i);
}
}
if (i == 3)
{
printf("三次密码均错误,退出程序。\n");
}
return 0;
}
以上就是C语言中循环语句练习实例的详细内容,更多关于C语言编程技巧的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









