日期: 星期一, 2024年3月11日
时间: 下午10:21
-
输入密码并进行确认:
- 使用
scanf
读取字符串时,遇到空格或换行符会停止读取。因此,用于密码输入的场景中,scanf(" %s", password);
可以避免因空格导致的提前终止。 getchar()
用于读取缓冲区中的下一个字符,返回值是int
类型。这是因为getchar()
返回的字符需要能够表示所有可能的字符以及EOF
(文件结束符),EOF
通常定义为-1。- 清空输入缓冲区的方法:使用
while((tmp = getchar()) != EOF && tmp != '\n');
循环读取字符,直到遇到换行符\n
或文件结束符EOF
,以确保之后的输入不会受到之前残留数据的影响。
- 使用
-
打印数字字符:
- 通过
getchar()
读取字符,并使用条件判断只处理数字字符(ASCII码在'0'至'9'之间的字符),忽略其他字符。
- 通过
-
循环结构:
while
循环和for
循环都是基本的循环结构,用于重复执行代码块直到满足某个条件。while
循环首先判断条件,然后执行循环体。for
循环在语法上更加紧凑,集成了初始化、条件判断和迭代步骤。- 使用
continue
在for
循环中会先执行增量表达式,再回到条件判断;在while
循环中,continue
直接跳到循环的判断表达式。
-
循环控制语句:
break
语句用于立即退出循环,不再执行后续的迭代。- 在循环体内修改循环变量时要小心,以避免造成无限循环或逻辑错误。
-
数组越界:
- 在使用数组时,确保不要访问数组的界限之外,否则会导致未定义行为。例如,在声明了大小为10的数组时,只能访问索引0到9的元素。
-
嵌套循环:
- 嵌套循环中,内层循环的执行速度远高于外层循环。要注意内外循环的控制变量,避免逻辑错误。
-
多变量控制的循环:
for
循环可以使用多个变量进行控制,适用于需要同时改变多个变量的情况。
1. 输入密码并确认
这段代码展示了如何使用 scanf
读取用户输入的密码,并使用 getchar
来清理输入缓冲区,然后确认密码是否正确。
#include <stdio.h>
int main() {
char password[20] = {0};
printf("请输入密码: ");
scanf("%19s", password); // 限制输入长度为19,防止溢出
printf("请确认密码(Y/N):>");
// 清理缓冲区
int tmp;
while ((tmp = getchar()) != EOF && tmp != '\n') {
; // 什么都不做,只是为了清空缓冲区
}
int ch = getchar(); // 读取确认字符
if (ch == 'Y') {
printf("密码确认成功\n");
} else {
printf("密码确认失败\n");
}
return 0;
}
2. 只打印数字字符
这段代码旨在从标准输入读取字符,只打印出数字字符,跳过非数字字符。
#include <stdio.h>
int main() {
int ch = 0;
while ((ch = getchar()) != EOF) {
if (ch >= '0' && ch <= '9') {
putchar(ch); // 如果是数字,就打印出来
}
}
return 0;
}
3. 使用 while
和 for
循环打印1到10
这部分代码演示了如何使用 while
和 for
循环实现同样的功能:打印数字1到10。
- 使用
while
循环:
#include <stdio.h>
int main() {
int i = 1;
while (i < 11) {
printf("%d\n", i);
i++;
}
return 0;
}
使用 for
循环:
#include <stdio.h>
int main() {
for (int i = 1; i < 11; i++) {
printf("%d\n", i);
}
return 0;
}
. 循环中的 continue
和 break
这里解释了 continue
和 break
在循环中的作用,以及它们在 for
和 while
循环中的行为差异。
continue
在for
循环中先执行增量表达式,然后再检查条件。continue
在while
循环中直接重新检查条件。break
用于立即退出循环。
例子:使用 break
来提前退出循环。
#include <stdio.h>
int main() {
for (int i = 1; i < 100; i++) {
if (i == 5) {
break;
}
printf("%d\n", i);
}
return 0;
}
5. for
循环中的变量修改
在 for
循环体内不推荐修改循环变量,因为这可能会导致循环的控制变得不可预测。
6. 嵌套循环与多变量 for
循环
- 嵌套循环的示例,注意内层循环的初始化位置:
#include <stdio.h>
int main() {
int i, j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
printf("hehe\n");
}
}
return 0;
}
使用多变量的 for
循环:
#include <stdio.h>
int main() {
int x, y;
for (x = 0, y = 0; x < 2 && y < 5; ++x, ++y) {
printf("hehe\n");
}
return 0; // 此处缺失了返回值,应补全
}
1. do-while
循环
do-while
循环至少执行一次循环体,然后根据条件表达式的结果决定是否继续执行。这与 while
循环不同,后者可能一次都不执行循环体。
示例:打印1到10的数字
#include <stdio.h>
int main() {
int i = 1;
do {
printf("%d", i);
i++;
} while (i <= 10);
return 0;
}
示例:使用 continue
在 do-while
循环中
注意:在 do-while
循环中直接使用 continue
可能会导致无法达到递增表达式,从而形成无限循环。因此,以下示例中的逻辑需要调整。
// 这个例子代码不正确,因为 `do-while` 循环中使用 `continue` 会导致无限循环。
2. switch
语句
switch
语句用于基于不同的条件执行不同的代码分支。它是一个控制语句,可以替代多个 if
判断。
示例:简单的 switch
用法
#include <stdio.h>
int main() {
int number;
scanf("%d", &number);
switch (number) {
case 1:
printf("hello 1");
break;
default:
printf("你好");
}
return 0;
}
3. 乘法表和阶乘累加
示例:打印乘法表
#include <stdio.h>
int main() {
int n = 0;
int num = 1;
int sum;
do {
sum = num * n;
n++;
printf("%d\n", sum);
} while (n <= 10);
return 0;
}
示例:计算阶乘累加
#include <stdio.h>
int main() {
int i = 0;
int n = 0;
int ret = 1;
scanf("%d", &n);
int num = 0;
for (i = 1; i <= n; i++) {
ret *= i;
num += ret;
};
printf("%d", num);
return 0;
}
4. 二分查找
二分查找是一种在有序数组中查找特定元素的高效算法。
示例:二分查找算法
#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) / 2;
if (arr[mid] < k) {
left = mid + 1;
} else if (arr[mid] > k) {
right = mid - 1;
} else {
printf("找到了下标为%d", mid);
break;
}
}
if (left > right) {
printf("找不到了\n");
}
return 0;
}
5. 字符串和密码输入
示例:逐字符替换字符串并动态显示
注意:以下代码使用了 windows.h
头文件中的 Sleep
函数和 system("cls")
来实现动态效果,这是特定于Windows操作系统的。
#include <stdio.h>
#include <string.h>
// #include <windows.h> // 仅在Windows环境下有效
int main() {
char arr1[] = "welcome to bit!!!!!!";
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);
// Sleep(1000); // Windows特定函数
// system("cls"); // 清屏,Windows特定
left++;
right--;
}
return 0;
}
示例:密码输入和验证
#include <stdio.h>
#include <string.h>
int main() {
int i = 0;
char password[20] = {0};
for (i = 0; i < 3; i++) {
printf("请输入密码: ");
scanf("%19s", password); // 限制输入以防止缓冲区溢出
if (strcmp(password, "123456") == 0) {
printf("登录成功\n");
break;
} else {
printf("密码错误,重新输入!\n");
}
}
if (i == 3) {
printf("三次密码错误,退出程序\n");
}
return 0;
}
实践
游戏设计要点
-
生成随机数:利用
rand()
函数生成一个1到100之间的随机数作为游戏的答案。为了确保每次游戏开始时随机数不同,使用srand((unsigned int)time(NULL))
对随机数生成器进行初始化。 -
用户交互:通过打印菜单提示用户进行选择,可以选择开始游戏或退出。
-
猜数字逻辑:玩家输入一个猜测的数字,程序会告诉玩家猜测结果是“猜大了”、“猜小了”还是“猜对了”。猜对了则游戏结束,否则可以继续猜测。
-
循环游玩:除非玩家选择退出,否则游戏可以无限次进行。
代码解析
主菜单函数 menu
void menu(){
printf("1.play\n");
printf("0.exit\n" );
}
这个函数用来打印游戏的主菜单,提供给玩家选择是开始游戏还是退出游戏的选项。
游戏函数 game
void game(){
int guess; // 玩家猜测的数字
int ret = rand() % 100 + 1; // 生成1到100之间的随机数作为答案
while(1){
printf("猜数字\n"); // 注意这里应该是 \n 不是 /n
scanf("%d", &guess);
if (guess < ret) {
printf("猜小了\n");
} else if (guess > ret) {
printf("猜大了\n");
} else {
printf("猜对了\n");
break; // 猜对了,退出循环
}
}
}
这个函数是游戏的核心,它首先生成一个随机数作为答案,然后不断提示玩家进行猜测,直到猜中为止。
主函数 main
int main(){
srand((unsigned int)time(NULL)); // 使用当前时间作为种子初始化随机数生成器
int input;
do {
menu();
printf("请选择: ");
scanf("%d", &input);
switch (input) {
case 1:
game(); // 开始游戏
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
主函数负责初始化随机数生成器,并在循环中处理玩家的输入,根据玩家的选择执行相应的操作。