x86汇编Powerball模拟器问题:宏调用与代码简化求助
Powerball抽奖模拟器:宏数组传参与代码简化方案
一、正确传递数组到宏的方法
宏在预处理阶段直接展开代码,数组作为参数传入时会退化为指针,无法直接获取数组长度,因此必须显式传递数组长度,同时用do-while(0)包裹宏代码避免语法陷阱(比如if分支后不加括号引发的逻辑错误)。
示例宏定义
// 宏参数:用户主号码数组、用户数组长度、开奖主号码数组、开奖数组长度、用户Powerball号、开奖Powerball号 #define CHECK_POWERBALL_WIN(user_nums, user_len, draw_nums, draw_len, pb_user, pb_draw) \ do { \ int main_match = 0; \ // 统计主号码匹配数 for (int i = 0; i < user_len; i++) { \ for (int j = 0; j < draw_len; j++) { \ if ((user_nums[i]) == (draw_nums[j])) { \ main_match++; \ break; \ } \ } \ } \ // 判断Powerball匹配情况 int pb_match = ((pb_user) == (pb_draw)) ? 1 : 0; \ // 输出中奖结果 if (main_match == 5 && pb_match == 1) { \ puts("头奖!恭喜你赢得Powerball大奖!"); \ } else if (main_match == 5) { \ puts("二等奖:匹配5个主号码"); \ } else if (main_match == 4 && pb_match == 1) { \ puts("三等奖:匹配4个主号码+Powerball"); \ } else { \ printf("未中奖,匹配%d个主号码,Powerball%s匹配\n", main_match, pb_match ? "" : "未"); \ } \ } while(0)
宏调用方式
#include <stdio.h> int main() { int user_main[] = {12, 23, 34, 45, 56}; int draw_main[] = {23, 34, 56, 78, 90}; int user_pb = 7; int draw_pb = 7; // 调用宏,传递数组、长度及Powerball号码 CHECK_POWERBALL_WIN( user_main, sizeof(user_main)/sizeof(user_main[0]), draw_main, sizeof(draw_main)/sizeof(draw_main[0]), user_pb, draw_pb ); return 0; }
注意:宏中所有参数引用都加括号(),避免因参数是表达式导致的运算符优先级错误。
二、代码简化方案
1. 用排序+双指针替代双重循环,提升效率与简洁度
把主号码数组排序后,用双指针遍历统计匹配数,比嵌套循环更高效,代码更简洁:
#include <stdio.h> #include <stdlib.h> // 整数比较函数,用于qsort排序 int int_cmp(const void* a, const void* b) { return *(int*)a - *(int*)b; } #define CHECK_POWERBALL_WIN(user_nums, user_len, draw_nums, draw_len, pb_user, pb_draw) \ do { \ qsort(user_nums, user_len, sizeof(int), int_cmp); \ qsort(draw_nums, draw_len, sizeof(int), int_cmp); \ \ int main_match = 0; \ int i = 0, j = 0; \ while (i < user_len && j < draw_len) { \ if ((user_nums[i]) == (draw_nums[j])) { \ main_match++; \ i++; j++; \ } else if ((user_nums[i]) < (draw_nums[j])) { \ i++; \ } else { \ j++; \ } \ } \ \ int pb_match = ((pb_user) == (pb_draw)) ? 1 : 0; \ // 中奖判断逻辑同前... \ } while(0)
2. 封装重复逻辑为辅助函数
将号码生成、用户输入等非核心逻辑封装成函数,让宏只负责核心比对:
// 生成指定范围的不重复随机开奖号码 void generate_draw_numbers(int* nums, int len, int min, int max) { // 实现随机生成+去重逻辑(可结合rand()和循环判断) } // 获取用户输入的号码 void get_user_numbers(int* nums, int len, int min, int max) { printf("请输入%d个主号码(范围%d-%d):", len, min, max); for (int i = 0; i < len; i++) { scanf("%d", &nums[i]); } }
3. 用枚举定义中奖等级,提升代码可读性
typedef enum { NO_WIN, WIN_3, WIN_3_PB, WIN_4, WIN_4_PB, WIN_5, JACKPOT } WinRank;
在宏中根据匹配数映射到对应的枚举值,再输出结果,代码逻辑更清晰易维护。
内容的提问来源于stack exchange,提问作者Kasizah
相关产品推荐
相关产品推荐

