嵌入式之行(9):我的编程习惯与风格

说明:
1、编程风格因人而异,每个人都有自己的风格,因此,争论谁谁的风格,谁谁的习惯,等等问题是没有意义,也浪费时间。此处所讲的风格,绝对是个人的风格,不具有代表性,也不想将这些风格强加于人。
2、本文的风格只是在笔者学习过程中看书积累下来的,所以行文比较随意,不像大公司的编程规范手册那么规范。

3、本文不涉及C语言基本知识,如果连头文件格式也写不正确;对于“声明”和“定义”还搞不清楚,那只能再去看书,巩固基础知识了,笔者爱莫能助。

下面这些风格是当初学单片机时,自己想当然写的。

1、头文件:

头文件一般是声明外部或内部变量、函数以及定义的宏。一般不作变量的初始化。

其格式为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef __MY_TYPE_H__
#define __MY_TYPE_H__
.
.
.
#endf /* __MY_TYPE_H__ */

或:
#ifndef _MY_TYPE_H
#define _MY_TYPE_H
.
.
.
#endif /* _MY_TYPE_H */

两者均可以。

2、注释:

多行注释的格式为:

1
2
3
4
/*
* this is the comment…
* this is the comment…
*/

单行注释为:

1
/* this is the comment */

请注意:

(1)、*与注释文字是有一个空格的;
(2)、在可能方便的情况下可以使用C++格式的注释,注释格式为:

1
// this is the comment

(3)、注释文字可为中文,亦可为英文,因人而定。

3、Tab宽度:

Tab宽度设置为8。特别情况可以设置为4。

5、函数和变量:

程序的变量、函数名称等均用小写表示,但定义的宏大写。函数一般为有表示动作的词语,如有多于两个词,中间可以用下划线连接(即_),也可以不用,名称使用有意思的文字,如:

1
2
3
write_cmd(uint8 cmd)

write_command(uint8 command)

或者:

1
2
3
writecmd(uint8 cmd)

writecommand(uint8 command)

均为正确形式,可接受。首选第一种方式。但不能接受下列的函数:

1
2
3
4
int aa(int bb,int cc)
{
return bb + cc;
}

另外:文件名大写小写均可,但要统一使用同一种风格。

6、杂项:

(1)、程序一般均有头文件与相应的函数实现文件,如:M16_SPI.h和M16_SPI.c,在测试程序文件只需要#include “M16_SPI.h”即可。不能将所有函数、变量放在M16_SPI.c文件中,更不能出现#include “M16_SPI.c”这类情况,尽管编译器不会报错。
(2)、对于运算符号、逻辑符号等等空格问题,只要能突出主次符号即可,其他者形式不限。
(3)、对于一些C99新增特性,如使用的编译器支持者,采用之。如一般使用

1
for (int i=0;i<8;i++)

这类的形式。

近来多用emacs写程序,又配置了一些额外的工具,用起来比较顺手。因此,在原来基础上添加了一些额外的东西。

如果是在emacs下编程,注释风格使用doxymacs工具生成的注释风格(可以参考关于emacs那篇文章)。

对于某些符号的写法,如、&(别名那个,不是取地址那个)等,个人更喜欢将其靠近类型,如int p,这样,对于可以认为int*就是一种类型,而p就是变量(指针),不过int *p也可以。这个看情况而定。

函数与变量命令习惯要与所用平台一致。如在MFC中的CmyClass,C++中函数名setSize(),等等。如果在MFC中使用v4l2_init()函数会显得有点另类,应当使用V4L2Init(),而在Linux下使用V4L2Init()同样会显得另类。所谓“入乡随俗”是也。——当然,编译器才不管这个呢,但要记住,程序是写给人看的。

在大部分情况下,不做指针的运算,因为指针随平台(32位,64位)不同而不同。

头文件,只包含必要的头文件,虽然把无关的头文件都包含进去也没有什么错误,但总觉得这样做不太好。如果包含一些不常用的头文件,以注释形式给出程序中用到的函数或结构体。如

1
#include <strings.h> /*< bzero */

程序如文章,理应有“段落”之分。比如,所有变量的定义与语句之间空一行,每一种功能的语句之间空一行。至于如何使用空行,因情况而定,不能滥用之。如下面程序片段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 uint16 i = 0;
// 空一行
if (vd_info->is_streaming) /**< stop if it is still capturing */
v4l2_off(vd_info);
// 空一行
if (vd_info->frame_buffer)
free(vd_info->frame_buffer);
if (vd_info->tmp_buffer)
free(vd_info->tmp_buffer);
vd_info->frame_buffer = NULL;
/* it is a good thing to unmap! */
for (i = 0; i < NB_BUFFER; i++)
{
if (-1 == munmap(vd_info->mem[i], vd_info->buf.length))
error_out("munmap");
}
// 空一行
close(vd_info->camfd);
debug_msg("close OK!n");
// 空一行
return 0;

又:再次声明,编程风格绝对是个人的事情,别人无权强加意见于自己身上。我不接受别人对我的风格的批评,但也不会说服别人接受我的风格。但是,一个公司,一个团队,应该有一套自己的编程风格,应当遵循之。