image

欢迎大家访问我的个人博客:吴佳轶 | WuJiaYi,第一时间获取最新的文章。

规范制定说明

本套C语言编程规范为提高代码质量、便于维护、协同编码、可移植等特点而编写。要求所有参与编码人员要严格遵循本编程规范。

参考文献:

华为C语言开发编程规范。

阿里巴巴Java开发手册。

【示例】 展示的代码片段,做参考使用。

【原则】 在编写程序时必须严格遵守的规范。

【建议】 在编写程序时需要认真参考的规范。

【粗体】 在规范中特别强调的内容。

标识符命名与定义

建议使用unix like风格给标识符命名,即单词用小写字母,每个单词直接用下划线“_”分割。

例如:text_mutex,test_one,kernel_text_address。

我们对标识符定义主要是为了让团队的代码看起来尽可能统一,有利于代码的后续阅读和修改。标识符的命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。尽可能给出描述性名称,不要节约空间,让别人很快理解你的代码更重要。

【示例】

常见缩写:

buffer 可缩写为 buff

command 可缩写为 cmd

compare 可缩写为 cmp

error 可缩写为 err

initialize 可缩写为 init

maximum 可缩写为 max

message 可缩写为 msg

parameter 可缩写为 para

previous 可缩写为 prev

register 可缩写为 reg

temp 可缩写为 tmp

【示例】

好的命名:

int error_number;

int number_of_completed_connection;

不好的命名:

int n;

int n_comp_conns;

【原则】

除了常见的通用缩写以外,不得使用单词缩写,不得使用汉语拼音。

代码中的命名均不能以下划线开始,也不能以下划线符号结束。

禁止使用单字母命名变量,但允许且仅能定义i、j、k、l作为局部循环变量。

严禁使用未经初始化的变量作为右值。

全局变量应增加“g_”前缀,全局数组应增加“a_”前缀。

【建议】

尽量避免名字中出现数字编号,除非逻辑上的确需要编号。

重构/修改部分代码时,应保持和原有代码的命名风格一致。

常量和宏的定义应该全部大写,多个单词应使用“_”相隔。

变量初始化必须赋予初值。

函数

函数设计的精髓:编写整洁函数,同时把代码有效组织起来。

整洁函数要求:代码简单直接、不隐藏设计者的意图、用干净利落的抽象和直截了当的控制语句将函数有机组织起来。

说明:扇出是指一个函数直接调用(控制)其它函数的数目,而扇入是指有多少上级函数调用它。

设计高扇入,合理扇出(小于7)的函数。扇出过大,表明函数过分复杂,需要控制和协调过多的下级函数;而扇出过小,例如:总是1,表明函数的调用层次可能过多,这样不利于程序阅读和函数结构的分析,并且程序运行时会对系统资源如堆栈空间等造成压力。通常函数比较合理的扇出(调度函数除外)通常是3~5。扇出太大,一般是由于缺乏中间层次,可适当增加中间层次的函数。扇出太小,可把下级函数进一步分解多个函数,或合并到上级函数中。当然分解或合并函数时,不能改变要实现的功能,也不能违背函数间的独立性。

扇入越大,表明使用此函数的上级函数越多,这样的函数使用效率高,但不能违背函数间的独立性而单纯地追求高扇入。公共模块中的函数及底层函数应该有较高的扇入。

较良

【示例】

static void calibrate_run_measurement_overhead(void)

{

u64 T0, T1, delta, min_delta = 1000000000ULL;

int i;

for (i = 0; i < 10; i++)

{

T0 = get_nsecs();

burn_nsecs(0);

T1 = get_nsecs();

delta = T1-T0;

min_delta = min(min_delta, delta);

}

run_measurement_overhead = min_delta;

printf("run measurement overhead: %Ld nsecs\n", min_delta);

}

【原则】

避免函数的代码块嵌套过深,新增函数的代码块嵌套不超过4层。

避免函数过长,新增函数不超过50行(非空非注释行)。

设计高扇入,合理扇出(小于7)的函数。

