C - 程序结构(避免全局变量、包含等)

问题描述 投票:0回答:6

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

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

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

有什么好的、严格用 C 语言编写的开源软件可以看一下吗?我想不出任何办法,其中大多数似乎都是用 C++ 编写的。

谢谢。

编辑

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

具体而言,该应用程序挂钩另一个应用程序中使用的 API 函数。它通过使用 WriteProcessMemory 覆盖对原始的调用并使其成为对我的 DLL 的调用来实现此目的。

但是,当unhook 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 );

抱歉,如果这令人困惑。

c global-variables program-structure
6个回答
13
投票

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

  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
      关键字)。

2
投票

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


2
投票

很简单:只需不要使用它们即可。在

main()
函数中创建全局变量,然后将它们作为参数传递给需要它们的函数。


1
投票

我大学里最推荐的学习 C 语言的开源软件是 Linux,所以你可以从他们的源代码中获取示例。


1
投票

我也认为,全局变量不好,会降低可读性并增加错误可能性和其他问题。

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

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


0
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.