CS50马里奥(进阶版)C语言代码能否进一步优化重构?
CS50马里奥双列墙代码优化建议
我自主编写了CS50马里奥(进阶难度)的C语言代码,没参与过这门课程,希望把代码重构到最优状态。目前已经将代码拆分为两个函数并在main函数中调用,想咨询这段代码是否还能进一步优化或重构?
代码功能说明
首先获取0到550之间的有效行数输入,然后生成如下样式的马里奥双列墙:
# # ## ## ### ###
原代码
#include <stdio.h> #include <stdlib.h> void build_wall(int num_rows); void get_rows(int n); int rows = 0; int spaces = 0; int bricks = 0; int main(void) { get_rows(rows); build_wall(rows); } void get_rows(int n) { do { printf("How many rows would you like? "); scanf("%d", &rows); printf("\n"); printf("You would like %d rows.\n", rows); } while (rows <= 0 || rows >=550); } void build_wall(int num_rows) { for (int i = 0; i < num_rows; i++) ///number of rows { for(spaces = 0; spaces < num_rows-i-1; spaces++ ) // first spaces { printf(" "); } for(bricks = 0; bricks < i+1; bricks++) // first wall bricks { printf("#"); } { printf(" "); //Middle spaces } for(bricks = 0; bricks < i+1; bricks++) // Second wall bricks { printf("#"); } printf("\n"); } }
优化方向与重构建议
- 移除全局变量:当前代码使用了
rows、spaces、bricks三个全局变量,这会增加代码耦合度,容易引发意外修改。建议全部改为局部变量:get_rows函数不需要参数,直接返回获取到的有效行数;build_wall中的spaces、bricks定义在各自循环内部,作为循环变量使用。
- 优化输入容错性:原代码中
scanf如果读取到非整数输入,会导致输入缓冲区残留无效字符,进而进入死循环。可以添加输入错误处理逻辑,清空缓冲区并提示用户重新输入。 - 明确函数职责:
get_rows的核心职责是获取有效行数,应该通过返回值传递结果,而不是依赖全局变量;当前函数的参数n完全未被使用,直接删除即可。 - 消除重复代码:
build_wall中两次打印#的循环逻辑完全重复,可以提取为一个通用的打印重复字符的函数,比如void print_repeat(char c, int times),减少代码冗余。 - 使用常量增强可读性:把行数的有效范围(1到549)定义为宏常量,比如
#define MIN_ROWS 1、#define MAX_ROWS 549,后续修改范围时只需调整宏定义,代码更易维护。
重构后的示例代码
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #define MIN_ROWS 1 #define MAX_ROWS 549 // 打印指定字符指定次数 void print_repeat(char c, int times) { for (int i = 0; i < times; i++) { putchar(c); } } // 获取有效行数输入 int get_valid_rows(void) { int rows; char ch; do { printf("How many rows would you like? "); // 处理输入错误:如果scanf失败,清空输入缓冲区 if (scanf("%d", &rows) != 1) { // 跳过所有非换行字符 while ((ch = getchar()) != '\n' && ch != EOF); printf("请输入有效的数字!\n"); rows = 0; // 重置为无效值,进入下一轮循环 continue; } printf("\nYou would like %d rows.\n", rows); } while (rows < MIN_ROWS || rows > MAX_ROWS); return rows; } // 构建马里奥双列墙 void build_wall(int num_rows) { for (int i = 0; i < num_rows; i++) { // 打印左侧空格 print_repeat(' ', num_rows - i - 1); // 打印左侧砖墙 print_repeat('#', i + 1); // 打印中间间隔 print_repeat(' ', 2); // 打印右侧砖墙 print_repeat('#', i + 1); // 换行 putchar('\n'); } } int main(void) { int rows = get_valid_rows(); build_wall(rows); return 0; }
内容的提问来源于stack exchange,提问作者David Wyatt
相关产品推荐
相关产品推荐

