如何在C程序中使全局常量(跨多个文件工作)?

时间:2011-11-29 01:14:30

标签: c

我有一个包含两个文件的ANSI C程序。第一个文件包含main()函数,第二个文件包含第一个文件调用的其他函数。在main()函数定义之前,我已经放置了以下代码:

#define PI 3.14159265358979323846

但是第二个文件没有看到这个变量。第一个文件看起来很好。然后,我将相同的行放在第二个文件中(同时将其保存在上面的第一个文件中),在函数定义之前,但仍然没有第二个文件看到它。事情总是很好地编译,但是当在gdb中跟踪变量PI时,它会显示"No symbol "PI" in current context."

如何使PI成为应用程序中编译的所有文件的全局常量?

编辑/更新:

根据目前为止的回复,我创建了以下文件:

myheader.h

#ifndef my_header_stuff
#define my_header_stuff
    #define PI 3.1415926535897932384626433832795
#endif

在我希望看到这个常量PI的两个文件中,我已按如下方式包含此文件:

file1.c中

#include <stdio.h>
#include <stdlib.h>
#include "myheader.h"
int main(void) {
  etc...
}

file2.c

#include <stdio.h>
#include <stdlib.h>
#include "myheader.h"
double interesting_function(void) {
  etc...
}

问题:

  1. 当我使用GDB进行调试时,b PI返回(在两个文件中,相同的结果)“当前上下文中没有符号”PI“。但是,正确计算取决于PI的数学运算。有没有办法在gdb中查看PI?

  2. 我是否还可以在myheader.h文件中包含stdio和stdlib的两行?

  3. 我还可以在myheader.h文件中包含任何函数原型吗?如果我这样做,然后让我说我创建一个不需要任何这些原型的file3.c,因为它不使用这些函数,是否有任何损害?

7 个答案:

答案 0 :(得分:3)

  1. GDB中没有显示宏定义是正常的。这是因为GCC用实际的pi值替换每个PI
  2. 是。在你的情况下,它没有伤害。如果.h文件包含使用其他地方定义的类型的原型(它们通常称为声明),则只需在头文件中#include
  3. 是。你可以声明你想要的功能原型,它不会对程序的功能造成任何伤害。编译器甚至不检查这些函数的定义是否存在,除非您实际从其他地方调用它们。

答案 1 :(得分:2)

我在头文件中声明了PI,并将此头文件包含在所有源文件中

您应该在头文件中放置函数声明,宏(可能还有一些简单的内联函数) 实施应放在.c文件

//我编辑了对您评论的回复的答案

答案 2 :(得分:2)

宏不是变量,它不会作为变量出现在gdb中。事情很好,因为他们工作得很好;你对gdb抱有错误的期望。

通常,应在头文件中定义多个地方所需的宏,该文件包含在需要的任何地方;例如,宏M_PI已经定义为标准包含math.h中的pi。

您可以做的另一件事是将const int PI = 3.14159etcetc;放在一个文件中,extern const int PI;放在所有其他文件中,但这很痛苦,因为它要求值的定义存在于< em>正好一个编译单元。

答案 3 :(得分:1)

您可以创建一个全局变量。

//file1.c
int my_global;


//file2.c
extern int my_global;
//code using my_global...

请注意,不鼓励使用预处理程序。

另请注意,其他人建议的M_PI定义在最新的C标准(C99)中不可用,因此您不能依赖它。

答案 4 :(得分:0)

如果您只使用标准数学定义,标准头文件math.h有一些好的:

 #include <math.h>
  ...
 double area = radius * radius * M_PI;

为了定义全局常量,有许多方法,在其他答案中有充分的解释。

答案 5 :(得分:0)

如果你为主源文件中包含的文件创建一个头文件,这将是非常好的,这也是一个很好的实践,你将提高你的C语言技能。想象一下,我们有一个源文件,其中包含我们在主源文件中需要的函数,全局变量和常量,我们可以为该文件创建一个头文件并将这些函数放在那里:

 #ifndef _FILE_H
 #define _FILE_H

 #include "file.h"
 #define PI 3.14
 /**
  *functions protypes here or other constants or globlal variables
  */
  void do_something(char **param1, int *param2);

 #endif

在“file.c”文件中,您应该执行以下操作:

#inlcude "file.h"

void do_something(char **param1, int *param2)
{

    /**
     *do something
     */
}

在“main.c”文件中,您应该这样做:

 #include "file.h"

 /**
  *Now you can use "PI"
  */

我希望我能以某种方式提供帮助。

答案 6 :(得分:-1)

预编译器直接将在编译之前用实际代码替换,因此在您的情况下,您的第一个文件的PI将替换为3.14 ...并且在第一个翻译单元的符号表中没有PI符号。所以gdb不会说“PI”符号。

如果您想使用#define并且不想使用头文件,则需要在每个文件的开头使用#deine PI。