知识屋:更实用的电脑技术知识网站
所在位置:首页 > 科技

c++编程思路

发表时间:2022-03-25来源:网络

一、基本准备工作

1、设计工程目录结构

(1)基本原则:

【1】工程本身的文件、项目编译生成的中间文件放一个文件夹;

【2】最终生成的目标文件单独放一个文件夹;

【3】如果有工程依赖的库文件等单独放一个文件夹;

【4】用户代码文件放单独一个文件夹,或者将头文件和源文件单独分开放置;

【5】用户代码文件里面如果有比较重要的功能模块单独放一个文件夹,如陀螺仪,气压计,光感,音乐,灯效,图片,字库等。

【6】重要的项目资料单独放一个文件夹保存,如硬件原理图,软件框架图,通信协议,复杂重要功能的说明等等。

【7】必须维护一个软件版本升级记录文档,也可以在某个主要的代码文件内维护(不推荐)。

【8】可以为一些代码阅读工具需要的生成文件开一个文件夹,如SourceInsight。

(2)举例

【1】linux

【2】arm9

【3】stm32

2、版权和版本的申明

(1)基本原则:

位置:位于说明文件或者源文件头部,或者源文件和头文件都加上版本声明。

内容:版权、文件名,概要;版本号-作者-日期+代码更新信息,备注信息;

(2)举例:

【1】

@头文件注释带上函数功能的简要说明,但如果在头文件有对外接口的函数声明,则在函数声明上进行函数功能的注释。

【2】源文件,说明此模块功能,主要函数,被其他函数调用的接口

【3】源文件和头文件都加上版本声明

STM32F10x_FWLib/stm32f10x_adc.h /******************************************************************************** * @file stm32f10x_adc.h * @author MCD Application Team * @version V3.5.0 * @date 11-March-2011 * @brief This file contains all the functions prototypes for the ADC firmware * library. ****************************************************************************** * @attention * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS ****************************************************************************** */STM32F10x_FWLib/stm32f10x_adc.c /** ****************************************************************************** * @file stm32f10x_adc.c * @author MCD Application Team * @version V3.5.0 * @date 11-March-2011 * @brief This file provides all the ADC firmware functions. ****************************************************************************** * @attention * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS ****************************************************************************** */

3、头文件的结构和作用

(1)头文件开头处的版权和版本声明。

(2)预处理块。

#ifndef/#def/#endif  防止头文件被重复引用。

(3)其他头文件、函数和类结构声明等。

[1]#include :引用标准库的头文件,编译器将从标准库目录开始搜索。

#include “filename.h”:引用非标准库的头文件,编译器从用户的工作目录开始搜索。

[2]变量和函数,头文件只存声明,不存定义。

@extern规范用法:

[1]不提倡用全局变量,不用extern int value; 这类声明;

[2]必须使用时,要规范用法。不要在一个源文件中直接用extern调用另个一文件的变量。而是:

在1.h头文件中声明extern int value;在2.h里面包含1.h用来调用value。

二、排版和代码行基本规则

目的:使代码布局整齐清晰,便于阅读和理解。

1、起始代码的缩进:

      函数或过程的开始、结构的定义及循环、判断等语句中的代码都要采用缩进风格, case语句下的情况处理语句也要遵从语句缩进要求。

2、缩进规则:

【1】缩进风格:程序块要采用缩进编写,缩进的空格数一般为4个。

【2】不用TAB用空格:以免用不同的编辑器阅读程序时,因 TAB 键所设置的空格数目不同而造成程序布局不整齐。

3、程序块大括号对齐:

【1】WIN和嵌入式底层:程序分界符" {"和“ }”:应该独占一行并且两者位于同一列,同时与引用他们的语句左对齐;

