《编码规范和测试方法——C/C++版》学习笔记 ·002
文章目录
- 一、相关知识补充
- 1、switch接受的参数类型
- 2、内存分区与数据存放
- 3、变量的作用域与生命期
- 4、调试开关的使用
- 二、规范事项
- 1、杂项
- (1).for循环语句中只出现影响循环控制的变量
- (2).不要比较指针类型的变量
- (3).不要在sizeof运算符中使用自增自减
- (4).逻辑表达式中的每一个逻辑判断都加上括号
- 2、循环语句的效率
- (1).对不同的情况使用适当的循环体
- (2).建议for循环采用“左闭右开区间”写法
- (3).建议将高循环次数的循环置于嵌套循环的最内层
- (4).建议将高循环次数的循环体内的逻辑判断移到循环体外
- 3、if语句
- (1).if语句独占一行,执行语句不得紧跟其后
- (2).无论有几条执行语句,都要用大括号将执行语句括起来
- (3).else-if语句一定要包含最后的else节
- 4、switch语句
- (1).switch语句独占一行
- (2).每个case独占一行,执行语句不得紧跟其后
- (3).若某个case没有break需要给出确认性注释
- (4).一定要有default语句
- (5).真假两种处理不应采用switch语句,应采用if语句
- (6).case语句的先后顺序要使得执行次数尽可能少
- 5、for语句
- (1).for语句独占一行,执行语句不得紧跟其后
- (2).无论有多少条执行语句,都必须用大括号将执行语句括起来
- (3).空的循环体要给出确认性注释
- (4).循环计数尽量从0开始,不要从1开始。
- (5).不要在循环体内强制变更循环变量
- (6).for循环中禁用逗号运算符
- (7).尽量避免在循环内申请/释放内存
- 6、while语句
- (1).while语句独占一行,执行语句不得紧跟其后
- (2).无论多少条语句都要用大括号将执行语句括起来
- (3).空的循环体要给出确认信解释
- 7、return语句
- (1).return语句的返回值类型和函数声明的返回值类型相同
- (2).void返回值的函数return语句不应该有返回值
- (3).建议一个函数一条返回语句
- (4).禁止使用goto语句
- 8、初始化
- (1).在enum类型中,将成员全部初始化/都不初始化/只初始化最前连续的几个
- (2).初始化所有指针变量
- 9、代码格式
- (1).函数的参数一般不要超过7个
- (2).函数的大小不要过长,一般定为350行以内(去除注释、变量定义、调试开关)
- (3).嵌套语句需要4字符的缩进
- (4).用空行将代码逻辑片段进行划分
- (5).存储类型应该紧跟类型,而不是变量
- (6).在声明和定义处,将指针、引用[*, &]紧跟类型,而不是变量
- 10.函数
- (1).数组作为函数参数时,不需要指定数组大小
- (2).内定数据类型作为参数时,如果不需要修改就作为值传递而不是引用传递
- (3).使用标准库<ctype.h>或<cctype>里的函数进行字符判断
- (4).函数的声明和定义里参数标识应该保持一致
- (5).禁止函数返回局部变量的指针或引用
一、相关知识补充
1、switch接受的参数类型
switch接受的参数实际上是整型int,但是许多其他类型都可以被隐式转换为整型,所以这一点不是很明显。
2、内存分区与数据存放
如下图所示:
上述内存分区中,栈区的大小往往比堆区小很多,因此不宜在栈区申请过大的数组等。
当一个指针在堆区动态申请到一些空间时,相当与获得了堆区内存的访问权限,因此没有被申请的空间是无法访问的。
- 如果指针指向一个未被申请/已被释放的地址,则无权限访问,称为指针悬挂,这样的指针称为野指针
- 如果指针之前申请的空间未被收回,又更换了指向,则之前申请的内存将无法被别人访问,称为内存泄漏
3、变量的作用域与生命期
局部变量的作用域在代码块内,生命期持续到代码块调用结束。
全局变量的作用域是整个程序,生命期持续到程序执行结束。
堆区变量的生命期从申请内存空间开始,持续到释放内存空间结束。
4、调试开关的使用
调试开关主要通过#if
、#ifdef
、#ifndef
等预编译指令来实现。
二、规范事项
1、杂项
(1).for循环语句中只出现影响循环控制的变量
像下面这段代码中,num即为无关变量,定义、初始化可以放到for循环上面,num的迭代可以放到for循环里面。
for (int i = 0, num = 10; i < 5; ++i, ++num)
(2).不要比较指针类型的变量
指针变量的比较除了在数组里可能有意义,在其他大部分时候是没有意义的。
(3).不要在sizeof运算符中使用自增自减
增强可读性,避免出错。
(4).逻辑表达式中的每一个逻辑判断都加上括号
勤加括号,避免混淆不同运算符的优先级。
2、循环语句的效率
(1).对不同的情况使用适当的循环体
- 有明确循环次数,一般选择for循环
- 没有明确循环次数,一般选择while循环
- 至少循环1次,一般选择do while循环
(2).建议for循环采用“左闭右开区间”写法
不建议写成以下形式:
for (int i = 0; i <= 4; ++i)
建议写成以下形式:
for (int i = 0; i < 5; ++i)
(3).建议将高循环次数的循环置于嵌套循环的最内层
可以减少CPU跨切循环层的次数,从而优化程序性能。
(4).建议将高循环次数的循环体内的逻辑判断移到循环体外
3、if语句
(1).if语句独占一行,执行语句不得紧跟其后
(2).无论有几条执行语句,都要用大括号将执行语句括起来
便于以后的维护。
(3).else-if语句一定要包含最后的else节
增强可读性,避免出错。
4、switch语句
(1).switch语句独占一行
(2).每个case独占一行,执行语句不得紧跟其后
(3).若某个case没有break需要给出确认性注释
避免漏加而出错
(4).一定要有default语句
使switch语句完整。
(5).真假两种处理不应采用switch语句,应采用if语句
(6).case语句的先后顺序要使得执行次数尽可能少
各个case的顺序尽可能从以下顺序中选择有效的:
- 按出现频率的顺序,将频繁出现的处理放在前面
- 按照常见性的顺序,从通常的case到例外的case
- 按数值或字母的顺序
5、for语句
(1).for语句独占一行,执行语句不得紧跟其后
(2).无论有多少条执行语句,都必须用大括号将执行语句括起来
便于以后的维护。
(3).空的循环体要给出确认性注释
(4).循环计数尽量从0开始,不要从1开始。
(5).不要在循环体内强制变更循环变量
增强可读性,避免出错。
(6).for循环中禁用逗号运算符
增强可读性,避免出错。
(7).尽量避免在循环内申请/释放内存
防止产生内存泄漏。
6、while语句
(1).while语句独占一行,执行语句不得紧跟其后
(2).无论多少条语句都要用大括号将执行语句括起来
便于以后的维护。
(3).空的循环体要给出确认信解释
7、return语句
(1).return语句的返回值类型和函数声明的返回值类型相同
类型不同的时候可能会触发一个隐式强制类型转换。
但是在有些时候,将范围大的类型转换成范围小的类型时,会产生高位截断,如以下代码:
#include <cstdio>char func()
{int a = 0x1010;return a;
}int main()
{char ch = func();printf("%#x", ch); // 0x10return 0;
}
(2).void返回值的函数return语句不应该有返回值
(3).建议一个函数一条返回语句
不建议使用下面的格式:
int func()
{int a = 100;if (a > 50)return 100;elsereturn 0;
}
建议使用下面的格式:
int func()
{int res;int a = 100;if (a > 50)res = 100;elseres = 0;return res;
}
(4).禁止使用goto语句
goto语句往往会破坏代码的执行结构,让代码难以理解,除了极少数的特殊的适用场景下,很少会用到。
有一种场景就是多个变量动态申请内存空间。
- 一开始的代码如下,这样写存在内存泄漏的问题,如果q申请空间失败,p的内存没有回收,就会有内存泄漏。
int func() {int *p, *q;p = (int*)malloc(4 * sizeof(int));if (NULL == p){printf("malloc fail\n");return 0;}q = (int*)malloc(4 * sizeof(int));if (NULL == q){printf("malloc fail\n");return 0;}return 1; }
- 因此,需要一个统一的申请失败终点,如以下代码
int func() {int *p, *q;p = (int*)malloc(4 * sizeof(int));if (NULL == p){printf("malloc fail\n");goto End;}q = (int*)malloc(4 * sizeof(int));if (NULL == q){printf("malloc fail\n");goto End;}return 1;End:if (NULL == p){free(p);}if (NULL == q){free(q);}return 0; }
类似的场景还有文件的打开。
8、初始化
(1).在enum类型中,将成员全部初始化/都不初始化/只初始化最前连续的几个
(2).初始化所有指针变量
9、代码格式
(1).函数的参数一般不要超过7个
从汇编角度来看,函数有4个参数时传递效率最高,因为在不超过4个参数的时候是通过寄存器来传递参数的,超过了就得借助栈空间来传递。
当参数过多时,应该考虑将参数定义为一个结构体,并将结构体指针作为参数
(2).函数的大小不要过长,一般定为350行以内(去除注释、变量定义、调试开关)
提高可读性,便于以后的维护,遵循函数设计原则。
(3).嵌套语句需要4字符的缩进
(4).用空行将代码逻辑片段进行划分
增加可读性。
(5).存储类型应该紧跟类型,而不是变量
存储类型有auto、static等。
举个例子,应该使用static int a;
而不是int static a;
(6).在声明和定义处,将指针、引用[*, &]紧跟类型,而不是变量
在这一点往往不同的公司要求不同。举个例子,一种是int* a
,另一种是int *a;
10.函数
(1).数组作为函数参数时,不需要指定数组大小
数组作为参数传递的是首地址,因此指定数组大小也是没有意义的。
(2).内定数据类型作为参数时,如果不需要修改就作为值传递而不是引用传递
(3).使用标准库<ctype.h>或<cctype>里的函数进行字符判断
提高代码效率,使代码更加精简。
(4).函数的声明和定义里参数标识应该保持一致
(5).禁止函数返回局部变量的指针或引用
《编码规范和测试方法——C/C++版》学习笔记 ·002相关推荐
- 《编码规范和测试方法——C/C++版》作业 ·002——函数返回地址、static关键词用法整理
文章目录 一.函数返回地址的情形 1.函数返回值为指针 二.static关键字用法整理 1.static全局变量 2.static局部变量 3.static函数 4.类的static成员数据 5.类的 ...
- 《编码规范和测试方法——C/C++版》学习笔记 ·001
文章目录 一.编码规范的目的 二.相关知识补充 1.32位机下C++中各变量占用的字节数 2.按位操作 三.规范事项 1.把常量放在==左边 2.按位位移操作的右操作数必须小于操作的位数 3.不要对有 ...
- 《编码规范和测试方法——C/C++版》作业 ·003——宏定义作用整理、设计删除数组元素的函数
文章目录 一.宏定义(#define)的作用 1.普通宏 2.带参宏 [注]:特殊用法 3.其他用法和注意点 二.实际问题(函数设计) 1.原题 2.题解参考 (1).面向过程的设计 (2).面向对象 ...
- 《编码规范和测试方法——C/C++版》作业 ·008——编写一个符合依赖倒置原则的简单学生管理系统
文章目录 问题描述 参考解答 整体架构 UML图 整体代码 MySQL-C-API封装 Model层 Dao层 Service层 Controller层 View层 主程序 测试环境 测试流程 测试效 ...
- 《编码规范和测试方法——C/C++版》作业 ·007——C++引入MySQL给C的API并简单封装
文章目录 问题描述 参考解答 API引入 API测试 一些问题 封装代码 测试环境 测试代码 测试结果 问题描述 使用MySQL为C提供的API,封装出一个访问MySQL数据库的类.要求至少能实现如下 ...
- 《编码规范和测试方法——C/C++版》作业 ·006——设计模式 · 模板方法
文章目录 一.设计模式-模板方法 1.简单介绍 2.框架演示 3.实际案例 一.设计模式-模板方法 1.简单介绍 简单来说,就是先在父类FFF中定义好一个函数AAA,然后这个函数AAA代表了一个操作M ...
- 《编码规范和测试方法——C/C++版》作业 ·005——设计一组员工类
问题描述 Cola公司的雇员分为以下若干类:ColaEmployee :所有员工总的父类属性:员工的姓名,员工的生日月份方法:getSalary(int month) 根据参数月份来确定工资,如果该月 ...
- 《编码规范和测试方法——C/C++版》作业 ·004——设计一个顺序表
问题描述 实现一个能够实现自动扩容ArrayList类的封装(不使用C++容器),主要至少具有增加.删除.求长的功能 参考解答 ArrayList.h文件 #ifndef ARRAYLIST_H #d ...
- C++Primer第5版学习笔记(一)
C++Primer第5版学习笔记(一) 第一.二章的重难点内容 这个笔记本主要记录了我在学习C++Primer(第5版,中文版)的过程中遇到的重难点及其分析.因为第一.二章都比较简单,因 ...
最新文章
- 如何成为一个优秀的程序员
- 使用Android Studio的时候如何查看开发文档,API文档,doc文档,SDK文档
- 一步一步教你在 docker 容器下使用 mmdetection 训练自己的数据集
- 鸿蒙os2.0游戏体验,华为运行鸿蒙OS 2.0体验:界面近似EMUI 11
- 解决 WPF 绑定集合后数据变动界面却不更新的问题
- RabbitMQ六种队列模式-简单队列模式
- php response响应,9. 响应 (Response)
- 一个有钱人儿子写的作文!
- 首次公开!华为最前沿的X Labs实验室都在研究什么?5G+CV
- Asp.Net MVC使用HtmlHelper渲染,并传递FormCollection参数的陷阱
- android7 编译配置摄像头,MTK平台新增摄像头指南 -- 已更新android 7.0路径的更改。...
- python实现蒙特卡洛算法_用Python实现基于蒙特卡洛算法小实验
- 虹软java接摄像头_java基于虹软sdk实现人脸识别(demo)
- ORACLE 常用脚本(4)
- ATtiny85单片机制作PCB小提琴
- Unity 资源池,对象池,Object Poor
- JS仿iGoogle自定义首页模块拖拽效…
- CSAPP第五章家庭作业(原书第二版)
- PokemonGo:LBS游戏开发
- 安卓java代码ping网关_Android代码中使用Ping命令
热门文章
- 美国计算机科学奥林匹克竞赛试题,中学信息奥林匹克竞赛试题精选.doc
- 怎么更改滚动条的位置php,给网站顶部添加一个滚动条位置百分比教程
- matlab 自带pca函数,matlab实现主成分分析 princomp函数 PCA中有这个函数
- 可以判断用户打开页面次数吗?_看前端如何单枪匹马实现小程序页面级版本控制...
- 动态规划——最长公共子序列
- Python——如何屏蔽函数内部的print输出
- 《南溪的目标检测学习笔记》——COCO数据集的学习笔记
- 机器学习 Machine Learning中向量化矩阵化的技巧
- 【超简单已实现】CSDN实现点击跳转到指定段落
- pip 安装 rdkit