《编码checklist规范》--学习笔记

1. 排版

排版
图片网址

2. 注释

  • 函数头注释范例
/**
* 发送数据给服务器
* @param [in]buf 数据缓冲区指针
* @param len 数据长度
* @return <0 表示失败,否则表示实际发送成功的字节数
* @sample
* int len = send_buf(buf, buflen);
* if (len < 0) {
* DUMP("send failed, errno: %x\n", len);
* return -1;
* } else {
* DUMP("send ok, already send %d bytes.\n", len);
* }
*/
int send_buf(const char* buf, int len);
  • 文件头注释范例
/*
功能:本文件定义文件列表的接口,文件列表是个存储文件路径名和文件信
息的列表,本文件提供了文件列表的存储、读取、定位、访问等接口。
日期:2011-3-4
作者:zbc
*/
#ifndef FILELIST_H_
#define FILELIST_H_#endif //FILELIST_H_
  • 类型定义注释
/**
* 文件列表类
* @remark
* 可用于记录系统所缓存的所有小文件,该列表可存在磁盘上
* @note
*/
class filelist {
...
};
  • 全局变量注释
char g_log_fname[MAX_PATH]; //日志文件的路径名称,从配置文件中读取得到
//日志文件的路径名称,从配置文件中读取得到
char g_log_fname[MAX_PATH];
  • 宏注释
/**
* 释放内存,并把指针清零,防止重复释放
* @param ptr 内存块指针,只允许传入 malloc/remalloc/strdup 等
* C 库函数分配的内存块指针
*/
#define FREE_ZERO(ptr) \
do{                    \
if (!(ptr)) {          \
free(ptr);             \
ptr = NULL;            \
}                      \
}while(0)
// 最大的缓冲区长度
#define MAX_BUF_SIZE 200
  • 语句注释
-----------
// 将所有用户配置文件打包
pdir = opendir("/var/sangfor");
if (!pdir) {
...
return -1;
}
// 遍历/var/sangfor 目录下所有配置文件(*.conf),通过 tar 命令将其打到压缩包
while ((pcur = readdir(pdir)) != NULL) {
...
}

注释
图片链接

3. label - - 标识符

  • 一个变量多个用途:一个实际引起了 BUG 的例子:value 既作为入参表示哈希值,又作为出参,表示是否成功
#define HASH_INSERT(hash_table, node, value, type)     \
do {                                                   \
    node->pre = NULL;                                  \
    node->pnext = NULL;                                \
    unsigned int h_i_i = value % HASH_SIZE;            \
    if (hash_table[h_i_i] != NULL &&                   \
        hash_table[h_i_i]->key != node->key) {         \
        ...                                            \
    }else if (hash_table[h_i_i] == NULL) {             \
        hash_table[h_i_i] = node;                      \
    } else {                                           \
        value = 0;                                     \
    }                                                  \
} while (0);
  • 提供给 c 模块使用的函数原型声明
#ifdef __cplusplus
extern "C" {
#endif
void foo(int xxx, int yyy);
#ifdef __cplusplus
}
#endif

label
图片链接

4. 函数

  • 以下函数声明违反 checklist
1) void func(string name);
2) struct record {
int type;
int len;
char data[16];
};
void send_record(record rec);
  • 函数参数中使用布尔类型,会使代码更难以理解,如
UpdateData(TRUE)
CreateProcess(chPath, "", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)
如果不是对这些函数非常熟悉,你知道这些 TRUEFALSE 代表什么意思吗?如 果 改 为
 UpdateData(SAVE_VALIDATE) , 
 CreateProcess(chPath, "", NULL, NULL,NO_INHERIT_HANDLE, 0, NULL, NULL, &si, &pi)
改造方法:
UpdateData 是 MFC 函数,原型如下:
BOOL UpdateData(BOOL bSaveAndValidate);
下述修改方法都可以提高 UpdateData 的可读性:
1)分拆成两个函数实现
BOOL UpdateData();
BOOL UpdateData_SaveAndValidate();
2)将 bSaveAndValidate 参数改造成枚举
enum SaveAndValidate_e{
SAVE_VALIDATE,
NO_SAVE_VALIDATE
};
BOOL UpdateData(enum SaveAndValidate_e eSave);
这样,在调用这个函数时就有一个名字了,可以通过枚举的名字更好的理解这个函数调用的意思,
如:UpdateData(SAVE_VALIDATE);
  • 以上代码违反子条款 3,sizeof(arr)的结果为 sizeof(int)
void test_arr_copy(int arr[ARRAY_SIZE])
{
    int buf[ARRAY_SIZE];
    memcpy(buf, arr, sizeof(arr));
}
  • 非 GCC 编译环境的处理方法
vc 等编译器不支持__attribute__扩展编译指令。为了保证代码的跨平台能力,可以在非 GCC 编译
环境下加上如下代码:
#if !defined(__GNUC__)
#define __attribute__(x)
#endif
这样可以保证使用了__attribute__扩展编译选项的代码能够顺利在 VC 下编译
  • format 指令的参数该怎么定
Format 指令有三个参数:format(printf,fmt_pos,args_pos),此处固定第一个参数为 printf,第二
个参数为格式串参数在函数参数列表中的位置(位置计数从 1 开始),第三个参数为变参开始的位置。
如:
void my_print(int fd, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
表示声明 my_print 为类 printf 函数,my_print 的第二个参数为格式串,变参列表从第三个参数开始。
  • 成员函数
如果类 printf 函数是一个类的成员函数,format 指令中的位置参数必须加 1(即把 this 作为该函
数的第一个参数),如:
class strings {
void print(int fd, const char *fmt, ...) __attribute__((format(printf,3,4)));
};

函数
图片链接

5. 宏定义

宏定义
图片链接

6. 结构体

结构体
图片链接

7. 语句

这里写图片描述
图片链接

8. 错误处理

错误处理
图片链接

猜你喜欢

转载自blog.csdn.net/qq_36337149/article/details/80423477