思路
当前的poker工程还能进一步改进:把只与扑克相关的各种声明和定义单独拿出来,放到单独的文件中;把只与玩家相关的东西拿出来,放到单独的文件中,而main函数里只是使用这些定义或声明,于是变成了三个文件:poker.c、player.c,main.c。这样带来什么好处呢?一是要查看或修改poker相关的功能,我们只需打开poker.c。现在由于程序小,感觉不出分开的优势,但当写一个程序要处理几十上百种结构时,如果不分开,面对一个上万行代码的main文件,相信一般人都会头晕。二是当别人要写一个poker游戏时,发现我们的poker.c中已经把操作一副牌的功能都实现了,于是他们只需把poker.c文件复制到自己的工程中用就ok了。通过分散到多个文件中,我们提高了代码的可维护性和可重用性。
下面我们就来研究一下代码中的东西该归各处:
card结构,表示一张牌,肯定要放到poker.c中。 定义一副牌数量的宏card_count只与扑克有关,放到poker.c中。 定义poker花色的枚举,与宏card_count一样,放到poker.c中。 比较函数,只与扑克相关,放到poker.c中。 比较函数类型定义,跟着比较函数走,放到poker.c中。 构造一副牌的函数initonepack,放到poker.c中。 洗牌函数shuffle,只操作card结构,放到poker.c中。 排序函数,只排扑克的序,放到poker.c中。 获取牌免费精选名字大全的函数,只操作扑克,放到poker.c中。 结构player,肯定放到player.c中。 存放原始一副牌的数组pokers,放到poker.c中。 分牌函数,操做了player和card两个结构,放在main.c中可以, 是从人思维角度讲,是人发牌,所以把它放到 player.c中也没问题。这个随意吧,但是我个人的话感觉放到player.c文件中比较好,所以我放到player.c中。 函数声明们跟着函数定义走。
现在是不是可以在main.c里include这两个文件然后就能编译出结果呢?有个问题先说明一下:c文件也是可以被include的,因为include的实质就是将被include的文件的内容复制到include行的位置。但include之后会产生一大堆错误,编译是不会成功的。这些错误的描述大都是说类型或标志符重复定义。这些错误是怎么造成的,后面再说,先说怎么解决。解决方法很简单:将poker.c和player.c从编译中排除,即不再编译poker.c和player.c。它们的内容会被插入main.c中,形成完整的main.c,此时poker.c和player.c不需要编译了。如果编译的话,就会产生重复定义,其原因后面的“编译过程详解”(请期待)一节有解释。所以要把这两个文件从工程中删掉,但不能删除实际的文件哦,只是从工程中删除对它们的引用,如果删掉了实际的文件,include就是找不到文件了。
删除一个文件的引用,在qtcreator中是这样的,如图,不要选中check按钮:
现在三个文件是这样的:
poker.c
#include //一副牌的数量 #define card_count 54 //定义扑克的花色 enum suit{ heart, spade, diamond, club, joker1, joker2 }; //定义扑克 typedef struct card{ int value;//牌的点数从1开始 enum suit suit;//花色 }card; //定义比较函数的类型 typedef int (*compare)(card* ,card*); //原始一副牌所在的数组 card pokers[card_count]; //构造一副牌 void initonepack(){ int i=0; //前52张 for(;ivalue > b->value){ return 1; }else if(a->value < b->value){ return 0; }else{ if(a->suit > b->suit) return 1; else return 0; } } //比较函数,先比较点数再比较花色 int compare2(card* a,card* b){ if(a->value > b->value){ return 0; }else if(a->value < b->value){ return 1; }else{ if(a->suit > b->suit) return 0; else return 1; } } //获取牌的免费精选名字大全 //返回牌的免费精选名字大全字符串,调用者用完后需要free()之。 char* getcardname(const card* card){ //存放花色免费精选名字大全 char suitstr[16]={0};//0=='