1、C#
1.1 注释#
按照 C 语言风格,使用
/* */添加注释,不使用//
.c文件头注释
/*
* Copyright (c) 2022, The xxx project authors. All Rights Reserved.
* SPDX-License-Identifier: MIT
*
* First Created :
* Author : nanche
* Description : 文件级注释应该广泛/简单地描述文件的内容,以及抽象是如何相关的
*/.h文件头注释
/*
* Copyright (c) %YEAR%, The xxx project authors. All Rights Reserved.
* SPDX-License-Identifier: MIT
*
* First Created : %DATE%
* Author : nanche <%MAIL%>
* Description :
*/
#ifndef %GUARD%
#define %GUARD%
#endif函数注释
参数命名写清楚含义,前面可以加 IN/OUT,不需要在函数注释中添加过多重复信息。
注释说明代码做了什么,而不是如何做
/*
* 函数功能、实现大致思路、需要注意的点
* 需要特别注意的参数
* 函数是否分配了必须由调用者释放的空间.
* 参数是否可以为空指针.
* 是否存在函数使用上的性能隐患.
*/TODO 注释
/*
* TODO:
*/1.2 C 工程结构#
├── build.sh
├── LICENSE
├── Makefile
├── README
├── .gitignore
├── 3rdparty/
├── build/
│ ├── debug/
│ └── release/
├── doc/
├── examples/
├── src/
│ ├── main.c
│ ├── include/
│ └── type_pub.h
│ ├── module_1/
│ │ ├── cps.c
│ │ └── cps.h
│ └── module_2/
├── scripts/
└── test/公共头文件放在 src/include 目录下,文件结尾加 pub
在
3rdparty/下存放的工程中用到的第三方库和第三方源码。第三方库尽量不要直接把静态连接库直接放到git仓库中,应该另外提供链接以便下载,或者提供文档说明库的名称和版本自行安装下载,或者提供git仓库自行编译。第三方源码一般为开源的,只提供git链接。TODO:日志文件/文件夹
1.3 公共头文件#
类型定义 type_pub.h
#include <stdint.h>
#ifnedf IN
#define IN
#endif
#ifnedf OUT
#define OUT
#endif
#ifnedf INOUT
#define INOUT
#endif1.4 命名规范#
变量命名:Linux 标准风格,小写字母加下划线
宏命名:模块名_功能名
复杂数据类型:全部为大写字母,结尾用 S 表示结构体,U 表示联合体,E 表示枚举
typedef struct PPP_CB
{
uint32_t c_p;
...
}PPP_CB_S;
typedef union SNMP_CMD
{
uint8_t cmd;
...
}SNMP_CMD_U;
typedef enum SNMP_ERR
{
err_1;
err_2;
}SNMP_ERR_E;1.5 其他规范#
Linux 下括号 {和}的使用原则如下:
- if、else、for、do、while、switch、case、default 等语句各自占一行,其后语句一律用
{}括起来,哪怕只有一行 - 大括号自己独占一行
Linux 空格的使用方式主要取决于它是函数还是关键字。大多数关键字后要加空格:
if, switch, case, for, do, while但是不要在 sizeof、typeof、alignof 这些关键字后加空格:
s = sizeof(struct file)不要在小括号里的表达式两边加空格。
当声明指针类型或者返回指针类型的函数时, * 的首选使用方式是使之靠近变量名或者函数名,而不是靠近类型名:
char *linux_banner;
unsigned long long memparse(char *ptr, char **retptr);
char *match_strdup(substring_t *s);二元运算符两边加空格,一元运算符不加空格(二元运算符:有两个操作数,如 a + b)
对于 switch/case 语句,Linux 建议 switch 和 case 对齐,例如:
switch(suffix){
case 'G':
case 'g':
mem <<= 30;
break;
default:
break;
}如果一个数据结构,在创建和销毁它的单线程执行环境之外可见,那它必须要有一个引用计数器。内核里没有垃圾收集,这意味着你必须要记录对这个数据结构的使用情况。
如果另一个线程中可以拿到该数据结构,但这个数据结构没有引用计数器,那这就是一个 bug。
定义几个相关的常量时,枚举比宏定义更好。
typeof(x) 可以获得 x 的类型
C99 已经支持 __func__ 宏,可以得到当前函数名称。
goto 语句
用不用 goto 语句一直是一个著名的争议话题,Linux 内核源代码中对 goto 的应用非常广泛,但一般只用在错误处理中:
if(register_a() != 0)
goto err;
if(register_b() != 0)
goto err1;
...
err1:
unregister_b();
err:
return ret;需要保证在错误处理时注销、资源释放等,与正常的注册、申请资源释放顺序相反。
2、Python#
文件头注释#
# -*- coding: utf-8 -*-
"""
Copyright (c) 2022, The xxx project authors. All Rights Reserved.
SPDX-License-Identifier: MIT
First Created :
Last Updated :
Author : nanche
Description :
"""