7

我正在使用 C(不是 C++),我不确定如何避免使用全局变量。

我对 C、它的语法以及如何编写基本应用程序有相当不错的掌握,但我不确定构建程序的正确方法。

真正的大型应用程序如何避免使用全局变量?我很确定总是至少需要一些,但是对于用 C 编写的大型游戏和其他应用程序,最好的方法是什么?

有没有我可以看的严格用 C 语言编写的好的开源软件?我无法想到任何东西,它们中的大多数似乎都是用 C++ 编写的。

谢谢。

编辑

这是一个我将在简单的 API 挂钩应用程序中使用全局变量的示例,它只是另一个进程中的 DLL。

这个应用程序,具体来说,挂钩在另一个应用程序中使用的 API 函数。它通过使用 WriteProcessMemory 覆盖对原始文件的调用,并改为调用我的 DLL 来实现这一点。

但是,当取消挂钩 API 函数时,我必须写回原始内存/机器代码。

所以,我需要为那个机器代码维护一个简单的字节数组,每个被钩住的 API 函数一个,而且有很多。

// Global variable to store original assembly code (6 bytes)
BYTE g_MessageBoxA[6];

// Hook the API function
HookAPIFunction ( "user32.dll", "MessageBoxA", MyNewFunction, g_MessageBoxA );

// Later on, unhook the function
UnHookAPIFunction ( "user32.dll", "MessageBoxA", g_MessageBoxA );

对不起,如果这令人困惑。

4

6 回答 6

11

“真正的大型应用程序如何避免使用全局变量?”

  1. 使用静态变量。如果函数需要在调用之间记住某些内容,请使用 this 而不是全局变量。例子:

    int running_total (int num) {
        static int sum  = 0;
        sum             += num;
        return sum;
    }
    
  2. 通过参数传递数据,以便将值定义在一个地方,也许main()并传递到需要它的地方。

  3. 如果所有其他方法都失败了,请继续使用全局变量,但尝试缓解潜在问题。

    1. 至少,使用命名约定以尽量减少潜在的冲突。例如:Gbl_MyApp_DeveloperName。因此,所有全局变量都将从Gbl_MyApp_部分开始——其中“MyApp”是描述您的应用程序的内容。
    2. 尝试按目的对函数进行分组,以便需要给定全局的所有内容都在同一个文件中(在合理范围内)。然后可以定义全局变量并将其限制在该文件中(注意extern关键字)。
于 2010-07-08T23:27:44.467 回答
2

全局变量有一些有效的用途。学校开始教导他们是邪恶的,以防止程序员懒惰和过度使用它们。如果您确定数据确实是全球需要的,那么请使用它们。鉴于您关心做好工作,我认为您使用自己的判断不会错得太远。

于 2010-07-08T22:44:42.887 回答
2

这很容易 - 只是不要使用它们。在 main() 函数中创建本来应该是全局变量的内容,然后将它们作为参数从那里传递给需要它们的函数。

于 2010-07-08T22:50:45.853 回答
1

在我的大学里学习 C 的最佳推荐开源软件是 Linux,因此您可以从它们的源代码中获取示例。

于 2010-07-08T22:44:36.273 回答
1

我认为同样的,全局变量很糟糕,会降低可读性并增加错误可能性和其他问题。

我会解释我的例子。我有一个 main() 做的事情很少。大部分动作来自定时器和外部中断。由于我使用的平台是 32 位微控制器,这些是没有参数的函数。我不能传递参数,此外,这些中断和定时器是异步的。最简单的方法是一个全局的,想象一下,中断填充一个缓冲区,这个缓冲区在一个定时器内部解析,解析的信息在其他定时器中使用、存储、发送。好的,我可以在主函数中拉起一个中断标志并处理,但是在执行关键软件时,以这种方式不是一个好主意。

这是唯一一种不会让我感觉不好的全局变量;-)

于 2013-03-09T20:07:18.307 回答
0

全局变量几乎是不可避免的。但是,它们经常被过度使用。它们不能替代传递正确的参数和设计正确的数据结构。

每次你想要一个全局变量时,想一想:如果我还需要一个这样的变量怎么办?

于 2010-07-08T22:45:02.010 回答