程序变量命名应易于理解。匈牙利命名法是个坏主意。推荐使用CamelCase的各种变体。微软曾建议使用匈牙利命名法,但目前其已经不合时宜。
匈牙利命名法的主要坏处是优秀的编辑环境(不包括Visual C++ 6.0)已经内置类型检查,且当数据类型修改时,变量名将必须改变。且其跨平台性差,“匈牙利命名法在被用作代表多个属性的时候会造成困惑,如 a_crszkvc30LastNameCol:一个常量引用参数,保存了一个varchar(30)类型的数据库列LastName的内容,而这列又是这个表的主键的一部分。(Wikipedia)”。
使用不可读的命名法会对程序的可读性产生致命影响。使用 a, b, c; 拼音首字母例如 xm, xx, bj 等是不推荐的。下面一段程序就是一个反面典型:
int foo(char *a, char *b, float c, char *d) { FILE *m = open(a, "r"); FILE *n = open(b, "w+"); fscanf(a, "%f", &c); fprintf(b, "%s|%f", c, d); return 0; }
程序缩进直接表明程序员的工作态度以及知识水平。如果没有好的编辑环境,程序缩进会常常产生不一致的问题。虽然可以使用 indent 实用程序规范代码,但编写时即产生优秀代码是最佳的选择。下面是一个反面典型:
#include <stdio.h> #include <stdint.h> #include <stdlib.h> #define FILE_PATH "/tmp/anyfile" struct record { uint8_t id; uint8_t type; uint8_t source; char body[32]; }; int main () { struct record any_record = {.id = 2, .type = 4, .source = 33, .body = "Hello"}; uint16_t another_stuff = 12; FILE* that_file; that_file = fopen(FILE_PATH, "w"); if (NULL == that_file) { printf("Sorry, failed to open file.\n"); return -1; } // put an record to the file fwrite(&any_record, sizeof(any_record), 1, that_file); fflush(that_file); fclose(that_file); return 0; }
而下面的代码则有较好的可读性:
#include <stdio.h> #include <stdint.h> #include <stdlib.h> #define FILE_PATH "/tmp/anyfile" struct record { uint8_t id; uint8_t type; uint8_t source; char body[32]; }; int main () { struct record any_record = {.id = 2, .type = 4, .source = 33, .body = "Hello"}; uint16_t another_stuff = 12; // Different compiler have different implementation of int, however uint16_t mitigites such problem FILE* that_file; // Blank line: seperates the declaration and program that_file = fopen(FILE_PATH, "w"); if (NULL == that_file) { // why NULL == that_file? // if the program made a typo of "NULL = that_file", it works actually printf("Sorry, failed to open file.\n"); return -1; } // put an record to the file fwrite(&any_record, sizeof(any_record), 1, that_file); fflush(that_file); fclose(that_file); return 0; }