Chinaunix首页 | 论坛 | 博客
  • 博客访问: 237035
  • 博文数量: 61
  • 博客积分: 125
  • 博客等级: 入伍新兵
  • 技术积分: 100
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-23 23:28
文章分类

全部博文(61)

文章存档

2014年(37)

2013年(21)

2012年(3)

分类: C/C++

2014-08-09 10:50:06

原文地址: C 语言规范 作者:叶子的背叛



文件结构

   c程序文件:*.C (implementation) 、 *.h (Declaration)

  一. 头文件结构
      头文件作用:通过头文件来调用库功能。在很多场合,
用户得不到源代码,只向用户提供二进制库和头文件;头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件中的声明不一致,编译器就会指出错误
        1>头文件开头处的版权和版本声明
        2>预处理块
        3>函数和类结构声明等
    • 为了防止头文件被重复引用,应当用 ifndef/define/endif 结构产生预处理块。
    • 用 #include 格式来引用标准库的头文件(编译器将从标准库目录开始搜索)、#include “filename.h” 格式来引用非标准库的头文件(编译器
      将从用户的工作目录开始搜索) 
    • 头文件中只存放“声明”而不存放“定义”、并且尽量不要在头文件中定义全局静态变量

点击(此处)折叠或打开

  1. // 版权和版本声明此处省略
  2. #ifndef GRAPHICS_H // 防止 graphics.h 被重复引用
  3. #define GRAPHICS_H

  4. #include <math.h> // 引用标准库的头文件
  5. ...
  6. #include “myheader.h” // 引用非标准库的头文件
  7. ..
  8. void Function1(...); // 全局函数声明
  9. ...
  10. class Box // 类结构声明
  11. {
  12. ...
  13. };

  14. #endif

  二定义文件结构
        1>定义文件开头处的版权和版本声明
        2>头文件的引用
        3>程序的实现体(包括数据和代码) Implementation

(此处)书写范例

    1. // 版权和版本声明此处省略。
    2. #include “graphics.h” // 引用头文件
    3. ...
    4. // 全局函数的实现体
    5. void Function1(...)
    6. {
    7. ...
    8. }
    9. // 类成员函数的实现体
    10. void Box::Draw(...)
    11. {
    12. ...
    13. }

   三. 版权/版本声明及文件描述
   版权和版本的声明位于头文件和定义文件的开头    
        1>版权信息
        2>文件名称,标识符,摘要
        3>当前版本号,作者/修改者,完成日期
       4>版本历史信息

点击(此处)折叠或打开

  1. /*
  2. * Copyright (c) 2014,xxxxx有限公司
  3. * All rights reserved.
  4. *
  5. * 文件名称:xxx.h
  6. * 摘 要:简要描述本文件的内容
  7. *
  8. * 当前版本:1.1
  9. * 作 者:输入作者(或修改者)名字
  10. * 完成日期:2014 年 6 月 25 日
  11. *
  12. * 取代版本:1.0
  13. * 原作者 :输入原作者(或修改者)名字
  14. * 完成日期:2001 年 5 月 10 日
  15. */



程序书写规范
一> 在每个类声明之后、每个函数定义结束之后都要加“空行
二>
 一行代码只做一件事情
三>
 一元操作符(如 “!” 、 “~” 、 “++” 、 “--” 、 “&” 等)前后不能加空格
 

