如何为现有C语言测验程序添加rand函数实现随机出题?
给C语言测验程序添加随机出题功能的实现方案
核心思路
要实现随机出题,得先把题目和对应正确答案结构化存储,摆脱硬编码的顺序依赖,再通过随机算法打乱题目顺序,最后按打乱后的顺序出题即可。
具体实现步骤
添加必要头文件
引入stdlib.h(提供rand()和srand()函数)和time.h(用于生成随机种子)。定义题目结构体
把题目内容、选项文本、正确答案封装成结构体,方便批量管理题目:typedef struct { char domanda[200]; char opzioni[4][100]; int risposta_corretta; } QuizDomanda;初始化题目数组
将现有题目填充到结构体数组中,后续新增题目直接追加即可:QuizDomanda domande[] = { { "Secondo il tredicesimo Obiettivo di Sviluppo Sostenibile, la minaccia piu' grande allo sviluppo e'/sono:", {"I cambiamenti climatici", "L'inquinamento", "Lo scioglimento della calotta glaciale polare", "La crescita demografica"}, 1 }, { "Il tempo e il clima sono la stessa cosa.", {"Vero", "Falso"}, 2 } };设置随机种子
在程序开头调用srand(time(NULL)),用当前时间作为随机种子,确保每次运行程序的随机序列都不一样:srand(time(NULL));洗牌算法打乱题目顺序
用Fisher-Yates洗牌算法打乱题目数组,保证每个题被抽到的概率均等:int num_domande = sizeof(domande) / sizeof(domande[0]); for (int i = num_domande - 1; i > 0; i--) { int j = rand() % (i + 1); QuizDomanda temp = domande[i]; domande[i] = domande[j]; domande[j] = temp; }遍历打乱后的题目出题判分
循环遍历打乱后的题目数组,依次显示题目、选项,接收用户输入并判断得分。
完整修改后的代码
#include <stdio.h> #include <stdlib.h> #include <time.h> typedef struct { char domanda[200]; char opzioni[4][100]; int risposta_corretta; } QuizDomanda; int main(void) { int domanda_input, punti = 0; srand(time(NULL)); // 设置随机种子 // 初始化题目数组 QuizDomanda domande[] = { { "D1) Secondo il tredicesimo Obiettivo di Sviluppo Sostenibile, la minaccia piu' grande allo sviluppo e'/sono:", {"I cambiamenti climatici", "L'inquinamento", "Lo scioglimento della calotta glaciale polare", "La crescita demografica"}, 1 }, { "D2) Il tempo e il clima sono la stessa cosa.", {"Vero", "Falso"}, 2 } }; int num_domande = sizeof(domande) / sizeof(domande[0]); // Fisher-Yates洗牌算法打乱题目顺序 for (int i = num_domande - 1; i > 0; i--) { int j = rand() % (i + 1); QuizDomanda temp = domande[i]; domande[i] = domande[j]; domande[j] = temp; } puts("Quiz sul Riscaldamento Globale\n Otterrai 1 punto per ogni risposta esatta e 0 per ogni risposta sbagliata o non valida\n"); // 遍历出题 for (int i = 0; i < num_domande; i++) { puts(domande[i].domanda); puts(""); // 显示选项(跳过空选项) for (int j = 0; j < 4; j++) { if (domande[i].opzioni[j][0] != '\0') { printf("[%d] %s\n", j+1, domande[i].opzioni[j]); } } puts(""); scanf("%d", &domanda_input); if (domanda_input == domande[i].risposta_corretta) { puts("risposta corretta\n"); punti++; } else { puts("risposta sbagliata\n"); } } printf("hai fatto un punteggio di %d su %d", punti, num_domande); return 0; }
关键细节说明
- 结构体的作用:把题目相关数据打包,后续新增题目只需在数组里添加新的结构体元素,不用修改主逻辑代码,扩展性更强。
- 随机种子的必要性:如果不调用
srand(time(NULL)),每次运行rand()都会生成相同的随机序列,随机出题就失去意义了。 - 洗牌算法:Fisher-Yates算法是高效且公平的洗牌方式,时间复杂度为O(n),能保证每个元素的排列概率均等。
内容的提问来源于stack exchange,提问作者franzyk
相关产品推荐
相关产品推荐