废弃代码(没有被调用的函数和变量)要及时清除。

【建议】

一个函数仅完成一个功能。

重复代码应该尽可能提炼成函数。

函数的参数个数不超过5个。

关于注释

建议所有变量(包括全局变量)定义语句的上方使用单行注释加以阐述和说明此变量的作用,语言简洁、易懂。最好不要超过一行。

优秀的代码可以自我解释,不通过注释即可轻易读懂。优秀的代码不写注释也可轻易读懂,注释无法把糟糕的代码变好,需要很多注释来解释的代码往往存在坏味道,需要重构。

【示例】

注释不能消除代码的坏味道:

/* 判断m是否为素数*/

/* 返回值:: 是素数,: 不是素数*/

int p(int m)

{

int k = sqrt(m);

for (int i = 2; i <= k; i++)

if (m % i == 0)

break; /* 发现整除,表示m不为素数,结束遍历*/

/* 遍历中没有发现整除的情况,返回*/

if (i > k)

return 1;

/* 遍历中没有发现整除的情况,返回*/

else

return 0;

}

重构代码后,不需要注释:

int IsPrimeNumber(int num)

{

int sqrt_of_num = sqrt (num);

for (int i = 2; i <= sqrt_of_num; i++)

{

if (num % i == 0)

{

return FALSE;

}

}

return TRUE;

}

【示例】

功能说明:

/*

* lib/prio_tree.c - priority search tree

*

* Copyright (C) 2004, Rajesh Venkatasubramanian

*

* This file is released under the GPL v2.

*

* Based on the radix priority search tree proposed by Edward M. McCreight

* SIAM Journal of Computing, vol. 14, no.2, pages 257-276, May 1985

*

* 02Feb2004 Initial version

*/

#include

#include

#include

单行注释:

/*

* Maximum heap_index that can be stored in a PST with index_bits bits

*/

static inline unsigned long prio_tree_maxindex(unsigned int bits)

{

return index_bits_to_maxindex[bits - 1];

}

【原则】

文件头部应进行注释,注释必须列出:版权说明、版本号、生成日期、作者姓名、工号、内容、功能说明、与其它文件的关系、修改日志等,头文件的注释中还应有函数功能简要说明。

如果模块或函数有重大重构或修改时应标明修改时间和修改内容。

注释的内容要清楚、明了,含义准确,防止注释二义性。

修改代码时,维护代码周边的所有注释,以保证注释与代码的一致性。不再有用的注释要删除。

函数声明处注释描述函数功能、性能及用法,包括输入和输出参数、函数返回值、可重入的要求等;定义处详细描述函数功能和实现要点,如实现的简要步骤、实现的理由、设计约束等。

全局变量要有较详细的注释,包括对其功能、取值范围以及存取时注意事项等的说明。

【建议】

对于每个模块应使用块注释在模块上方说明作用和功能,语言简洁、易懂。

建议不要在模块或函数内部加入过多的注释影响阅读。注释的作用是解释难以表达的抽象意图,而不是重复描述代码。

建议注释应放在其代码上方相邻位置或右方,不可放在下面。如放于上方则需与其上面的代码用空行隔开,且与下方代码缩进相同。

排版与格式

程序的可读性和可维护性除了编码好坏外,还要很重要的因素是编码时的排版与格式。应该注意排版风格一致、美观。

【示例】

int swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,

enum dma_data_direction dir, struct dma_attrs *attrs)

{

struct scatterlist *sg;

int i;

BUG_ON(dir == DMA_NONE);

for_each_sg(sgl, sg, nelems, i)

{

phys_addr_t paddr = sg_phys(sg);

dma_addr_t dev_addr = phys_to_dma(hwdev, paddr);

if (swiotlb_force || !dma_capable(hwdev, dev_addr, sg->length))

{

void *map = map_single(hwdev, sg_phys(sg),sg->length, dir);

if (!map)

{

/* Don't panic here, we expect map_sg users to do proper error handling. */

swiotlb_full(hwdev, sg->length, dir, 0);

swiotlb_unmap_sg_attrs(hwdev, sgl, i, dir,attrs);

sgl[0].dma_length = 0;

return 0;

}

sg->dma_address = swiotlb_virt_to_bus(hwdev, map);

}

else

{

sg->dma_address = dev_addr;

}

sg->dma_length = sg->length;

}

return nelems;

}

