高质量C/C++编程指南笔记
1.文件结构
版权和版本的声明
版权和版本的声明位于头文件和定义文件的开头,主要内容有:
(1)版权信息。
(2)文件名称,标识符,摘要。
(3)当前版本号,作者/修改者,完成日期。
(4)版本历史信息。
下面是一个例子:
1 /** Copyright (c) 2011,xx有限公司xx部
2 * All rights reserved.
3 *
4 * 文件名称:filename.h
5 * 文件标识:见配置管理计划书
6 * 摘要:描述本文件的内容
7 *
8 * 当前版本:1.0
9 * 作者:
10 * 完成日期:3/18/2011
11 *
12 * 取代版本:0.9
13 * 原作者:
14 * 完成日期:2/18/2011
15 */
头文件中只存放“声明”而不存放“定义”
在 C++ 语法中,类的成员函数可以在声明的同时被定义,并且自动成为内联函数。这虽然会带来书写上的方便,但却造成了风格不一致,弊大于利。因此建议将成员函数的定义与声明分开,不论该函数体有多么小。
我为什么要使用头文件?他的作用呢?
(1)通过头文件来调用库功能。在很多场合,源代码不便(或不能)向用户公布,只要向用户提供头文件和二进制的库即可。用户只需要按照头文件中的接口声明来调用库功能,而不必关心接口怎么实现的。编译器会从库中提取相应的代码。(ps:也就是源代码的安全性和程序的易用性吧。)
(2)头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件中的声明不一致,编译器就会指出错误,这一简单的规则能大大减轻程序员调试、改错的负担。。
2.程序的版式
空行怎么用?
1)在每个类声明之后、每个函数定义结束之后都要加空行。
2)在一个函数体内,逻揖上密切相关的语句之间不加空行,其它地方应加空行分隔。比如if和紧接的else之间就不需要空行了。
实例如下:
1 while (condition)
2 {
3 statement1;
4 // 空行
5 if (condition)
6 {
7 statement2;
8 }//和紧接的else就不加空行了
9 else
10 {
11 statement3;
12 }
13 // 空行
14 statement4;
15 }
代码行怎么写的“漂亮”些?
1)一行代码只做一件事情,如只定义一个变量,或只写一条语句。这样的代码容易阅读,并且方便于写注释。
2)if、for、while、do 等语句自占一行,执行语句不得紧跟其后。应在下一行使用“{”,再下一行写执行语句,不论执行语句有多少都要加{}。这样可以防止书写失误。
代码行内的空格风格?
看下面的表格,注意空格哦:
良好的风格 |
不良的风格 |
void Func1(int x, int y, int z); |
void Func1 (int x,int y,int z); |
if (year >= 2000) |
if(year>=2000) |
if ((a>=b) && (c<=d)) |
if(a>=b&&c<=d) |
for (i=0; i<10; i++) |
for(i=0;i<10;i++) for (i = 0; I < 10; i ++) |
x = a < b ? a : b; |
x=a<b?a:b; |
int *x = &y; |
int * x = & y; |
array[5] = 0; |
array [ 5 ] = 0; |
a.Function(); |
a . Function(); |
b->Function(); |
b -> Function(); |
表达式太长?拆了他
长表达式要在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符)。拆分出的新行要进行适当的缩进,使排版整齐,语句可读。
修饰符还是不随意的好
应当将修饰符 * 和& 紧靠变量名
例如:
char *name;
int *x, y; // 此处y 不会被误解为指针
int* x, y; // 此处y 会被误解为指针
命名规则
命名规则尽量与所采用的操作系统或开发工具的风格保持一致。例如 Windows 应用程序的标识符通常采用“大小写”混排的方式,如AddChild。而Unix 应用程序的标识符通常采用“小写加下划线”的方式,如add_child。别混用
类名和函数名用大写字母开头的单词组合而成。如:class LeafNode;
变量和参数用小写字母开头的单词组合而成。如:int drawMode;
常量全用大写的字母,用下划线分割单词。如:const int MAX_LENGTH = 100;
静态变量加前缀s_(表示static)。如:static int s_initValue;
如果不得已需要全局变量,则使全局变量加前缀g_(表示global)。如:int g_howManyPeople;
类的数据成员加前缀m_(表示member),这样可以避免数据成员与成员函数的参数同名。如:
void Object::SetValue(int width, int height)
{
m_width = width;m_height = height;
}
运算符的优先级和结合率
虽然有这个表,但是记住的人不多,,所以为了自己和阅读代码的人,语句长了还是用括号吧
if语句
假设布尔变量名字为 flag,它与零值比较的标准if 语句如下:
if (flag) // 表示flag 为真
if (!flag) // 表示flag 为假
其它的用法都属于不良风格,就不要用了。
如果变量是整型假设整型变量为 value,它与零值比较的标准if 语句如下:
if (value == 0)
if (value != 0)
这时候就不要用上面那种写法了,很容易产生value是布尔类型的误解。
如果是浮点型变量就需要有误差比较,
if ((x-0>=-EPSINON) && (x-0<=EPSINON)) //其中EPSINON 是允许的误差(即精度)。其他的比如比较两个浮点数相等也可以这样来,把0改成被比较的数就行了。
如果是指针变量
if (p == NULL) // p 与NULL 显式比较,强调p 是指针变量if (p != NULL)
循环语句的效率
C++/C 循环语句中,for 语句使用频率最高,while 语句其次,do 语句很少用。
在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU 跨切循环层的次数,下面右边的效率比左边要高。
for (row=0; row<100; row++) { for ( col=0; col<5; col++ ) { sum = sum + a[row][col]; } } |
for (col=0; col<5; col++ ) { for (row=0; row<100; row++) { sum = sum + a[row][col]; } } |
如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面。
建议for 语句的循环控制变量的取值采用“半开半闭区间”写法。像这样:for (int x=0; x<N; x++) 循环次数N次。
3.常量
在C++ 程序中只使用const 常量而不使用宏常量,即const 常量完全取代宏常量(就是那个#define)。
不能在类声明中初始化const 数据成员,const 数据成员的初始化只能在类构造函数的初始化表中进行
4.函数设计
好了,不更新了,感觉还是原书要好很多,把原书传上来
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述