1.输入一个整数并按逆序输出
- 输入整数:使用?
scanf
?读取用户输入的整数。 - 处理数字:使用循环和取模(
%
)、整除(/
)操作来逐位提取数字,打印逆序后的数字。
#include <stdio.h>
int main() {
int num;
printf("请输入一个整数: ");
scanf("%d", &num);
// 处理负数
if (num < 0) {
printf("-");
num = -num; // 转为正数
}
// 处理 0 的特殊情况
if (num == 0) {
printf("0\n");
return 0;
}
// 循环打印每一位(逆序)
while (num != 0) {
printf("%d", num % 10); // 直接打印最后一位
num = num / 10; // 去掉最后一位
}
printf("\n"); // 换行
return 0;
}
验证输入1000,和-123 的结果?
?
?2.允许用户最多输入三次用户名和密码,判断是否与预设的值匹配。
-
核心逻辑:
- 使用?
while
?循环控制最多三次输入机会。 - 使用?
strcmp()
?函数比较字符串(用户名和密码)。 - 使用?
login_success
?标志判断是否成功登录。
- 使用?
#include <stdio.h>
#include <string.h> // 用于 strcmp 函数
#define MAX_ATTEMPTS 3
#define USERNAME_MAX_LEN 50
#define PASSWORD_MAX_LEN 50
// 预设的正确用户名和密码 (在实际应用中,密码不应明文存储)
#define CORRECT_USERNAME "admin"
#define CORRECT_PASSWORD "123456"
int main() {
char username[USERNAME_MAX_LEN];
char password[PASSWORD_MAX_LEN];
int attempts = 0;
int loginSuccess = 0; // 标志位,0表示未成功,1表示成功
printf("欢迎登录系统!\n");
printf("您有 %d 次尝试机会。\n", MAX_ATTEMPTS);
// 最多循环 MAX_ATTEMPTS 次
while (attempts < MAX_ATTEMPTS) {
attempts++;
printf("\n第 %d 次尝试:\n", attempts);
// 输入用户名
printf("请输入用户名: ");
// 使用 fgets 读取一行,包括空格,并自动在末尾添加 '\0'
// 注意:fgets 会读取换行符 '\n',需要手动去除
if (fgets(username, sizeof(username), stdin) != NULL) {
// 去除可能读取到的换行符
size_t len = strlen(username);
if (len > 0 && username[len - 1] == '\n') {
username[len - 1] = '\0';
}
} else {
// 输入错误,例如 EOF
printf("输入错误!程序退出。\n");
return 1;
}
// 输入密码
printf("请输入密码: ");
if (fgets(password, sizeof(password), stdin) != NULL) {
size_t len = strlen(password);
if (len > 0 && password[len - 1] == '\n') {
password[len - 1] = '\0';
}
} else {
printf("输入错误!程序退出。\n");
return 1;
}
// 使用 strcmp 比较字符串
// strcmp 返回 0 表示两个字符串相等
if (strcmp(username, CORRECT_USERNAME) == 0 && strcmp(password, CORRECT_PASSWORD) == 0) {
printf("登录成功!欢迎, %s!\n", username);
loginSuccess = 1; // 设置成功标志
break; // 跳出循环
} else {
printf("用户名或密码错误!");
// 如果不是最后一次尝试,提示剩余次数
if (attempts < MAX_ATTEMPTS) {
printf(" 还有 %d 次机会。\n", MAX_ATTEMPTS - attempts);
} else {
printf(" 您已用完所有尝试机会。\n");
}
}
}
// 循环结束后,检查是否成功登录
if (!loginSuccess) {
printf("登录失败!系统已锁定或退出。\n");
}
return 0;
}
-
输入处理:
- 使用?
fgets
?而不是?scanf("%s", ...)
。fgets
?可以安全地读取包含空格的字符串,并且能防止缓冲区溢出(因为它会限制读取的字符数)。 fgets
?会将用户输入的换行符?\n
?也读入字符串。因此,需要检查字符串末尾是否有?\n
,如果有就用?\0
?替换它,以正确终止字符串。
- 使用?
-
字符串比较:
- 使用?
strcmp
?函数比较两个字符串。如果两个字符串完全相同,strcmp
?返回 0。
- 使用?
?3.100块钱换成50,20,10,5块的零钱有多少种方法
解题思路:
- 设50元纸币的数量为?
a
- 设20元纸币的数量为?
b
- 设10元纸币的数量为?
c
- 设5元纸币的数量为?
d
我们需要满足:
50a + 20b + 10c + 5d = 100
且 a, b, c, d
都是非负整数(即 ≥ 0)。
#include <stdio.h>
int main() {
int amount = 100;
int d50, d20, d10, d5; // 分别表示50,20,10,5元的数量
int combination = 0; // 组合计数
printf("所有可能的换零钱方式:\n");
// 枚举50元的数量(最多2张)
for (d50 = 0; d50 <= amount / 50; d50++) {
// 枚举20元的数量(基于剩余金额)
for (d20 = 0; d20 <= (amount - d50 * 50) / 20; d20++) {
// 枚举10元的数量
for (d10 = 0; d10 <= (amount - d50 * 50 - d20 * 20) / 10; d10++) {
// 计算5元的数量
d5 = (amount - d50 * 50 - d20 * 20 - d10 * 10) / 5;
// 检查是否正好兑换完(即余数为0)
if (d5 * 5 == amount - d50 * 50 - d20 * 20 - d10 * 10) {
combination++;
printf("%d: 50元×%d, 20元×%d, 10元×%d, 5元×%d\n",
combination, d50, d20, d10, d5);
}
}
}
}
printf("总共 %d 种换法。\n", combination);
return 0;
}
4. 输入1-12数字,显示对应月份,和月份缩写
#include <stdio.h>
int main() {
// 定义月份名称和缩写的数组
const char* monthNames[] = {
"January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"
};
const char* monthAbbreviations[] = {
"Jan", "Feb", "Mar", "Apr",
"May", "Jun", "Jul", "Aug",
"Sep", "Oct", "Nov", "Dec"
};
int month;
printf("请输入一个月份数字 (1-12): ");
if (scanf("%d", &month) != 1) {
printf("输入错误!请输入一个有效的数字。\n");
return 1;
}
// 检查输入的数字是否在有效范围内
if (month < 1 || month > 12) {
printf("错误:月份数字必须在 1 到 12 之间!\n");
return 1;
}
// 注意:数组索引从 0 开始,所以月份 1 对应索引 0
int index = month - 1;
// 输出结果
printf("月份 %d 对应的完整名称是: %s\n", month, monthNames[index]);
printf("月份 %d 对应的缩写名称是: %s\n", month, monthAbbreviations[index]);
return 0;
}
-
数组定义:
monthNames[]
: 一个字符串指针数组,存储了 12 个月份的完整英文名称。monthAbbreviations[]
: 另一个字符串指针数组,存储了 12 个月份的三字母缩写。- 使用?
const char*
?类型,因为这些字符串是常量,不应被修改。
-
输入处理:
- 使用?
scanf("%d", &month)
?读取用户输入的整数。 - 检查?
scanf
?的返回值(应为 1),以确保输入的是一个有效的整数。如果输入非数字(如字母),scanf
?会失败,返回值不为 1。
- 使用?
?5.机选一注双色球
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define RED_BALLS 6 // 红球数量
#define RED_MAX 33 // 红球最大号码
#define BLUE_MAX 16 // 蓝球最大号码
// 生成不重复的随机数(用于红球)
int generateUniqueRandom(int* used, int count, int max) {
int num;
do {
num = rand() % max + 1; // 生成 1 到 max 的随机数
} while (used[num]); // 如果这个数已经被使用过,重新生成
used[num] = 1; // 标记这个数已被使用
return num;
}
// 简单的冒泡排序(将红球按从小到大排序)
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main() {
// 初始化随机数种子,确保每次运行结果不同
srand((unsigned int)time(NULL));
int redBalls[RED_BALLS]; // 存储红球号码
int used[RED_MAX + 1] = { 0 }; // 标记红球号码是否已使用(索引0不用)
int blueBall; // 存储蓝球号码
printf("机选双色球号码:\n");
// 生成6个不重复的红球
for (int i = 0; i < RED_BALLS; i++) {
redBalls[i] = generateUniqueRandom(used, i, RED_MAX);
}
// 打印红球(未排序)
printf("生成的红球红球:");
for (int i = 0; i < RED_BALLS; i++) {
printf("%02d ", redBalls[i]); // %02d 确保输出两位数,不足前面补0
}
printf("\n\n\n红球:");
// 将红球按从小到大排序
bubbleSort(redBalls, RED_BALLS);
// 打印红球
for (int i = 0; i < RED_BALLS; i++) {
printf("%02d ", redBalls[i]); // %02d 确保输出两位数,不足前面补0
}
// 生成蓝球(可以重复,但双色球规则蓝球独立于红球,所以直接生成1-16即可)
blueBall = rand() % BLUE_MAX + 1;
// 打印蓝球
printf(" 蓝球:%02d\n", blueBall);
printf("祝您好运!\n");
//memset 是 C 标准库函数(<string.h>),用于将一块内存区域设置为特定的值
memset(used, 0, sizeof(used));
size_t c = sizeof(used) / sizeof(used[0]);
for (int i = 0; i < c; i++) {
printf("%02d ", used[i]); // %02d 确保输出两位数,不足前面补0
}
return 0;
}
-
随机数生成:
- 使用?
srand(time(NULL))
?初始化随机数种子,确保每次运行程序产生的随机序列不同。 - 使用?
rand()
?函数生成随机数。
- 使用?
-
红球生成:
- 使用?
generateUniqueRandom
?函数确保生成的6个红球号码不重复。 - 该函数使用一个布尔数组?
used
?来跟踪哪些号码已经被选中。如果生成的随机数已被使用,则重新生成,直到得到一个未使用的号码。
- 使用?
-
排序:
- 使用简单的冒泡排序算法?
bubbleSort
?将生成的6个红球号码按从小到大的顺序排列,符合彩票公布号码的惯例。
- 使用简单的冒泡排序算法?
-
蓝球生成:
- 蓝球是从1-16中独立选择的,与红球号码是否重复无关(规则允许红球和蓝球号码相同,但通常分开看待)。这里直接生成一个1-16之间的随机数。
-
格式化输出:
- 使用?
%02d
?格式化输出,确保号码显示为两位数(例如,5
?显示为?05
),看起来更整齐。
- 使用?