上次在用函式来传达你的心意> 0 <中我们把while迴圈内在做什么用函式名称诠释出来,看起来像是在阅读一篇文章一样,这次让我带你看main里面还有什么可以改进的部分,让整个main更直觉好懂。
第一眼我看见的是seats[10]这个阵列宣告长度的数值,10在很多地方用到而且这个数字是在这个範例内永远是固定值,所以我们可以用一个叫做size来取代他,也方便我们之后长度修改,再来看到宣告变数i, j的地方,由于我们之前把函式切割出去了,这两个变数就不需要存在。
int main(){ int seats[10] = {99, 0, 10, 31, 0, 42, 70, 67, 0, 0}; int i, j, seat, number; showSeats(seats, 10); getUserInput(seat, number); while(number != 0){ if(seats [seat - 1] == 0){ seats[seat - 1] = number; showSeats(seats, 10); getUserInput(seat, number); } else{ printf("Sorry, seat is taken.\n"); scanf("%d %d", &seat, &number); } } bubble_sort(seats, 10); showSeats(seats, 10); printf("\n"); printf("***************\n"); return 0;}
变数宣告这个区块我感觉上是差不多了,你有其他想法也欢迎提出来跟我讨论^ ^,再来我想往提示使用者输入这整个区块来做个修改,让我帮你切割出我说的地方。
int main(){ const int size = 10; int seats[size] = {99, 0, 10, 31, 0, 42, 70, 67, 0, 0}; int seat, number; showSeats(seats, size); getUserInput(seat, number); while(number != 0){ if(seats [seat - 1] == 0){ seats[seat - 1] = number; showSeats(seats, size); getUserInput(seat, number); } else{ printf("Sorry, seat is taken.\n"); scanf("%d %d", &seat, &number); } } bubble_sort(seats, size); showSeats(seats, size); printf("\n"); printf("***************\n"); return 0;}
提示使用者输入这整个区块的流程可以分成几点:
显示所有位置资讯输入位置索引和号码判断位置是否合法然后塞值判断是否继续输入(使用者输入数字不等于0)首先第1点和第2点我们已经有了分别是showSeats和getUserInput,3和4我想再加两个新函式,分别式isSeatValid跟isContinueInput,我们可以用这几个函式来重新组织看看。
showSeats(seats, size); getUserInput(seat, number); while(number != 0){ if(seats [seat - 1] == 0){ seats[seat - 1] = number; showSeats(seats, size); getUserInput(seat, number); } else{ printf("Sorry, seat is taken.\n"); scanf("%d %d", &seat, &number); } }
太棒了!!看看我们修改后的成果,整个区块越来越精简了,而且阅读性增加更多,试着一行一行过去就像看文章一样,他要做的事情就跟你想得差不多,这是让人觉得最舒服的程式码。
原本的while迴圈我更换成do...while,因为使用者是先输入才判断之后要做的事,do...while会更符合整个流程概念,让我们把整个修改结果整个合併一下。
do{ showSeats(seats, size); getUserInput(seat, number); if(isSeatValid(seats, size, seat)){ seats[seat - 1] = number; } }while(isContinueInput(number));
void showSeats(int seats[], int size){ printf("*seating*\n"); for(int i = 0; i < size; ++i){ printf("%d ", seats[i]); }}void getUserInput(int& seat, int& number){ printf("\n"); printf("***************\n"); printf("Please input the seat (0~9) and number(-1 to end game)\n"); scanf("%d %d", &seat, &number);}bool isSeatValid(int seats[], int size, int seat){ if(seat - 1 < 0 || seat - 1 >= size){ printf("Sorry, seat is invalid.\n"); return false; } if(seats[seat - 1] != 0){ printf("Sorry, seat is taken.\n"); return false; } return true;}bool isContinueInput(int number){ return number != 0;}int main(){ const int size = 10; int seats[size] = {99, 0, 10, 31, 0, 42, 70, 67, 0, 0}; int seat, number; do{ showSeats(seats, size); getUserInput(seat, number); if(isSeatValid(seats, size, seat)){ seats[seat - 1] = number; } }while(isContinueInput(number)); bubble_sort(seats, size); showSeats(seats, size); printf("\n"); printf("***************\n"); return 0;}
到这边你可能会对isContinueInput有个疑问,这个函式里面只有一行有需要为了这一行新增一个函式吗?没错很多人会觉得没有必要,对我自己来说number != 0这行没办法直接说明他到底想做什么,我必须切换我的思维才能了解这是根据使用者输入数字来决定要不要继续,思维上的转换会导致分心,在看main的时候我只想专注在抽象的想法上,而不是实作细节,这会帮助我减少理解程式码所花的时间,相信也可以帮助其他看程式码的人,要记住你一定会跟别人一起合作写程式码,能够为别人多做一点都是值得的。
整个重新架构的部分就先到这里,你可以回头看这篇变数命名的善意来比较看看阅读性上的差异,相信你会感受很深,很感谢你这么有耐心看到最后,过程中可能有些讲解上不太明确的部分都欢迎留言告诉我,或是你有任何想法也都欢迎,之后还有其他可以重新修正的程式码範例我也会继续分享给你,让我们继续往更美好程式码迈进,我们下次见 ^ ^