C 语言的编码风格对于编写清晰、可维护、易于调试的代码至关重要。本文将结合 ISO/IEC 9899:2024 (N3220) 标准(即 C23 标准)和 Linux 内核编码风格 v6.13.0-rc4,全面讲解 C 语言编码规范。这两个文献代表了行业中的两个重要编码风格,本文将结合它们的规则和最佳实践进行对比分析,并提供代码示例。
编码风格 | 规则 |
---|---|
C23 标准 | 推荐使用 4 个空格,但可根据团队约定进行调整。 |
Linux 内核风格 | Tab(制表符) 缩进,每一级缩进为 8 个字符。 |
规范出自:
示例:
Linux 内核风格:
if (condition) {
do_something();
} else {
do_something_else();
}
C23 标准(建议):
if (condition) {
do_something();
} else {
do_something_else();
}
编码风格 | 规则 |
---|---|
C23 标准 | 二元运算符(如 +、-、== 等)两边应加空格。 |
Linux 内核风格 | 与 C23 标准相同,但特别注意 sizeof、alignof 等关键字后不加空格。 |
规范出自:
示例:
Linux 内核风格:
s = sizeof(struct file); // sizeof 后不加空格
a = b + c; // 运算符两侧加空格
C23 标准(建议):
s = sizeof(struct file); // sizeof 后不加空格
a = b + c; // 运算符两侧加空格
编码风格 | 规则 |
---|---|
C23 标准 | 建议每行不超过 100 个字符。但 79 个字符 更为常见。 |
Linux 内核风格 | 严格要求每行 不超过 80 个字符。 |
规范出自:
示例:
Linux 内核风格:
printf("This is a long line, which should be broken into two lines "
"to avoid exceeding the 80-character limit.");
C23 标准(建议):
printf("This is a long line, which should be broken into two lines "
"to avoid exceeding the 100-character limit.");
编码风格 | 规则 |
---|---|
C23 标准 | 推荐使用 小写字母 和 下划线(snake_case)。 |
Linux 内核风格 | 使用 小写字母 和 下划线,并确保命名简洁描述性。 |
规范出自:
示例:
Linux 内核风格:
int max_buffer_size;
C23 标准(建议):
int max_buffer_size;
编码风格 | 规则 |
---|---|
C23 标准 | 宏名应使用 大写字母 和 下划线(UPPER_SNAKE_CASE)。 |
Linux 内核风格 | 宏名应使用 全大写字母 和 下划线。 |
规范出自:
示例:
Linux 内核风格:
#define MAX_BUFFER_SIZE 1024
C23 标准(建议):
#define MAX_BUFFER_SIZE 1024
编码风格 | 规则 |
---|---|
C23 标准 | 结构体成员按顺序列出,类型对齐。 |
Linux 内核风格 | 结构体成员应按内存对齐要求排列。 |
规范出自:
示例:
Linux 内核风格:
struct file {
struct inode *inode;
unsigned long f_flags;
char *f_path;
};
C23 标准(建议):
struct file {
struct inode *inode;
unsigned long f_flags;
char *f_path;
};
编码风格 | 规则 |
---|---|
C23 标准 | 枚举成员应使用 大写字母,单词间使用下划线。 |
Linux 内核风格 | 枚举成员应使用 大写字母,单词间使用下划线。 |
规范出自:
示例:
Linux 内核风格:
enum file_flags {
O_RDONLY,
O_WRONLY,
O_RDWR
};
C23 标准(建议):
enum file_flags {
O_RDONLY,
O_WRONLY,
O_RDWR
};
编码风格 | 规则 |
---|---|
C23 标准 | 二元运算符两边加空格;一元运算符前后不加空格。 |
Linux 内核风格 | 同 C23 标准,但特别强调 sizeof、alignof 等关键字后不加空格。 |
规范出自:
示例:
Linux 内核风格:
s = sizeof(struct file); // sizeof 后不加空格
a = b + c; // 运算符两侧加空格
C23 标准(建议):
s = sizeof(struct file); // sizeof 后不加空格
a = b + c; // 运算符两侧加空格
编码风格 | 规则 |
---|---|
C23 标准 | 单行注释使用 //,注释内容简洁清晰。 |
Linux 内核风格 | 单行注释使用 //,紧跟在代码后面。 |
规范出自:
示例:
Linux 内核风格:
int value = 10; // 设置初始值为10
C23 标准(建议):
int value = 10; // 设置初始值为10
编码风格 | 规则 |
---|---|
C23 标准 | 使用 /* 和 */ 包裹多行注释,并尽量简洁明了。 |
Linux 内核风格 | 多行注释应避免过度嵌套,保持清晰简洁,使用 /* 和 */。 |
规范出自:
示例:
Linux 内核风格:
/*
* 这是一个多行注释,描述代码的功能。
* 这里继续说明该部分代码的作用。
*/
C23 标准(建议):
/*
* 这是一个多行注释,描述代码的功能。
* 这里继续说明该部分代码的作用。
*/
编码风格 | 规则 |
---|---|
C23 标准 | 函数定义时,返回类型和函数名之间应有一个空格。参数列表应紧跟在函数名之后,若参数超过一行,应缩进。 |
Linux 内核风格 | 同 C23 标准,且建议函数名前加下划线以表示其为内核私有函数(如果适用)。 |
规范出自:
示例:
Linux 内核风格:
static int my_function(int a, int b)
{
return a + b;
}
C23 标准(建议):
int add(int a, int b)
{
return a + b;
}
编码风格 | 规则 |
---|---|
C23 标准 | if、else 等语句的花括号({})应始终使用,即使代码块仅包含一条语句。 |
Linux 内核风格 | 与 C23 标准相同,要求花括号 {} 即使只有一条语句也要写上。 |
规范出自:
示例:
Linux 内核风格:
if (condition) {
do_something();
} else {
do_something_else();
}
C23 标准(建议):
if (condition) {
do_something();
} else {
do_something_else();
}
编码风格 | 规则 |
---|---|
C23 标准 | 错误处理应尽量使用标准库函数,如 perror()、strerror(),并适当返回错误码。 |
Linux 内核风格 | 使用 pr_err() 等内核函数输出错误信息,并使用适当的错误码(如 -EINVAL)。 |
规范出自:
示例:
Linux 内核风格:
if (error_condition) {
pr_err("Error occurred: %d\n", error_code);
return -EINVAL;
}
C23 标准(建议):
if (error_condition) {
perror("Error occurred");
return -1;
}
编码风格 | 规则 |
---|---|
C23 标准 | 使用 malloc() 和 free() 进行内存分配和释放,确保分配成功后处理错误。 |
Linux 内核风格 | 使用内核专用的 kmalloc() 和 kfree() 进行内存管理。 |
规范出自:
示例:
Linux 内核风格:
int *ptr = kmalloc(sizeof(int) * 10, GFP_KERNEL);
if (!ptr) {
pr_err("Memory allocation failed\n");
return -ENOMEM;
}
kfree(ptr);
C23 标准(建议):
int *ptr = malloc(sizeof(int) * 10);
if (ptr == NULL) {
perror("Memory allocation failed");
return -1;
}
free(ptr);
C 语言的编码风格标准在许多方面有相似之处,特别是在变量命名、函数定义、注释和代码结构方面。ISO/IEC 9899:2024 (N3220)(即 C23 标准)提供了一些通用的编码建议,而 Linux 内核编码风格 则更多关注内核代码的性能和可维护性。
//
和 /* */
,强调简洁明了。这些规范可以帮助开发者编写更整洁、易于阅读和维护的 C 语言代码,特别是在多团队协作的项目中。