EXPORT_SYMBOL(swiotlb_map_sg_attrs);

【原则】

程序块应采用缩进风格编写,每级缩进为1个tab(1个tab设为4个空格)。

if、for、do、while、case、switch、default等语句独占一行。

相对独立的程序块之间、变量说明之后必须加空行。

【建议】

多个短语句(包括赋值语句)不允许写在同一行内,即一行只写一条语句。

任何运算符左右必须加一个空格。

一条语句不能过长,如不能拆分需要分行写。一行到底多少字符换行比较合适,产品可以自行确定。

在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符之前、之后或者前后要加空格;进行非对等操作时,如果是关系密切的立即操作符(如->),后不应加空格。

注释符(包括„/‟„//‟„/‟)与注释内容之间要用一个空格进行分隔。

所有花括号必须独占一行,if语句即使一条表达式也要加花括号。

程序效率

本章节后面所有的原则和建议,都应在不影响前述可读性等质量属性的前提下实施。不能一味地追求代码效率,而对软件的正确、简洁、可维护性、可靠性及可测性造成影响。

记住:让一个正确的程序更快速,比让一个足够快的程序正确,要容易得太多。大多数时候,不要把注意力集中在如何使代码更快上,应首先关注让代码尽可能地清晰易读和更可靠。

【示例】

int foo()

{

if (异常条件)

{

异常处理;

return ERR_CODE_1;

}

if (异常条件)

{

异常处理;

return ERR_CODE_2;

}

正常处理;

return SUCCESS;

}

上面的示例代码看起来很清晰,而且也避免了大量的if else嵌套。但是从性能的角度来看,应该把执行概率较大的分支放在前面处理,由于正常情况下的执行概率更大,若首先考虑性能。应如下书写:

int foo()

{

if (满足条件)

{

正常处理;

return SUCCESS;

}

else if (概率比较大的异常条件)

{

异常处理;

return ERR_CODE_1;

}

else

{

异常处理;

return ERR_CODE_2;

}

}

除非证明foo函数是性能瓶颈,否则按照本规则,应优先选用前面一种写法。

【原则】

通过对数据结构、程序算法的优化来提高效率。

将不变条件的计算移到循环体外。

c语言编程规范总结,【技术小记 | C语言】C 语言编程规范相关推荐

  1. 单片机应用技术案例教程(c语言)答案,单片机应用技术案例教程(C语言版)

    项目1单片机及其开发系统(1) 任务1-1控制1颗LED发光二极管闪烁(1) 1.151单片机的引脚排列及其功能(14) 1.2单片机很小应用系统(15) 1.2.1时钟电路(15) 1.2.2复位电 ...

  2. html语言技术基础,第2章Web编程基础HTML语言技术方案.ppt

    通过Internet浏览世界各地的网络资源,或者要把信息通过Internet以Web方式发布到全球,就必须使用网页.网页就是用户在浏览器上看到的一个个画面.通过网页,即便是一个不懂计算机的人,也能借助 ...

  3. [GO语言基础] 三.变量声明、数据类型、标识符及编程练习12题

    作为网络安全初学者,会遇到采用Go语言开发的恶意样本.因此从今天开始从零讲解Golang编程语言,一方面是督促自己不断前行且学习新知识:另一方面是分享与读者,希望大家一起进步.前文介绍了Go的编译运行 ...

  4. android xml java混合编程_Java学习中注解与多线程,网络编程与XML技术

    本部分内容主要有集合框架及泛型,实用类,输入和输出处理,注解与多线程,网络编程与XML技术.初次学习这部分会感觉很难,主要是概念难于理解,最好是多看看例子,多练习.下面是个人的总结 拉勾IT课小编为大 ...

  5. 会c 学plc编程语言,想学PLC编程?先弄清5种PLC专用语言!

    PLC目前有5种标准的编程语言,包含图形化编程语言和文本化编程语言. 图形化编程语言包含:梯形图(LD-Ladder Diagram).功能块图(FBD - Function Block Diagra ...

  6. C语言编程入门学习精华:这样学习C语言最有效

    1. C语言已死吗? 本资料描述的是使用C语言的高级技巧,力求将你的C语言能力由"基础"提升为"高级".但是学习态度胜过学习方法,在正式学习之前,有一个问题不吐 ...

  7. Python GUI编程-了解相关技术[整理]

    Python GUI编程-了解相关技术[整理] 我们可以看到,其实python进行GUI开发并没有自身的相关库,而是借用第三方库进行开发.tkinter是tcl/tk相关,pyGTK是Gtk相关,wx ...

  8. python与c语言在语法上的区别-C语言和Python编程先学习哪个

    原标题:C语言和Python编程先学习哪个 初学者,Python和C语言先学哪个好? 就像是"先有鸡还是先有蛋一样",先学python还是先学C语言,这也是个世纪难题. 这种纠结并 ...

  9. 编程入门python语言是多大孩子学的-包头孩子学编程python好吗

    包头孩子学编程python好吗,学习少儿编程就选童程童美,童程童美专注3-18岁少儿编程教育.历时多年,形成了以创意启蒙课程.人工智能编程.智能机器人编程.信息学奥赛编程等课程为核心的一站式编程教育平 ...

  10. 随机森林c语言编程,一种基于随机森林的C语言源代码静态评分方法与流程

    本发明涉及评分领域及机器学习领域,它特别涉及一种基于随机森林的c语言源代码静态评分的构建方法. 背景技术: c语言源代码静态评分是指对根据一定的题目描述做出解答的c语言源代码进行评分.目前,主要流行的 ...

最新文章

  1. Android drawLine 画虚线
  2. 参赛队员对于第十六届全国大学智能车竞赛的建议-05月
  3. 功能规格说明书Version2
  4. 一个 MVC 框架以 MVVM 之「魂」复活了!
  5. [bzoj4823][洛谷P3756][Cqoi2017]老C的方块
  6. R语言处理1975-2011年的人口信息
  7. linux rkt命令,rkt 1.13.0发布,CoreOS的容器引擎
  8. Maven学习总结(52)——Maven 配置文件密码加密机制使用说明
  9. Python补充之函数
  10. 计算机网络在金融领域的应用,计算机网络毕业论文计算机网络技术在金融领域的应用.pdf...
  11. linux限制ip带宽,apache如何限制并发数 IP 带宽?
  12. 2022百度之星第一场初赛
  13. 水晶报表CrystalReports很强大也很简单!
  14. PIXI入门-PIXI文档翻译(1)
  15. 城市生活污水处理技术现状及活性炭的应用
  16. [WinError 206] 文件名或扩展名太长(组策略值修改 解除windows文件名 字符长度限制)
  17. ISP IAP 详解与ISP IAP的实现
  18. 词库列阵的作用与使用方法
  19. Microsoft Office 2016 镜像文件以及安装步骤
  20. 二进制安装K8S(四):部署flannel网络

热门文章

  1. turtle绘画-移动落笔点(改变初始原点)
  2. [翻译]理解Unity的自动内存管理
  3. 2015 中国(广州)国际健康产业博览会即将拉开帷幕
  4. UVA - 10118 Free Candies
  5. 【人脸识别】千变万化的人脸识别 REID损失函数总结
  6. 无法识别 移动固态硬盘_M.2接口的固态硬盘无法识别?其实解决方法非常简单!...
  7. keda.#P1097. 不要62
  8. Java二维数组声明与初始化
  9. html 显示天气预报,前端HTML页面获取实时天气预报并展示
  10. 以二进制方式打开文件并显示