zoukankan      html  css  js  c++  java
  • 19、Linux编码规范

    一、排版

    1.相对独立的程序块之间、变量声明之后必须加空行。

    int          conn_fd;

    int          ret;

        

    conn_fd = socket(AF_INET, SOCK_STREAM,0);

    if (conn_fd < 0)

    {

        perror("socket create");

    }

    2.程序块要采用缩进风格编写,缩进4空格或一个Tab键。

    3.对于较长的语句(超过个80字符)要分成多行书写,划分出的新行要进行适当的缩进,使排版整齐,语句可读。对于参数较长的函数也要划分成多行。

    ret = connect(conn_fd, (struct sockaddr *)&serv_addr,

                      sizeof (struct sockaddr));

    5.if、fordowhilecaseswitchdefault等语句各自占一行,且iffordowhile等语句的执行语句部分无论多少都要加括号{ }

    if (conn_fd < 0)

    {

         perror("socket create");

     }

    6.函数内的语句、结构的定义、循环和if语句中的代码都要采用缩进风格,case语句后的处理语句也要缩进。

    示例:

    typedef struct _port_segment

    {

         struct in_addr dest_ip; // struct相对于typedef缩进4个字符

         unsigned short int min_port;

         unsigned short int max_port;

    } port_segment;

    if (conn_fd < 0)

    {

         perror("socket create"); // perror缩进4个字符

    }

    for (i=portinfo.min_port; i<=portinfo.max_port; i++)

    {

          serv_addr.sin_port = htons(i); // serve_addr.sin_port缩进4个字符

    ...

    7.空格的使用

    1)以下语句在逗号后面加空格。

         int min_port, max_port;

    2"+""-""*""="等算术运算符两边都有一个空格。

         a = i + j;

    3"<"">="等比较操作符两边都有一个空格。

         if (conn_fd < 0) {

    4"!""""++""--""&"(地址运算符)等单目操作符前后不加空格。

         i++;

    5"->""."前后不加空格。

         portinfo.min_port = i * seg_len + 1;

    6ifforwhileswitch等与后面的括号间应加空格,以便使iffor等关键字更为突出明显。

         if (conn_fd < 0)

    二、注释

    1.程序文件(如以.h结尾头文件、以.c结尾的源程序文件)头部代码应进行注释。注释必须列出:版权说明、版本号、生成日期、作者、内容、功能、与其文件的关系、修改日志等。头文件的注释中还应有函数功能简要说明。

    示例

    /*

    * Copyright(C), 2007-2008, Red Hat Inc. // 版权声明

    * File name: // 文件名

    * Author:     // 作者

    * Version:   // 版本

    * Date: // 完成日期

    * Description: // 描述本文件的功能,与其他模块的关系

    * Function List: // 主要函数的列表,每条记录应包括函数名及功能简要说明

    * History:    // 修改历史,包括每次修改的日期、修改者和修改内容简述

    */

    2.函数头部应进行注释,列出函数的功能、输入参数、输出参数、返回值、调用关系等。

    示例:

    /*

    * Function:     // 函数名称

    * Description:   // 函数功能、性能等的描述

      * Calls:      // 被本函数调用的函数清单

    * Called By:     // 调用本函数的函数清单

    * Input:         // 输入参数说明,包括每个参数的作用

    * Output:        // 输出参数说明,有时通过指针参数返回一些变量值

    * Return:         // 函数返回值的说明

    * Others:        // 说明

    */

    3.注释应该在相应的代码附近,对代码的注释应放在其上方或右方(对单条语句的注释),不可放在下面,若放于上方则需与其上面的代码用空行隔开。

    4.对于所有有特定含义的变量、常量、宏、结构体等数据结构,如果其命名不是充分自注释的,在声明时都必须加上注释,说明其实际含义。变量、常量、宏的注释应放在其上方或右方。

    5.全局变量要有较详细的注释,包括功能,取值范围,哪些函数访问它,访问时的注意事项。

    6.对关键变量的定义、条件分支、循环语句必须写注释。这些语句往往是程序实现某一特定功能的关键代码,良好的注释能帮助理解程序,有时甚至优于看设计文档。

    7.避免在一行代码的中间插入注释。

    max_port  /* 只扫描11024的常用端口 */ = 1024;

    三、命名

    1.对于标识符的命名,要有自己的风格,一旦形成不可随意变更,除非团队项目开发中要求使用统一的风格。

    2.标识符的命名要清晰明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。

    示例:

    temp可以简写为tmp

    message可以简写为msg

    3.对于变量命名,禁止使用单个字符(如ijk),建议除了要有具体含义外,还能表明其数据类型等,但ijk作为局部循环变量是允许的。

    示例:

    int iwidth; // i表明该变量为int型,width指明是宽度

    //对于这一点,不同的人有不同的写法。linux下提倡简洁的变量命名方法,即“min-length&&max-information”原则,不建议大小写混合使用,一般标识符只由小写字母,数字和下划线构成;甚至于由于在linux下编程中所用的类型相对于windows而言相当少,在意义明确的场合,也不需要变量名前加类型标识。宏和常量用大写字母,用下划线分隔。

    4.命名规范必须与所使用的系统风格保持一致,如在Linux下变量命名一般是全小写加下划线的风格。

    一般使用:

    int min_port;

    5.除了头文件或结构体定义,应避免使用_ourhead_h_之类以下划线开始和结尾的定义。

    7.注意运算符的优先级,并用括号明确表达式的操作顺序。

    示例:

    if ((a | b) < (c & d))

    8.避免使用不易理解的数字,用有意义的标识来替代。对于常量,不应直接使用数字,必须用有意义的枚举或宏来代替。

    示例:

    #define BUFF_SIZE          1024

    input_data = (char *)malloc(BUFF_SIZE);

    而应避免出现类似以下的代码:

    p = (char *)malloc(1024);

        9.不要使用难懂的技巧性很高的语句,除非很有必要时

    10.尽量避免使用全局变量,全局变量增大了模块间的耦合性,不利于软件维护。

    11.使用全局变量时,应明确其含义、作用、取值范围。明确全局变量与操作此变量的函数的关系,如创建、访问、修改。

    12.在多线程程序中使用全局变量,应注意对变量操作的原子性。

    13.严禁使用未经初始化的变量作为右值。在C程序中,引用未经赋值的指针,经常会引起程序崩溃。

    以下代码在Linux下将导致错误,原因在于:没有使p_string指向某个内存空间的情况下,即对其进行操作是错误的。

    char *p_string;

    p_sting[0] = a;

    应先进行初始化:

    char *p_string;

    p_string = (char *)malloc(BUFF_SIZE);          // 这里假设BUFF_SIZE已定义

    p_sting[0] = a;    

    四、函数

    1.一个函数完成一个特定的功能,不应尝试在一个函数中实现多个不相关的功能。

    2.检查函数所有输入参数的有效性,比如指针型参数要判断是否为空,数组成员参数判断是否越界。

    3.一个函数的规模应限制在200行以内(不包括空行和注释行)。

    4.函数的功能应该是可以预测的,也就是只要输入数据相同就应产生同样的预期输出。

    5.函数的参数不宜过多,以13个为宜

    6.函数名应准确描述函数的功能,一般以动词加宾语的形式命名。

    示例。

    void print_record( struct *p_record, int record_len) ;

    7.函数的返回值要清楚、明了,让使用者不容易忽视错误情况。函数的每种出错返回值的意义要清晰、明确,防止使用者误用理解错误或忽视错误返回码。

    8.如果多段代码重复做同一件事情,那么应该考虑把重复功能实现为一个函数。

    9.减少函数本身或函数间的递归调用。

    递归调用特别是函数间的递归调用(如A->B->C->A),影响程序的可理解性;递归调用一般都占用较多的系统资源(如栈空间);递归调用对程序的测试不利。

    五、效率

    1.通过对数据结构的划分与组织的改进,以及对程序算法的优化来提高空间效率。

    2.循环体内的工作量应最小化

    3.要仔细地构造或直接用汇编编写调用频繁或性能要求极高的函数。

    4.在保证程序质量的前提下,通过压缩代码量,去掉不必要代码以及减少不必要的局部和全局变量,来提高空间效率。

    5.在多重循环中,应将最忙的循环放在最内层,以减少CPU切入循环层的次数。

    如下代码效率较低:

    for (row = 0; row < 100; row++) {

             for (col = 0; col < 5; col++) {

                sum += a[row][col];

        }

    }

    可以改为如下方式,以提高效率:

    for (col = 0; col < 5; col++) {

        for (row = 0; row < 100; row++) {

                sum += a[row][col];

        }

    }

    6.避免循环体内含判断语句,应将循环语句置于判断语句的代码块之中。

    如下代码效率较低:

         for (ind = 0; ind < MAX_RECT_NUMBER; ind++) {

             if (data_type == RECT_AREA) {

                 area_sum += rect_area[ind];

                  }

                  else {

                     rect_length_sum += rect[ind].length;

                     rect_width_sum += rect[ind].width;

                  }

         }

    因为判断语句与循环变量无关,可作如下改进,以减少判断次数:

         if (data_type == RECT_AREA) {

                  for (ind = 0; ind < MAX_RECT_NUMBER; ind++) {

                           area_sum += rect_area[ind];

                       }

         }    

         else {

                  for (ind = 0; ind < MAX_RECT_NUMBER; ind++) {

                      rect_length_sum += rect[ind].length;

                      rect_width_sum  += rect[ind].width;

                  }

         }

    六、代码安全

    1.要避免野指针,内在泄露,越界,操作已释放内在的指针,引用未初始化的变量,对无符号数执行--并比较操作,异常处理,宏定义没有使用完备的括号,等问题。

    内存操作越界是软件系统主要的错误之一,后果是使运行中的程序崩溃,或者留下安全漏洞。

    2.程序编写完成后,应该检查易混淆的操作符,如“==”和“=”、“&&”和“&”、“||”和“|”。

    3.Linux下,多线程中的子线程退出必须采用主动退出方式,即子线程应在return处结束运行。

    【1】 http://www.cnblogs.com/mydomain/archive/2011/07/30/2121823.html

  • 相关阅读:
    cookie加载不正确的问题
    android多图选择器 图片/视频 单选or多选,以及视频录制。
    Android开发之高仿微信图片选择器
    Glide升级到4.x版本遇到的问题
    v关于使用Glide加载图片失败时显示自己特定的图片
    Java的方法类型
    Java二维数组的应用
    Java中字符串操作的基本方法总结:
    Java冒泡排序
    报错:flutter: Another exception was thrown: Could not find a generator for route RouteSettings
  • 原文地址:https://www.cnblogs.com/mydomain/p/2121876.html
Copyright © 2011-2022 走看看