文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>linux C编程(2)--编码风格

linux C编程(2)--编码风格

时间:2006-08-06  来源:davidxueer

下面的代码是GNU emacs其中的一段代码。

/* Interface from Emacs to terminfo.

   Copyright (C) 1985, 1986 Free Software Foundation, Inc.

 

This file is part of GNU Emacs.

 

GNU Emacs is free software; you can redistribute it and/or modify

it under the terms of the GNU General Public License as published by

the Free Software Foundation; either version 2, or (at your option)

any later version.

 

GNU Emacs is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

GNU General Public License for more details.

 

You should have received a copy of the GNU General Public License

along with GNU Emacs; see the file COPYING.  If not, write to

the Free Software Foundation, Inc., 59 Temple Place - Suite 330,

Boston, MA 02111-1307, USA.  */

 

#include <config.h>

#include "lisp.h"

 

/* Define these variables that serve as global parameters to termcap,

   so that we do not need to conditionalize the places in Emacs

   that set them.  */

 

char *UP, *BC, PC;

 

/* Interface to curses/terminfo library.

   Turns out that all of the terminfo-level routines look

   like their termcap counterparts except for tparm, which replaces

   tgoto.  Not only is the calling sequence different, but the string

   format is different too.

*/

 

char *

tparam (string, outstring, len, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)

     char *string;

     char *outstring;

     int arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9;

{

  char *temp;

  extern char *tparm();

 

  temp = tparm (string, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);

  if (outstring == 0)

    outstring = ((char *) (xmalloc ((strlen (temp)) + 1)));

  strcpy (outstring, temp);

  return outstring;

}

分析上面的代码可以看出GNU的编码风格如下所示。

●       函数开头的左花括号放到最左边,避免把任何其他的左花括号、左括号或者左方括号放到最左边。

●       尽力避免让两个不同优先级的操作符出现在相同的对齐方式中。

●       每个程序开头都应该有一段简短地说明其功能的注释。例如GNU emacs上面的代码中的注释如下所示。

/* Define these variables that serve as global parameters to termcap,

   so that we do not need to conditionalize the places in Emacs

   that set them.  */

●       每个函数都书写注释,以说明函数做了些什么,需要哪些种类的参数,参数可能值的含义以及用途。

●       不要跨行声明多个变量。在每一行中都以一个新的声明开头。

●       当在一个if语句中嵌套了另一个if-else语句时,应用花括号把if-else括起来。

●       要在同一个声明中同时说明结构标识和变量,或者结构标识和类型定义(typedef)。

●       尽量避免在if的条件中进行赋值。

●       在名字中使用下划线以分隔单词,尽量使用小写;在宏或者枚举中通常使用大写常量。

●       使用一个命令行选项时,给出的变量应该在选项含义的说明之后,而不是选项字符之后。

看了上面两种风格的介绍,读者是不是觉得有些太多了,难以记住?不要紧,Linux有很多工具来帮助我们。除了vim和emacs以外,还有一个非常有意思的小工具 indent可以帮我们美化C/C++源代码。

下面用这条命令将Linux 内核编程风格的程序quan.c转变为GNU编程风格。

[david@localhost ~]$ indent -gnu quan.c

利用indent这个工具,大家就可以方便地写出漂亮的代码来。

 

更为详细的GNU的编码风格,读者可以在

http://www.gnu.org/prep/standards/standards.html阅读Richard Stallman所写的《GNU Coding Standards》一文。

下面是 Linux 内核2.6.13中的\arch\i386\kernel中的numaq.c的节选代码,现在并不要求读懂此代码,而是看Linux的内核编程风格。

/*

 * Written by: Patricia Gaughen, IBM Corporation

 *

 * Copyright (C) 2002, IBM Corp.

 *

 * All rights reserved.         

 *

 * This program is free software; you can redistribute it and/or modify

 * it under the terms of the GNU General Public License as published by

 * the Free Software Foundation; either version 2 of the License, or

 * (at your option) any later version.

 *

 * This program is distributed in the hope that it will be useful, but

 * WITHOUT ANY WARRANTY; without even the implied warranty of

 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or

 * NON INFRINGEMENT.  See the GNU General Public License for more

 * details.

 *

 * You should have received a copy of the GNU General Public License

 * along with this program; if not, write to the Free Software

 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

 *

 * Send feedback to <[email protected]>

 */

#include <linux/config.h>

#include <linux/mm.h>

#include <linux/bootmem.h>

#include <linux/mmzone.h>

#include <linux/module.h>

#include <linux/nodemask.h>

#include <asm/numaq.h>

