个人名片:
🦁作者简介:学生
🐯个人主页:妄北y🐧个人QQ:2061314755
🐻个人邮箱:2061314755@qq.com
🦉个人WeChat:Vir2021GKBS
🐼本文由妄北y原创,首发CSDN🎊🎊🎊
🐨座右铭:大多数人想要改造这个世界,但却罕有人想改造自己。
专栏导航:
妄北y系列专栏导航:
C/C++的基础算法:C/C++是一种常用的编程语言,可以用于实现各种算法,这里我们对一些基础算法进行了详细的介绍与分享。🎇🎇🎇
QT基础入门学习:对QT的基础图形化页面设计进行了一个简单的学习与认识,利用QT的基础知识进行了翻金币小游戏的制作🤹🤹🤹
Linux基础编程:初步认识什么是Linux,为什么学Linux,安装环境,进行基础命令的学习,入门级的shell编程。🍻🍻🍻
Linux应用开发基础开发:分享Linux的基本概念、命令行操作、文件系统、用户和权限管理等,网络编程相关知识,TCP/IP 协议、套接字(Socket)编程等,可以实现网络通信功能。💐💐💐
Linux项目开发:Linux基础知识的实践,做项目是最锻炼能力的一个学习方法,这里我们会学习到一些简单基础的项目开发与应用,而且都是毕业设计级别的哦。🤸🤸🤸
非常期待和您一起在这个小小的互联网世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨
文章介绍:
🎉本篇文章对编程规范进行分享!🥳🥳🥳
“干净的代码既简单又直接。干净的代码读起来像写得很好的散文。简洁的代码永远不会掩盖设计者的意图,而是充满清晰的抽象和直接的控制线。” -罗伯特·马丁(Robert C. Martin)
如果您觉得文章不错,期待你的一键三连哦,你的鼓励是我创作动力的源泉,让我们一起加油,一起奔跑,让我们顶峰相见!!!💪💪💪
🎁感谢大家点赞👍收藏⭐评论✍️
一、编程规范的作用
1.1 提高源程序的可读性和可维护性
1.2 降低错误的机会
1.3 提高源代码可重用性和质量
二、规范的三种形式
2.1 原则:编程时应该坚持的指导思想。
2.2 规则:编程时必须遵守的约定。
2.3 建议:编程时必须加以考虑的约定。
三、规范的内容
3.1 基本原则
3.1.1 原则一
首先是为人编写程序,其次才是计算机。
这是软件开发的基本要点,软件的生命周期贯穿产品的开发、测试、生产、用户使用、版本升级和后期维护等长期过程,只有易读、易维护的软件代码才具有生命力。
3.1.2 原则二
保持代码的简明清晰,避免过分的编程技巧。
简单是最美。保持代码的简单化是软件工程化的基本要求。不要过分追求技巧,否则会降低程序的可读性。
3.1.3 原则三
所有的代码尽量遵循ANSI C标准。
所有的代码尽可能遵循ANSI C标准,尽可能不使用ANSI C未定义的或编译器扩展的功能。
3.1.4 原则四
编程时首先达到正确性,其次考虑效率。
编程首先考虑的是满足正确性、健壮性、可维护性、可移植性等质量因素,最后才考虑程序的效率和资源占用。
3.1.5 原则五
避免或少用全局变量。
过多地使用全局变量,会导致模块间的紧耦合,违反模块化的要求 。
3.1.6 原则六
尽量避免使用GOTO语句。
3.1.7 原则七
尽可能复用、修正老的代码。
尽量选择可借用的代码,对其修改优化以达到自身要求。
3.1.8 原则八
尽量减少同样的错误出现的次数。
事实上,我们无法做到完全消除错误,但通过不懈的努力,可以减少同样的错误出现的次数
3.2 布局
3.2.1 规则一
遵循统一的布局顺序来书写头文件。
#ifndef 文件名_H(全大写)
#define 文件名_H
其它条件编译选项
#include(依次为标准库头文件、非标准库头文件)
常量定义
全局宏
全局数据类型
类定义
模板(template)(包括C++中的类模板和函数模板)全局函数原型
#endif
3.2.2 规则二
遵循统一的布局顺序来书写实现文件。
文件头注释
#include(依次为标准库头文件、非标准库头文件)
常量定义
文件内部使用的宏
文件内部使用的数据类型
全局变量
本地变量(即静态全局变量)
局部函数原型
类的实现
全局函数
局部函数
3.2.3 规则三
使用注释块分离上面定义的节。
/ ************************************************************ 数据类型定义 ************************************************************ /typedef unsigned char BOOLEAN;/************************************************************** 函数原型 *************************************************************/int DoSomething(void);
3.2.4 规则四
头文件必须要避免重复包含。
#ifndef MODULE_H
#define MODULE_H[文件体]
#endif
3.2.5 规则五
包含标准库头文件用尖括号 < >,包含非标准库头文件用双引号 “ ”。
#include <stdio.h>
#include “heads.h”
3.2.6 规则六
遵循统一的顺序书写类的定义及实现。
类的定义(在定义文件中)按如下顺序书写:
公有属性, 公有函数,
保护属性, 保护函数
私有属性, 私有函数
类的实现(在实现文件中)按如下顺序书写:
构造函数,析构函数
公有函数
保护函数
私有函数
3.2.7 规则七
程序中一行的代码和注释不能超过80列。
包括空格在内不超过80列。
3.2.8 规则八
if、else、else if、for、while、do等语句自占一行,执行语句不得紧跟其后。不论执行语句有多少都要加 { }。
if (varible1 < varible2)
{varible1 = varible2;
}
反例: if (varible1 < varible2) varible1 = varible2;
3.2.9 规则九
结构型的数组、多维的数组如果在定义时初始化,按照数组的矩阵结构分行书写。
int aiNumbers[4][3] =
{1, 1, 1,2, 4, 8,3, 9, 27,4, 16, 64
}
3.2.10 规则十
相关的赋值语句等号对齐。
tPDBRes.wHead = 0;
tPDBRes.wTail = wMaxNumOfPDB - 1;
tPDBRes.wFree = wMaxNumOfPDB;
tPDBRes.wAddress = wPDBAddr;
tPDBRes.wSize = wPDBSize;
3.2.11 规则十一
不同逻辑程序块之间要使用空行分隔。
void Foo::Hey(void)
{[Hey实现代码]
}
// 空一行
void Foo::Ack(void)
{[Ack实现代码]
}
3.2.12 规则十二
一元操作符如“!”、“~”、“++”、“--”、“*”、“&”(地址运算符)等前后不加空格。“[]”、“.”、“->”这类操作符前后不加空格。
!bValue,~iValue,++iCount,*strSource,&fSum,
aiNumber[i] = 5,tBox.dWidth,
tBox->dWidth
多元运算符和它们的操作数之间至少需要一个空格。
fValue = fOldValue;
fTotal + fValue
iNumber += 2;
3.2.13 规则十三
关键字之后要留空格。
if、for、while等关键字之后应留一个空格再跟左括号‘(’,以突出关键字。
函数名之后不要留空格。
函数名后紧跟左括号‘(’,以与关键字区别。
‘(’向后紧跟,‘)’、‘,’、‘;’向前紧跟,紧跟处不留空格。
‘,’之后要留空格。‘;’不是行结束符号时其后要留空格。
for凵(i凵=凵0;凵i凵<凵MAX_BSC_NUM;凵i++)
{DoSomething(iWidth,凵iHeight);
}
3.2.14 规则十四
注释符与注释内容之间要用一个空格进行分隔。
/* 注释内容 */
// 注释内容
反例:
/*注释内容*/
//注释内容
3.2.15 规则十五
//长表达式(超过80列)要在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符)。拆分出的新行要进行适当的缩进,使排版整齐
if ((iFormat == CH_A_Format_M) && (iOfficeType == CH_BSC_M))
{ DoSomething();}// for循环语句续行在初始化条件语句处对齐
for (long_initialization_statement;long_condiction_statement; long_update_statement){DoSomething();}// 函数声明的续行在第一个参数处对齐
BYTE ReportStatusCheckPara(HWND hWnd, BYTE ucCallNo, BYTE ucStatusReportNo); // 赋值语句的续行应在赋值号处对齐
fTotalBill = fTotalBill + faCustomerPurchases[iID]+ fSalesTax(faCustomerPurchases[iID]);
3.2.16 规则十六
函数声明时,类型与名称不允许分行书写。
正例:
extern double FAR CalcArea(double dWidth, double dHeight);
反例:
extern double FAR
CalcArea(double dWidth, double dHeight);
3.3 注释
3.3.1 规则一
C语言的注释符为“/* … */”。C++语言中,多行注释采用“/* … */”,单行注释采用“// …”。
一般情况下,源程序有效注释量必须在20%以上。
注释的原则是有助于对程序的阅读理解,注释不宜太多也不能太少,注释语言必须准确、易懂、简洁。有效的注释是指在代码的功能、意图层次上进行注释,提供有用、额外的信息。
3.3.2 规则二
注释使用中文。
对于特殊要求的可以使用英文注释,如工具不支持中文或国际化版本。
文件头部必须进行注释,包括:.h文件、.c文件、.cpp文件、.inc文件、.def文件、编译说明文件.cfg等。
注释必须列出:版权信息、文件标识、内容摘要、版本号、作者、完成日期、修改信息等。
/*********************************************************************
* 版权所有 (C)2024, xxxx股份有限公司。
*
* 文件名称: // 文件名
* 文件标识: // 见配置管理计划书
* 内容摘要: // 简要描述本文件的内容,包括主要模块、函数及其功能的说明
* 其它说明: // 其它内容的说明
* 当前版本: // 输入当前版本
* 作 者: // 输入作者名字及单位
* 完成日期: // 输入完成日期,例:2000年2月25日
*
* 修改日期 版本号 修改人 修改内容* ---------------------------------------------------------------* 2024/02/18 V1.0 XXXX XXXX
******************************************************************/
3.3.3 规则三
函数头部应进行注释,列出:函数的目的/功能、输入参数、输出参数、返回值、访问和修改的表、修改信息等。
说明:注释必须列出:函数名称、功能描述、输入参数、输出参数、返 回 值、修改信息
/**********************************************************************
* 函数名称: // 函数名称
* 功能描述: // 函数功能、性能等的描述
* 访问的表: //(可选)被访问的表,此项仅对于有数据库操作的程序
* 修改的表: //(可选)被修改的表,此项仅对于有数据库操作的程序
* 输入参数: // 输入参数说明,包括每个参数的作用、取值说明及参数间关系
* 输出参数: // 对输出参数的说明。* 返 回 值: // 函数返回值的说明 * 其它说明: // 其它说明
* 修改日期 版本号 修改人 修改内容* -----------------------------------------------
* 2002/08/01 V1.0 XXXX XXXX
***********************************************************************/
3.3.4 规则四
包含在{ }中代码块的结束处应加注释,便于阅读。特别是多分支、多重嵌套的条件语句或循环语句。
while (…)
{
…
} /* end of while (…) */ // 指明该条while语句结束
保证代码和注释的一致性。修改代码同时修改相应的注释,不再有用的注释要删除。
3.3.5 规则五
注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。
/* 代码段1注释 */
[ 代码段1 ]/* 代码段2注释 */[ 代码段2 ]
3.3.6 规则六。
全局变量要有详细的注释,包括对其功能、取值范围、访问信息及访问时注意事项等的说明。
/*
* 变量作用:(错误状态码)
* 变量范围:例如0 - SUCCESS 1 - Table error
* 访问说明:(访问的函数以及方法)
*/BYTE g_ucTranErrorCode;
3.3.7 规则七。
注释与所描述内容进行同样的缩排。
int DoSomething(void)
{
/* 代码段1注释 */[ 代码段1 ]/* 代码段2注释 */[ 代码段2 ]
}
3.3.8 规则八。
对分支语句(条件分支、循环语句等)必须编写注释。
通过对函数或过程、变量、结构等正确的命名以及合理地组织代码结构,使代码成为自注释的。
尽量避免在注释中使用缩写,特别是不常用缩写。
3.4 命名规则
3.4.1 规则一
标识符要采用英文单词或其组合,便于记忆和阅读,切忌使用汉语拼音来命名。标识符应当直观且可以拼读,可望文知义,避免使人产生误解。程序中的英文单词一般不要太复杂,用词应当准确。
标识符只能由26个英文字母,10个数字,及下划线的一个子集来组成,并严格禁止使用连续的下划线,下划线也不能出现在标识符头或结尾(预编译开关除外)。
标识符的命名应当符合“min-length && max-information”原则。
较短的单词可通过去掉“元音”形成缩写,较长的单词可取单词的头几个字母形成缩写,一些单词有大家公认的缩写,常用单词的缩写必须统一。协议中的单词的缩写与协议保持一致。对于某个系统使用的专用缩写应该在某处做统一说明。
temp 可缩写为 tmp ;
flag 可缩写为 flg ;
statistic 可缩写为 stat ;
increment 可缩写为 inc ;
message 可缩写为 msg ;
程序中不要出现仅靠大小写区分的相似的标识符。
3.4.2 规则二
用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。
add /remove;begin / end;create / destroy ; insert / delete ;
first/last; get/release; increment/decrement ; put / get ;
lock / unlock ;open / close ; min / max ;old / new ;
start / stop ;next / previous ;source / target ;
show / hide ; send / receive ;source / destination ;
cut / paste ; up / down
宏、常量名都要使用大写字母, 用下划线 ‘_’ 分割单词。预编译开关的定义使用下划线 ‘_’ 开始。
DISP_BUF_SIZE、MIN_VALUE、MAX_VALUE
变量名长度应小于31个字符,以保持与ANSI C标准一致。不得取单个字符(如i、j、k等)作为变量名,但是局部循环变量除外。
3.4.3 规则三
程序中局部变量不要与全局变量重名。
尽管局部变量和全局变量的作用域不同而不会发生语法错误,但容易使人误解。
使用一致的前缀来区分变量的作用域。
变量活动范围前缀规范如下:
g_ : 全局变量
m_ : 类的数据成员
s_ : 模块内静态变量
空 : 局部变量不加范围前缀
使用一致的小写类型指示符作为前缀来区分变量的类型。
i : int, f : float
d : double c : char
uc : unsigned char 或 BYTE l : long
p : pointer b : BOOL
h : HANDLE w : unsigned short 或 WORD
dw : DWORD或 unsigned long a : 数组,array of TYPE
str : 字符串 t : 结构类型
3.4.4 规则四
完整的变量名应由前缀+变量名主体组成,变量名的主体应当使用“名词”或者“形容词+名词”,且首字母必须大写。
float g_fValue; //类型为浮点数的全局变量
char *pcOldChar; //类型为字符指针的局部变量
函数名用大写字母开头的单词组合而成,且应当使用“动词”或者“动词+名词”(动宾词组)
函数名力求清晰、明了,通过函数名就能够判断函数的主要功能。函数名中不同意义字段之间不要用下划线连接,而要把每个字段的首字母大写以示区分。函数命名采用大小写字母结合的形式,但专有名词不受限制。
结构名、联合名、枚举名由前缀T_ 开头。
事件名由前缀EV_ 开头。
类名采用大小写结合的方法。在构成类名的单词之间不用下划线,类名在开头加上C,类的成员变量统一在前面加m_ 前缀。
尽量避免名字中出现数字编号,如Value1、Value2等,除非逻辑上的确需要编号。
标识符前最好不加项目、产品、部门的标识。这样做的目的是为了代码的可重用性。
大佬觉得有用的话点个赞 👍🏻 呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄
💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍
🔥🔥🔥任务在无形中完成,价值在无形中升华,让我们一起加油吧!🌙🌙🌙