【简洁的代码永远不会掩盖设计者的意图】如何写出规范整洁的代码

本文主要是介绍【简洁的代码永远不会掩盖设计者的意图】如何写出规范整洁的代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 个人名片:

🦁作者简介:学生
🐯个人主页:妄北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等,除非逻辑上的确需要编号。

标识符前最好不加项目、产品、部门的标识。这样做的目的是为了代码的可重用性。

大佬觉得有用的话点个赞 👍🏻 呗。

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥任务在无形中完成,价值在无形中升华,让我们一起加油吧!🌙🌙🌙

这篇关于【简洁的代码永远不会掩盖设计者的意图】如何写出规范整洁的代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/722004

相关文章

SQL Server使用SELECT INTO实现表备份的代码示例

《SQLServer使用SELECTINTO实现表备份的代码示例》在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误,在SQLServer中,可以使用SELECTINT... 在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误。在 SQL Server 中,可以使用 SE

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一

在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码

《在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码》在MyBatis的XML映射文件中,trim元素用于动态添加SQL语句的一部分,处理前缀、后缀及多余的逗号或连接符,示... 在MyBATis的XML映射文件中,<trim>元素用于动态地添加SQL语句的一部分,例如SET或W

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

python多进程实现数据共享的示例代码

《python多进程实现数据共享的示例代码》本文介绍了Python中多进程实现数据共享的方法,包括使用multiprocessing模块和manager模块这两种方法,具有一定的参考价值,感兴趣的可以... 目录背景进程、进程创建进程间通信 进程间共享数据共享list实践背景 安卓ui自动化框架,使用的是

SpringBoot生成和操作PDF的代码详解

《SpringBoot生成和操作PDF的代码详解》本文主要介绍了在SpringBoot项目下,通过代码和操作步骤,详细的介绍了如何操作PDF,希望可以帮助到准备通过JAVA操作PDF的你,项目框架用的... 目录本文简介PDF文件简介代码实现PDF操作基于PDF模板生成,并下载完全基于代码生成,并保存合并P

SpringBoot基于MyBatis-Plus实现Lambda Query查询的示例代码

《SpringBoot基于MyBatis-Plus实现LambdaQuery查询的示例代码》MyBatis-Plus是MyBatis的增强工具,简化了数据库操作,并提高了开发效率,它提供了多种查询方... 目录引言基础环境配置依赖配置(Maven)application.yml 配置表结构设计demo_st

SpringCloud集成AlloyDB的示例代码

《SpringCloud集成AlloyDB的示例代码》AlloyDB是GoogleCloud提供的一种高度可扩展、强性能的关系型数据库服务,它兼容PostgreSQL,并提供了更快的查询性能... 目录1.AlloyDBjavascript是什么?AlloyDB 的工作原理2.搭建测试环境3.代码工程1.

Java调用Python代码的几种方法小结

《Java调用Python代码的几种方法小结》Python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求很常见、实用,本文介绍几种方法从java调用Pyt... 目录引言Java core使用ProcessBuilder使用Java脚本引擎总结引言python

Java中ArrayList的8种浅拷贝方式示例代码

《Java中ArrayList的8种浅拷贝方式示例代码》:本文主要介绍Java中ArrayList的8种浅拷贝方式的相关资料,讲解了Java中ArrayList的浅拷贝概念,并详细分享了八种实现浅... 目录引言什么是浅拷贝?ArrayList 浅拷贝的重要性方法一:使用构造函数方法二:使用 addAll(