Google编码规范及《数学之美读后感》
一、谷歌公司C++编码规范
简介:养成代码规范的习惯,有助于程序员自身的成长。为提升自身的编码能力,优化所编代码的可读性,笔者从参考文献的《谷歌编程规范》(Google_Cpp_Style_guide_CN)中挑选了三个篇章:命名约定、注释、格式,并认为是本学期编码需要严格遵守的规范。
1.命名约定
(1) 通用命名规则
函数命名、变量命名、文件命名应具有描述性,不要过度缩写,类型和变量应该是名词,函数名可以用“命令性”动词。
如何命名:
尽可能给出描述性名称,不要节约空间,让别人很快理解你的代码更重要。
缩写:
除非放到项目外也非常明了,否则不要使用缩写。
(2) 文件命名
文件名要全部小写,可以包含下划线(_)或短线(-),按项目约定来。
(3) 类型命名
类型命名每个单词以大写字母开头,不包含下划线:MyExcitingClass、MyExcitingEnum。所有类型命名——类、结构体、类型定义(typedef)、枚举——使用相同约定
(4) 变量命名
变量名一律小写,单词间以下划线相连,类的成员变量以下划线结尾,如:my_exciting_local_variable、my_exciting_member_variable_
(5) 函数命名
普通函数:
函数名以大写字母开头,每个单词首字母大写,没有下划线:AddTableEntry()、DeleteUrl()
在遵从代码一致性、可读性的前提下,可将上述规则概括为:
- 不要随意缩写,如果说 ChangeLocalValue写作 ChgLocVal还有情可原的话,把 ModifyPlayerName写作 MdfPlyNm就太过分了,除函数名可适当为动词外,其他命名尽量使用清晰易懂的名词;
- 宏、枚举等使用全部大写+下划线;
- 变量(含类、结构体成员变量)、文件、命名空间、存取函数等使用全部小写+下划线 ,类成员变量以下划线结尾,全局变量以 g_开头;
- 普通函数、类型(含类与结构体、枚举类型)、常量等使用大小写混合,不含下划线;
- 参考现有或相近命名约定。
2.注释
注释虽然写起来很痛苦,但对保证代码可读性至为重要,下面的规则描述了应该注释什么、注释在哪儿。当然也要记住,注释的确很重要,但最好的代码本身就是文档(self-documenting),类型和变量命名意义明确要比通过注释解释模糊的命名好得多。
(1) 注释风格
使用//或/* */,统一就好。//或/* */都可以,//只是用的更加广泛,在如何注释和注释风格上确保统一。
(2) 函数注释
函数声明处注释描述函数功能,定义处描述函数实现。
函数声明:
注释于声明之前,描述函数功能及用法,注释使用描述式("Opens the file")而非指令式("Open the file");注释只是为了描述函数而不是告诉函数做什么。通常,注释不会描述函数如何实现,那是定义部分的事情。
函数声明处注释的内容:
1) inputs(输入)及 outputs(输出);
2) 对类成员函数而言:函数调用期间对象是否需要保持引用参数,是否会释放这些参数;
3) 如果函数分配了空间,需要由调用者释放;
4) 参数是否可以为 NULL;
5) 是否存在函数使用的性能隐忧(performance implications);
6) 如果函数是可重入的(re-entrant),其同步前提(synchronization assumptions)是什么?
(3) 变量注释
通常变量名本身足以很好说明变量用途,特定情况下,需要额外注释说明。
类数据成员:
每个类数据成员(也叫实例变量或成员变量)应注释说明用途,如果变量可以接受 NULL 或-1等警戒值,须说明之。
全局变量(常量):
和数据成员相似,所有全局变量(常量)也应注释说明含义及用途。
(4) 标点、拼写和语法
留意标点、拼写和语法,写的好的注释比差的要易读的多。注释一般是包含适当大写和句点的完整的句子,短一点的注释(如代码行尾的注释)可以随意点,依然要注意风格的一致性。完整的句子可读性更好,也可以说明该注释是完整的而不是一点不成熟的想法。清晰易读的代码是很重要的,适当的标点、拼写和语法对此会有所帮助。
总结:
- 注释要言简意赅,不要拖沓冗余,复杂的东西简单化和简单的东西复杂化都是要被鄙视的;
- 对于Chinese coders 来说,用英文注释还是用中文注释,it is a problem,但不管怎样,注释是为了让别人看懂,难道是为了炫耀编程语言之外的你的母语或外语水平吗;
- 注释不要太乱,适当的缩进才会让人乐意看,但也没有必要规定注释从第几列开始。
3.格式
代码风格和格式确实比较随意,但一个项目中所有人遵循同一风格是非常容易的,作为个人未必同意下述格式规则的每一处,但整个项目服从统一的编程风格是很重要的,这样做才能让所有人在阅读和理解代码时更加容易。
(1) 行长度
每一行代码字符数不超过 80。
(2) 非 ASCII 字符
尽量不使用非 ASCII 字符,使用时必须使用 UTF-8 格式。
(3) 空格还是制表位
只使用空格,每次缩进 2 个空格。使用空格进行缩进,不要在代码中使用 tabs,设定编辑器将 tab 转为空格。
(4) 函数声明与定义
返回类型和函数名在同一行,合适的话,参数也放在同一行。
函数看上去像这样:
ReturnType ClassName::FunctionName(Type par_name1, Type par_name2) {
DoSomething();
...
}
注意以下几点:
1) 返回值总是和函数名在同一行;
2) 左圆括号(open parenthesis)总是和函数名在同一行;
3) 函数名和左圆括号间没有空格;
4) 圆括号与参数间没有空格;
5) 左大括号(open curly brace)总在最后一个参数同一行的末尾处;
6) 右大括号(close curly brace)总是单独位于函数最后一行;
7) 右圆括号(close parenthesis)和左大括号间总是有一个空格;
8) 函数声明和实现处的所有形参名称必须保持一致;
9) 所有形参应尽可能对齐;
10) 缺省缩进为 2 个空格;
11) 独立封装的参数保持 4 个空格的缩进。
(5) 条件语句
提倡不在圆括号中添加空格,关键字 else 另起一行。
注意所有情况下 if 和左圆括号间有个空格,右圆括号和左大括号(如果使用的话)间也要有个空格:
if (condition) { // Good - proper space after IF and before {
有些条件语句写在同一行以增强可读性,只有当语句简单并且没有使用 else 子句时使用:
if (x == kFoo) return new Foo();
良好的条件语句:
if (condition) { // no spaces inside parentheses
... // 2 space indent.
} else { // The else goes on the same line as the closing brace.
...
}
(6) 循环和开关选择语句
switch 语句可以使用大括号分块;空循环体应使用{}或 continue。
如果有不满足 case 枚举条件的值,要总是包含一个 default(如果有输入值没有 case 去处理,编译器将报警)。
空循环体应使用{}或 continue,而不是一个简单的分号:
while (condition) {
// Repeat test until it returns false.
}
for (int i = 0; i < kSomeNumber; ++i) {} // Good - empty body.
while (condition) continue; // Good - continue indicates no logic.
while (condition); // Bad - looks like part of do/while loop.
(7) 指针和引用表达式
句点(.)或箭头(->)前后不要有空格,指针/地址操作符(*、&)后不要有空格。
下面是指针和引用表达式的正确范例:
x = *p;
p = &x;
x = r.y;
x = r->y;
(8) 函数返回值
return 表达式中不要使用圆括号。函数返回时不要使用圆括号:
return x; // not return(x);
(9) 水平留白
水平留白的使用因地制宜。不要在行尾添加无谓的留白。
(10) 垂直留白
垂直留白越少越好。不要在两个函数定义之间空超过 2 行,函数体头、尾不要有空行,函数体中也不要随意添加空行。
基本原则是:同一屏可以显示越多的代码,程序的控制流就越容易理解。当然,过于密集的代码块和过于疏松的代码块同样难看,取决于你的判断,但通常是越少越好。
总结:
1. 行宽原则上不超过 80 列;
2. 尽量不使用非 ASCII 字符,如果使用的话,参考 UTF-8 格式;
3. UNIX/Linux下无条件使用空格;
4. 函数参数、逻辑条件、初始化列表:要么所有参数和函数名放在同一行,要么所有参数并排分行;
5. 除函数定义的左大括号可以置于行首外,包括函数/类/结构体/枚举声明、各种语句的左大括号置于行尾,所有右大括号独立成行;
6. ./->操作符前后不留空格,*/&不要前后都留,一个就可,靠左靠右依各人喜好;
7. 预处理指令/命名空间不使用额外缩进,类/结构体/枚举/函数/语句使用缩进;
8. 初始化用=还是()依个人喜好,统一就好;
9. return 不要加();
10. 水平/垂直留白不要滥用,怎么易读怎么来。
二、《数学之美》第一章读后感
本章简要概述了文字和语言的发展演变史,而在文字和语言史背后蕴含着的也是一部数学和信息的发展史。通过阅读本章的内容,我深刻的理解到文字和语言与数学和信息的关系,即文字和语言是作为一种媒介,用于传达其背后所蕴含的信息。我们日常生活中频繁使用的文字和语言,都只不过是信息的一种表达形式,即一切的交流都是基于信息的,信息是各种文字语言形式的内在根本。
文字是信息的表达形式,文字的发展体现了信息的发展,研究文字的历史有着重要的意义。文中阐述了文字的发展史,最早的是古埃及的图画文字,即用画的形式去描绘一些物体,或形容某件事情的发生,这种文字过于复杂,但作为文字的雏形有着重要的历史意义,随着人类所需表达的信息的增加,文字开始朝简发展,渐渐出现了象形文字,如中国古代的象形文字和古巴比伦的锲形文字,这些文字便是是由图画文字演化而来的。象形文字把具象的事物简化,创造了一个大众可接受的易于流通的信息,促进了信息的传播,但是在蔡伦发明纸之前,文字需要雕刻在石头等硬质物体上,而象形文字写起来仍然非常复杂。腓尼基人发明了拼音文字,这种文字更容易学习和初步掌握,文字的形式由繁变简,反映了人类对信息传播效率需求的提高。
本章也介绍了数字的发展,人类发明数字,最早是为了计数,随着人类所需计数的数目越来越大,数字的表达形式也在不断优化,进位制的发明是人类在科学上的一大飞跃,表明了我们的祖先懂得对数量开始编码,基于进位制,各种数字形式孕育而生,如罗马数字,但当需要表达几万的大数字时罗马数字又过于繁琐,与文字的简化类似,印度人发明了阿拉伯数字,能够脱离文字形式单独的简洁的表达数学,这是数学史上的一个伟大成就。
纵观整个语言文字,数字的发展演变史,尽管在历史上存在无数的文字、语言,但这些各具特点的信息形式最终都殊途同归,它们的诞生都源于人类对信息表达的渴望,而不同的具象文字背后都是对同一抽象信息的表示,人类交流的过程实际上就是“编码”到“译码”的过程:人们在写文字时或用语言交谈时,实际上是把抽象的信息用具象的形式通过“编码”表达出来,然后另一方接受信息实际上存在着“译码”的过程,将文字或语言转化成原始信息再以接受。如今语言学者所研究的问题,实际上古人在发明语言文字时都遇到过,且用和现代类似的方法解决了。文字、语言和数字这些各种各样的信息背后仿佛有一只“看不见的手”,它巧妙的控制着信息的发展史,如今的我们也处在这个历史之中,现代计算机的发展正是信息发展和进步的一大继承,我们作为计算机专业的学子,更需不断钻研于科学,探索信息背后的数学奥妙,弄清信息发展的数学规律。
Reference:https://blog.csdn.net/doubleintfloat/article/details/86552296