13.c语言完结练习

1.输入一个整数并按逆序输出

  1. 输入整数:使用 scanf 读取用户输入的整数。
  2. 处理数字:使用循环和取模(%)、整除(/)操作来逐位提取数字,打印逆序后的数字。
#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.允许用户最多输入三次用户名和密码,判断是否与预设的值匹配。

  1. 核心逻辑

    • 使用 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;
}
  1. 输入处理

    • 使用 fgets 而不是 scanf("%s", ...)fgets 可以安全地读取包含空格的字符串,并且能防止缓冲区溢出(因为它会限制读取的字符数)。
    • fgets 会将用户输入的换行符 \n 也读入字符串。因此,需要检查字符串末尾是否有 \n,如果有就用 \0 替换它,以正确终止字符串。
  2. 字符串比较

    • 使用 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;
}
  1. 数组定义

    • monthNames[]: 一个字符串指针数组,存储了 12 个月份的完整英文名称。
    • monthAbbreviations[]: 另一个字符串指针数组,存储了 12 个月份的三字母缩写。
    • 使用 const char* 类型,因为这些字符串是常量,不应被修改。
  2. 输入处理

    • 使用 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;
}

  1. 随机数生成

    • 使用 srand(time(NULL)) 初始化随机数种子,确保每次运行程序产生的随机序列不同。
    • 使用 rand() 函数生成随机数。
  2. 红球生成

    • 使用 generateUniqueRandom 函数确保生成的6个红球号码不重复
    • 该函数使用一个布尔数组 used 来跟踪哪些号码已经被选中。如果生成的随机数已被使用,则重新生成,直到得到一个未使用的号码。
  3. 排序

    • 使用简单的冒泡排序算法 bubbleSort 将生成的6个红球号码按从小到大的顺序排列,符合彩票公布号码的惯例。
  4. 蓝球生成

    • 蓝球是从1-16中独立选择的,与红球号码是否重复无关(规则允许红球和蓝球号码相同,但通常分开看待)。这里直接生成一个1-16之间的随机数。
  5. 格式化输出

    • 使用 %02d 格式化输出,确保号码显示为两位数(例如,5 显示为 05),看起来更整齐。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chxii

小小打赏,大大鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值