在C中,“公共”在置于全局变量之前意味着什么?

我正在浏览Mark Nudelman的“less”unix工具的源代码,main.c的开头有以下几点:

public int logfile = -1; public int force_logfile = FALSE; public char * namelogfile = NULL; 

在全局范围内,在main()的定义之前,

在这种情况下,公众意味着什么? 更重要的是,我在哪里可以自己找到这些信息? 我使用无数的查询组合进行搜索,无法找到此信息或任何彻底的C引用。

在文件less.h是你的答案:

 #define public /* PUBLIC FUNCTION */ 

公共似乎只用作公共/全局函数和变量的标记。 编译时,它会扩展为空。

如何找到这些信息?

  1. 从顶部搜索.c文件到您想要了解更多信息的标识符的位置
  2. 如果您没有找到任何声明,请查找#include指令
  3. 打开任何包含的文件,查找您要查找的内容的声明
  4. 对每个包含的文件重复步骤2

在这种情况下,这很简单。

这与C无关。 如果查看包含文件less.h,您将看到作者已定义了许多预处理器指令。 其中一些像“公共”最有可能是可读性的。 例如:

  /* * Language details. */ #if HAVE_VOID #define VOID_POINTER void * #else #define VOID_POINTER char * #define void int #endif #if HAVE_CONST #define constant const #else #define constant #endif #define public /* PUBLIC FUNCTION */ 

了解公众的定义。 它被翻译成什么都没有,因为你已经发现它在全球范围内。 然而,它在全球范围内更具可读性和更直观性。 此外,有人可能会争辩说,如果源是这样编写的,并且新版本的C出现了具有公共关键字的问题,则需要重新定义头文件并重新编译以实际使用它。

像这样的预处理技巧甚至可以巧妙地用于使用不同语言(如C ++和Java)编译一个源代码。 这不是你应该做的事情,但它是可能的。

您在上面的less.h示例中看到的HAVE_VOID等选项通常在编译时指定为编译器(实际上是预处理器)选项。 因此,如果您有一个支持void关键字的编译器和C版本,您将使用以下代码编译源代码:

g ++ -g -DHAVE_VOID -Wall myprog.C -o myprog

作者在源中使用VOID_POINTER的任何地方实际上都会被编译器视为:

 void * 

如果您未指定HAVE_VOID,编译器将改为使用

 char * 

这是一个合理的替代品。

提示:检查编译器的选项,看看是否可以选择预处理源。 这样,您可以查看发送到编译器的实际源。

公共作为空预处理器宏的定义已在其他答案中得到解决。 要找到定义,您可能希望使用ctags / etags或cscope等工具。 (有许多工具可以扫描源树以生成此信息。)例如,您可以通过调用以下命令找到less.h第55行的public定义:

 $ ctags -dtw * .c * .h
 $ vi -t public

或者,在开始编辑任何内容之前,只需运行ctags。 当你看到一个你不理解的定义时,把光标放在它上面并输入^](这是控制右方括号,并且可以在类似vi的编辑器中工作。)

C没有关键字“public”,因此它可能是在较少的源代码中定义的宏。