> 尽可能在定义变量的同时初始化该变量(就近原则
五>
 关键字之后要留空格。象 const、virtual、inline、case 等关键字之后至少要留一个空格,否则无法辨析关键字。象 if、for、while 等关键字之后应留一个空格再跟左括号"(",以突出关键字。
六>
 函数名之后不要留空格,紧跟左括号‘(’ ,与关键字相反。
七>
‘(’向后紧跟,‘)’ 、‘,’ 、‘;’向前紧跟,紧跟处不留空格
八>‘,’、‘;’前紧跟,后留空格
九> 赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符(“=” 、 “+=” “>=” 、 “<=” 、 “+” 、 “*” 、 “%” 、 “&&” 、 “||” 、 “<<”、“^”等)二元操作符的前后应当加空格
>
“ [ ] ” 、 “.” 、 “->”这类操作符前后不加空格 

十一>
 
if、for、while、do 等语句自占一行,执行语句不得紧跟其后。不论执行语句有多少都要加{}  

十二>  代码行最大长度宜控制在 70 至 80 个字符以内。代码行不要过长
十三>  长表达式要在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符)
十四>  应当将修饰符 * 和 & 紧靠变量名
  1. char *name;
  2. int *x, y;     //int* x, y; 容易引起误解(y并不是指针)
十五> 注释的位置应与被描述的代码相邻,可以放在代码的上方或右方,不可放在下方。


命名规则
变量的名字应当使用“名词”或者“形容词+名词
  1. float value;
  2. float oldValue;
  3. float newValue;

2
全局函数的名字应当使用“动词”或者“动词+名词”(动宾词组)类的成员函数应当只使用“动词”,被省略掉的名词就是对象本身
  1. DrawBox(); // 全局函数

  2. box->Draw(); // 类的成员函数

用正确的反义词组命名具有互斥意义的变量或相反动作的函数等
  1. int minValue;
  2. int maxValue;

  3. int SetValue(...);
  4. int GetValue(...);

尽量避免名字中出现数字编号,如 Value1,Value2 等,除非逻辑上的确需要编号

类名和函数名用大写字母开头的单词组合而成
  1. class Node; // 类名
  2. class LeafNode; // 类名

  3. void Draw(void); // 函数名
  4. void SetValue(int value); // 函数名

变量和参数用小写字母开头的单词组合而成
   
  1. BOOL flag;
  2. int drawMode;

常量全用大写的字母,用下划线分割单词
  1. const int MAX = 100;
  2. const int MAX_LENGTH = 100;

8
> 静态变量加前缀 s_(表示 static
        
  1. void Init()
  2. {
  3. static int s_initValue; // 静态变量
  4. ...
  5. }

9
> 如果不得已需要全局变量,则使全局变量加前缀 g_(表示 global)
  1. int g_howManyPeople; // 全局变量
  2. int g_howMuchMoney; // 全局变量

10
> 类的数据成员加前缀 m_(表示 member) ,这样可以避免数据成员与成员函数的参数同名
  1. void Object::SetValue(int width, int height)
  2. {
  3. m_width = width;
  4. m_height = height;
  5. }


量使用规则
 

        C语言定义常量有两种
#define  // 宏常量
const   // const 常量
异同: const常量有数据类型,而 #define 没有,编译器对前者进行类型安全检查,后者仅字符替换。
#define 比较简单不做详细介绍,这里着重描述下 const 变量的使用细节。
const 修饰变量放在类型前后无区别

  1. const int variable;
  2. int const variable;

  3. const int array[];
  4. int const array[];
  5. //以上两组没有区别

const修饰指针

  1. const int *var;
  2. int const *var;
  3. //以上两句没有区别,const 修饰指向对象,var可变,var指向对象不可变

  4. int *cosnt var; // const 修饰 指针var,指针var不可变,var指向对象可变
  5. const int *cosnt var; // 指针及指向对象都被const 修饰,不可变

注:提倡如果参数是指针,且仅作输入用,在类型前用 const 修饰,防止该指针被意外修改。



if语句中“0”值的比较规范
1> BOOL    布尔变量
不可将布尔值直接 TRUE  、FALSE  1 、0 比较
  1. 规范比较:
  2. BOOL flag;
  3.    ...
  4. if (flag)
  5. if (!flag)

2> int     整型变量
将整型变量直接用 “==”或“!=” 与 “0”比较
  1. 比较规范:
  2. int valu;
  3.   ...
  4. if (valu == 0)
  5. if (valu != 0)

3
> float/double   浮点变量
不可与整型变量一样比较,无论是 float 还是 double 都是有精度限制。所以规范比较应该转化为 “>=”“<=”形式
  1. 规范比较:
  2. float valuf;
  3.    ...
  4. if (valuf == 0.0) //隐含错误比较

  5. if (valuf >= -EPSINON) && (valuf <= EPSINON) // EPSINON 为允许的误差(精度)

4>
*   指针
使用 “==” “!=” 与 NULL 比较,尽管 NULL 与 “0” 值相同,但两者意义不同
  1. 比较规范:
  2. if(p == NULL)
  3. if(p != NULL)
  4. 或者
  5. if(NULL == p )
  6. if(NULL != p )
  7. // 推荐使用后者,防止漏写成 " p = NULL" ,有利于编译器报错



本文整理于 林锐博士《高质量C》 

阅读(1511) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~