【问题标题】:Global variables and functions in CC中的全局变量和函数
【发布时间】:2023-03-25 05:37:01
【问题描述】:

抱歉,这是一个基本问题,但我的所有研究都几乎没有错过回答我的问题,我只是想在编写所有代码之前进行双重检查,并假设。 我正在使用 C 并且我有一个声明了一些变量的头文件(ints、char 数组、int 数组)。如果我有一个使用这些全局变量的函数,我假设我可以使用这些变量而不传递它们?

示例 头文件:

int state;
int lnArray[];

C 文件:

void function(){ 
    int i;
    for(i=0;i<5;i++;){
        if(lnArray[i]<10)    
        state = lnArray[i];
    }
}

【问题讨论】:

    标签: c variables global


    【解决方案1】:

    请注意,您编写的头文件定义了全局变量state(它声明了一个不完整的数组lnArray);它应该只声明它们:

    extern int state;
    extern int lnArray[];
    

    然后,在其中一个源文件(也包括标题的源文件)中,你写:

    int state = 0;
    int lnArray[XXX];   //  XXX is an enum or #define that gives the array size
    

    或者你可以有一个lnArray 的初始化器,它给出了数组的大小。

    如果您的编译器使用“通用定义”机制,您可能会摆脱现有的情况;许多人都这样做。但是添加一个初始化程序,你就完蛋了。

    另请参阅:What are extern variables in C?

    请注意,全局变量通常不是一个好主意;很难跟踪哪些代码正在访问和修改它们。人们竭尽全力避免全局变量。全局常量是另一回事。它们带来的问题更少,尽管您仍然不会随意使用它们。

    【讨论】:

      【解决方案2】:

      没错。这就是为什么它们被称为“全局”变量的原因:它们可以在任何范围内使用。

      【讨论】:

      • 好的。谢谢你。我只是想在需要重写代码或出现大量错误之前确定一下。
      • 既然您知道它们是什么,请明智地使用它们。不要仅仅为了避免传递参数而使用它们。当拥有全局数据有意义时使用它们(即需要某事物的一个实例并在很多地方引用)。全球数据存在许多下行风险。小心行事。
      • 但是,您不仅在标头中声明变量,还定义它们。您不应该这样做:如果多个模块使用同一个 hader,您会遇到名称冲突。
      • 在真正的函数中,如果我传递所有内容,它将是 2 个整数、1 个整数数组、1 个字符数组和 1 个指针数组。我试图减少至少一些参数。
      【解决方案3】:

      您给出的示例是正确的,但容易出现“重新声明”链接器错误。

      使用全局变量的首选方式是:

      
      /* example.h */
      extern int state;
      extern int lnArray[];
      
      
      /* example.c */
      int state;
      int lnArray[SOME_SIZE_HERE];
      

      通过在头文件中声明externs,您可以在不重新声明statelnArray 的情况下从尽可能多的不同源文件中任意多次#include &lt;example.h&gt;

      【讨论】:

        【解决方案4】:

        是的,但如果您打算将其包含在其他标题中,请小心。

        http://tread.wordpress.com/2007/06/18/declaring-global-variables-in-header-files/

        Are global variables bad?

        【讨论】:

          【解决方案5】:

          您需要在这里小心。 “全局”变量是在代码中的任何点都可用的变量,但标准中没有正式的全局定义 - 它使用更正式的术语,如范围、存储持续时间和链接。

          全局的一种定义适用于单个文件,另一种可以适用于多个文件。

          通过您的特定设置,如果您将该头文件包含在多个 C 源文件中,然后尝试将它们链接在一起,您将收到链接错误,因为每个目标文件都有其 自己的副本变量,并且它们全部都在尝试导出它们。

          如果您希望变量对于单个源文件是全局的,请将它们放在该源文件的顶部并使其成为静态(实际上对链接器不可见):

          static int state;
          

          这意味着该文件中的每个函数都可以访问它们,但它们不会干扰其他文件。

          但是,如果您希望变量在所有源文件中都是全局的,请将 声明 放在头文件中,将 定义 放在一个 C 源文件中。声明声明某事物存在,而定义使其存在:

          something.h:
              extern int state;                     // declare it
          
          file1.c:
              #include "something.h"                // declare it (in header)
              int state;                            // AND define it.
              // Now you can use state anywhere.
          
          file2.c:
              #include "something.h"                // declare it (in header)
              // Now you can use state anywhere.
          

          这意味着所有文件都可以访问 一个 state 的副本。


          在使用全局变量方面,一般要尽量避免。使用它们会使封装变得更加困难,并将代码的内部暴露给外部操作。

          基本规则是对任何单个项目使用尽可能小的范围,这仍然可以让您实现目标。有时,这意味着传递信息。

          如果你真的不想传递它们,至少将所有数据和操作它的代码隔离到一个文件中,这样你就可以隐藏它。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-08-02
            • 1970-01-01
            相关资源
            最近更新 更多