VectorLu

C 语言命名和程序组织

写程序的过程中,最难的事情之一就是命名。

命名

C89 标准指出:
以下划线后跟一个大写字母开头的名字是保留字,程序员不应该使用。

程序组织

单文件

摘自《C 语言程序设计 现代方法》第 10 章。
清楚地讲解了一个程序,从将问题分解为若干任务,初步设计程序的构成,到实现程序的细节的整个过程。

一个单文件的组成顺序通常是:

  1. #include 指令;
  2. #define 指令;
  3. 类型定义;
  4. 外部变量声明;
  5. main() 之外的函数原型;
  6. main() 的定义;
  7. 其他函数的定义。

示例程序:给一手牌分类

背景

在每个函数定义前放盒型注释可以给出函数名、描述函数的目的、讨论每个形式参数的含义、描述返回值(如果有的话)并罗列所有的副作用(如修改了外部变量的值)。例如,给一手牌分类:手中的每张牌都有花色(方块、梅花、红心和黑桃)和等级(2、3、4、5、6、7、8、9、10、J、Q、K、和 A)。不允许使用王牌,并且假设 A 是最高等级的。程序将读取一手 5 张牌,然后把手中的牌分为下列某一类(列出的顺序从最好到最坏)。

  • 同花顺(即顺序相连又都是同花色)。
  • 四张(4 张牌等级相同)。
  • 葫芦(3 张牌是同样的花色,而另外 2 张牌是同样的花色)。
  • 同花(5 张牌是同样花色的)。
  • 顺子(5 张牌的等级顺序相连)。
  • 三张(3 张牌的等级相同)。
  • 两对。
  • 一对。
  • 其他牌

如果一手牌可分为两种或多种类别,程序将选择最好的一种:

为了便于输入,把牌的等级和花色简化如下(字母可以是大写也可以是小写)。

  • 等级:2 3 4 5 6 7 8 9 t j q k a
  • 花色:c d h s

如果用户输入非法牌或者输入同一张牌两次,程序将此牌忽略,产生错误消息,然后要求输入另外一张牌,如果输入为 0 而不是一张牌,就会导致程序终止。

程序任务分析

  • 读入一手 5 张牌;
  • 分析对子、顺子等情况
  • 显示一手牌的分类

把程序分为 3 个函数分别完成上述 3 个任务,即 read_cards()analyse_hand()print_result() 函数。main() 只负责在无限循环中调用这些函数。这些函数需要共享大量的信息,所以让它们通过外部变量来进行交流。read_cards() 将与一手牌相关的信息存进几个外部变量中,然后 analyze_hand() 将检查这些外部变量,把结果分类放在便于 print_result() 函数显示的其他外部变量中。

analyze_hand() 需要知道每个等级和每个花色的牌的数量。建议使用两个数组,即 num_in_ranknum_in_suit。为了便于 read_cards() 函数检查重复的牌,还需要第三个数组 card_exists[][]。每次读取等级为 r 且花色为 s 的牌时,read_cards 函数都会检查 card_exists[r][s]的值是否为 true。如果是,表明已经录入过。如果不是,那么 read_cards() 函数把 true 赋值给 card_exists[r][s]

read_cards()analyze_hand 函数都需要访问数组 num_in_ranknum_in_suit,所以这两个数组必须是外部变量;而数组 card_exists[][] 只用于 read_cards() 函数,所以可将它设为此函数的局部变量。通常只有必要时才把变量设为外部变量。

您的支持将鼓励我继续创作!

热评文章