【2】linux:‘{’位于上一行的行末,此时‘}’与‘{’所在行的行首对齐,‘{’前至少有一个空格。

for (...) { //多在linux底层和linux应用编程,单片机嵌入式未见此种用法。

... // program code

}  

===

for (...) //windows一般统一用下面这个格式。。。

{

... // program code

}

4、空行:

      每个函数定义结束后,相对独立的程序块之间(逻辑密切除外)、变量说明和程序块中间之后必须加空行。

5、标志符语句独占一行:

      if、 for、 do、 while、 case、 switch、 default等语句自占一行,不论语句的执行语句部分无论多少都要加括号{}。

6、长句拆分:

(1)单行单语句,一行不超过一个语句:

      不允许把多个短语句写在一行中,即一行只写一条语句。

(2)语句的拆分:

      代码长度最好控制在70-80个字符以内,较长的语句( >80字符)要分成多行书写。

      函数或过程中的参数较长,循环、判断等语句中有较长的表达式或语句,要进行适应的划分,长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要进行适当的缩进,使排版整齐,语句可读。

【1】report_or_not_flag = ((taskno < MAX_ACT_TASK_NUMBER)

                                            && (n7stat_stat_item_valid (stat_item))

                                            && (act_task_table[taskno].result_data != 0));

【2】for (i = 0, j = 0; (i < BufferKeyword[word_index].word_length)

                                  && (j < NewKeyword.word_length); i++, j++)

【3】 CANx->sTxMailBox[transmit_mailbox].TDLR = (((uint32_t)TxMessage->Data[3] Data[2] Data[1] Data[0]));

7、代码行内的空格和修饰符、括号等:

【1】关键字后留空格:C语言的32个关键字,如if/while/do/case ();

if (NewState != DISABLE)

【2】函数名后不留空格:紧跟括号( , 区别关键字.

void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);

【3】紧跟:(号向后紧跟, )和,和;向前紧跟,不留空格;   int a, b, c;

【4】二元操作符:前后加空格;==对等操作

【5】一元操作符:前后不加空格;如"[ ]"和" . "和"->"这类操作符前后不加空格.==关系密切的立即操作符

【6】对于表达式比较长的for语句和if语句,为了紧凑起见可以适当地去掉一些空格:

           if ((a>=b) && (c

     m_width = width;

m_height = height;

(2)类型部分:

数组 a

指针 p

函数 fn

无效 v

句柄 h

长整型 l

布尔 b

浮点型(有时也指文件) f

双字  dw

字符串  sz

短整型  n

双精度浮点 d

计数 c(通常用cnt)

字符 ch(通常用c)

整型 i(通常用n)

字节 by

字 w

实型 r

无符号 u

(3)描述部分:

最大 Max

最小 Min

初始化 Init

临时变量 T(或Temp)

源对象 Src

目的对象 Dest

(4)举例:

hwnd : h 是类型描述,表示句柄, wnd 是变量对象描述,表示窗口,所以 hwnd 表示窗口句柄;

pfnEatApple : pfn 是类型描述,表示指向函数的指针, EatApple 是变量对象描述,所以它表示指向 EatApple 函数的函数指针变量。

g_cch : g_ 是属性描述,表示全局变量,c 和 ch 分别是计数类型和字符类型,一起表示变量类型,这里忽略了对象描述,所以它表示一个对字符进行计数的全局变量。

五、宏、全局变量和其他注意

1、宏的使用+定义规范:

(1)由来:不易理解的数字和常量则用有意义的枚举或者宏来替代:

#define BUFF_SIZE          1024

input_data = (char *)malloc(BUFF_SIZE);

(2)宏定义规范

【1】括号:宏定义表达,需要完整的括号。

#define GET_AREA(a,b)     ((a) * (b))

【2】大括号:宏中有多条语句,应将语句放在一对大括号中。

#define INTI_RECT_VALUE( a, b ) {\

            a = 0;\

            b = 0;\

}

2、全局变量:

【1】避免使用: 尽量避免使用,它占用程序空间,同时增大了模块间的耦合性,不利于软件维护。

【2】规范:应明确其含义、作用、取值范围。明确全局变量与操作此变量的函数的关系,如创建、访问、修改。

3、其他原则

[1]专一:一行代码只做一件事情,如只定义一个变量,或只写一条语句。---易阅读和注释。

[2]就近原则:尽可能在定义变量的同时初始化该变量。

[3]数据大小端统一:通信协议中数据的大小端要和整个团队形成统一。

六、函数和类:

====函数

【1】函数名:应能准确描述函数功能,一般以动词加宾语的形式;print_record

【2】参数个数:不宜过多,1-3个为好;

【3】返回值:清楚、明了,让调用者不易忽视错误情况。每种错误的返回值要清晰、明确,防止调用者误用;

@linux中函数的返回值:正常的时候返回0,错误的时候返回-1或者小于零的错误码。

@WINDOWS和stm32函数返回值:

如果GetCommState()函数调用成功,则返回值大于零。若函数调用失败,则返回值为零,如果想得到进一步的错误信息,可以调用GetLastError()函数来获取。

【4】输入参数:检查其有效性,如指针型参数判断是否为空,数组成员是否越界等等;

【5】规模:限制在200行以内(不含空行和注释行);

【6】功能专一:一个函数完成一个特定功能;

【7】功能可预测:输入数据相同,能得到可预期的输出;

【8】代码重用:多段代码重复做一件事,考虑将重复功能实现成一个函数;

【9】独立性:减少与其他函数的联系,提高可读性、维护性和效率。

避免函数本身和函数间的递归调用,递归影响可读性和系统资源如栈空间。

====类的版式

类可以将数据和函数封装在一起,其中函数表示了类的行为(或称服务)。类提供关键字public、protected和private,分别用于声明哪些数据和函数是公有的、受保护的或者是私有的。

主张提倡的书写方式:将public类型的函数写在前面,而将private类型的数据写在后面,这种版式的程序员主张类的设计“以行为为中心”,重点关注的是类应该提供什么样的接口(或服务)。即首先考虑类应该提供什么样的函数。“这样做不仅让自己在设计类时思路清晰,而且方便别人阅读。因为用户最关心的是接口,谁愿意先看到一堆私有数据成员!”

class A

{

 public:

  void Func1(void);

  void Func2(void);

  …

 private:

int   i, j;

float  x, y;

    …

}

=========================================

七、编程规范杂烩:

1、变量和零值比较

  分别给出BOOL,int,float,指针变量 与“零值”比较的 if 语句(假设变量名为var)。

  解答:

   BOOL型变量:if(var)  if(!var)    int型变量: if(var==0)    float型变量:     const float EPSINON = 0.000001;     if ((x >= - EPSINON) && (x =”或“
收藏
  • 人气文章
  • 最新文章
  • 下载排行榜
  • 热门排行榜