头文件中的声明和#defines的首选顺序

时间:2012-06-29 05:48:42

标签: c linux coding-style macros header-files

我在Linux平台上用C语言编程。我想知道应该是头文件中的声明顺序和#defines

例如,如果我的头文件包含以下内容,那么任何人都可以建议我应该安排所有这些声明的完美顺序,如宏,扩展声明等功能。

这对于在可读性和编码标准方面正确地将所有这些内容安排在头文件中非常有用。

下面是示例头文件(我想以正确的顺序排列以下内容):

 #include <pthread.h>                   //  Including Header files 
 #include <signal.h>

 #define IMAGE_DIRECTORY                 "Abcdefgh..."   //  Providing #defines 
 #define FAILED_TO_RECOGNIZE             "Xykbkksk..."
 #define PROGRESS_FRAME_COLOR            "#8e8ea1"
 #define FRAME_BG_COLOR                  "#7c90ac"      

 #define PRINT_FUNCTION_NAME fprintf(stderr, 
                   "CTRL IN FUNCTION : %s\n",__func__);   // Macro like functions 
typedef struct {                                           
        int userId;                                      // Structure
         char name[32], rollNo[32];
         char class[16], section[16];
         unsigned long Id;
 }data_type;

int noOfUsersList=0, usersListCount=0;                   // Global variables 

3 个答案:

答案 0 :(得分:4)

多年来我没有这样做,但是当我在Unix,MS.DOS,OS / 2,NetWare和Windows上大量开发时,我开发了这种做法:

  1. 语言#includes
  2. 操作系统#includes
  3. #includes来自其他子系统,例如X11。
  4. 我自己的应用#includes。
  5. 此源文件的本地#defines。
  6. 我自己对此文件的前瞻性声明。
  7. 也许你可以反转(1)和(2),但我发现这个命令在很多编译器和操作系统中运行得最好。

答案 1 :(得分:1)

#define的宏定义是不是声明。唯一的要求是应该在使用之前定义宏。它们保持定义直到编译单元结束,或明确#undef(或重新定义...)。

我的风格惯例是将类似语句的宏定义为具有&#34;功能&#34;像语法一样:

 #define PRINT_FUNCTION_NAME() fprintf(stderr, \
     "CTRL IN FUNCTION: %s @%s:%d\n", __func__, __FILE__, __LINE__)

注意空的正式宏参数(即第一个())和缺少终止分号(因为你将使用它作为准函数调用,例如PRINT_FUNCTION_NAME();声明)。另请注意,在调试消息中也使用__FILE____LINE__

通常情况下,类似语句的宏是do{ 某事 } while(0),因为这是一种语法,它具有类似外观的语句,并且总是用作语句(包括{{1>}的然后部分,或if分支等)。来自else的示例:

<ncurses.h>

答案 2 :(得分:1)

编码风格是主观的,我个人使用下面描述的规则和方法,但请注意,这是我自己的意见,没有绝对的真理。然而,它们基于长期经验,在某些情况下基于广泛认可的编码标准(MISRA,CERT等)。

规则:

  • C编程在“代码模块”中完成,其中每个模块都包含.h文件和.c文件。
  • #includes应始终位于.h文件中,永远不会出现在.h文件中,因为.h文件应视为公共文件。您希望将要使用您的模块的人知道它们具有哪些依赖关系。
  • 从来没有理由在C中使用非const全局变量,所以放置非const全局变量和外部变量与我无关。
  • .h文件不应包含任何定义。这不仅是错误的程序设计,它还是一种很好的方法,可以避免许多难以解决的链接器错误。

在.h文件中,允许按以下顺序显示以下项目:

  • 头球卫士的开始。 (#ifndef MYHEADER_H ...)
  • 图书馆#includes。
  • 其他#includes。
  • 特定于Impl.的编译器设置,例如使用#pragmas设置的编译器选项。
  • 公共数字常量为#defines。
  • 公共宏。
  • 公共类型定义,包括opaque类型。
  • 公共常量声明(声明为extern const)。
  • 内联函数定义(罕见的特殊情况,尽可能避免)。
  • 功能原型。
  • 头球防守结束。 #endif

在.c文件中,允许按以下顺序显示以下项目:

  • 包含自己对应的.h文件。
  • #defines中的私有数字常量。
  • 私人宏。
  • opaque类型的定义,在相应的.h文件中声明为不完整类型。
  • 私人类型定义。
  • 公共常量的定义(在.h文件中声明为extern const)。
  • 私有常量的定义(static const)。
  • 文件范围(static)的私有变量的定义。
  • 声明私人功能(声明为static type func (type param);
  • .h文件中声明的公共函数的定义。
  • 私人职能的定义。