#include <asm/topology.h>

#include <asm/processor.h>

 

#define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT))

 

/*

 * Function: smp_dump_qct()

 *

 * Description: gets memory layout from the quad config table.  This

 * function also updates node_online_map with the nodes (quads) present.

 */

static void __init smp_dump_qct(void)

{

int node;

struct eachquadmem *eq;

         struct sys_cfg_data *scd =

                 (struct sys_cfg_data *)__va(SYS_CFG_DATA_PRIV_ADDR);

 

nodes_clear(node_online_map);

for_each_node(node) {

               if (scd->quads_present31_0 & (1 << node)) {

                      node_set_online(node);

                     eq = &scd->eq[node];

                      /* Convert to pages */

                      node_start_pfn[node] = MB_TO_PAGES(

                             eq->hi_shrd_mem_start - eq->priv_mem_size);

                   node_end_pfn[node] = MB_TO_PAGES(

                            eq->hi_shrd_mem_start + eq->hi_shrd_mem_size);

             memory_present(node,

                             node_start_pfn[node], node_end_pfn[node]);

                      node_remap_size[node] = node_memmap_size_bytes(node,

                                               node_start_pfn[node],

                                               node_end_pfn[node]);

}

}

}      

分析以上代码可以得出Linux内核代码的风格如下:

●       缩进采用的是tab制表符。

●       在if或者for循环中,将开始的大括号放在一行的最后,而将结束大括号放在本段语句结束行的第一位,但是函数中的大括号除外。

●       命名系统。变量命名尽量使用简短的名字,简写或者单词间采用了_ 隔开,比如代码中的sys_cfg_data。

●       函数最好要短小精悍,一个函数最好只做一件事情,而且函数中的变量一般都不超过10个,大小一般都小于80行。

●       注释。一个模块的注意一般注明了作者、版权、注释说明代码的功能,而不是说明其实现原理,这也和Linux的文化有关,Linus Torvald在回答有人问题时,经常说的第一句话说的第一句话是"阅读源代码(RTFSC)"(Read the fucking source code)

看了上面两种风格的介绍,读者是不是觉得有些太多了,难以记住?不要紧,Linux有很多工具来帮助我们。除了vim和emacs以外,还有一个非常有意思的小工具 indent可以帮我们美化C/C++源代码。

下面用这条命令将Linux 内核编程风格的程序quan.c转变为 GNU编程风格,代码如下:

[david@localhost ~]$ indent -gnu quan.c

利用indent这个工具,大家就可以方便地写出漂亮的代码来。

以上分别学习了GNU编码风格和Linux内核编码风格,两种风格之间体现着两种不同的文化精神,有些地方相似,有些地方迥然不同,但是目的只有一个形成一个清晰、美观、可维护、方便扩展的代码。而在实际项目开发中作者提出以下建议。

●       关于主函数。主函数如果不考虑命令行参数的话,可以写成

int main(void)

如果有命令参数的话可以写成

int main( int argc, char **argv )

●       关于缩进。可以采用空格或者tab制表符,但是在同一代码中不要混合使用tab指标符号,或者空格,因为大家可能使用不同的编辑器,有些编辑器认为一个tab制表符相当于8个空格,而有些编辑器认为是3个空格,容易造成代码结构的混乱。

●       关于命名规则。在通常情况下,具有前缀和后缀的下划线的名称是为系统用途而保留的,如_sys_等,不应当用于任何用户创建的名称。变量名称的命名规则可以参考Linux内核命名规则,简介但是有效。但还要注意以下宿订约成:

à       #define 常量应全部大写。

à       num 常量应以大写字母开头或全部大写。

à       函数、类型定义(typedef)和变量名以及结构(struct)、联合(union)和枚举(enum)标记名称应小写。

关于指针。声明指针的限定符号应该在变量前面,而不是类型后面,如下代码

char *david,*xueer;

而不应该是下面这样

char* david,xueer;

关于注释。注释的益处对于读者来说不言自明。不能过量的使用注释,在没一行都用注释,不但增加了工作量,还会使得代码比较乱。综合GNU编码风格和Linux内核编码风格,在实际项目中可以采用以下编码风格:每个模块要注明作者、版本历史、最后修改时间、实现的功能以及接口,对每个函数说明其原理‘在关键算法部分进行说明’或者在作者认为比较晦涩的代码部分也要作相关的注释。缩进采用的是tab制表符。
排行榜 更多 +
进击的小动物安卓版

进击的小动物安卓版

飞行射击 下载
进攻yalghaar

进攻yalghaar

飞行射击 下载
深空战场

深空战场

飞行射击 下载