一种避免C中全局变量的方法

时间:2016-10-15 06:00:44

标签: c global-variables

假设我有变量counter。如果我需要:

  • 从代码中的许多地方访问和修改变量
  • 确保以“正确”的方式修改变量,

这个解决方案是否足够,或者是否有更有效/更清洁的方法呢?

int counter_access(int value) {
    static int counter = 0;

    if (value > 100) {
        printf("there is a bug in the code");
        return counter;
    }

    counter += value;
    return counter;
}

然后当我需要修改变量时:

counter_access(10); /* increase counter by 10 */
counter_access(-2); /* decrease counter by 2 */

当我需要访问变量时:

if (counter_access(0) == 100) do_something();

这个解决方案对我来说似乎很狡猾。但是,我想不出很多很好的方法来做到这一点。我可以使用全局变量(导致错误)。我可以将counter的地址传递给需要它的函数,但这并不能确保变量没有以不正确的方式修改(在上面的示例中,如果counter递增超过100,有一个错误)。

基本上,使用函数访问变量的问题是没有令人满意的方法告诉调用者该值是不正确的。

1 个答案:

答案 0 :(得分:3)

对于单线程程序来说,对这样的事情使用单个函数是一个很好的选择,你只需要以正确的方式设置东西。

要发出错误信号,您可以使用某些"超出范围"值。在您的情况下,计数器范围是0 .. 100。

你可能有类似的东西:

#define COUNT_OVERFLOW            -1
#define COUNT_UNDERFLOW           -2

#define counter_get()    counter_add(0)

int counter_add(int incr) 
{ 
    static int counter = 0;
    int counter_temp;

    counter_temp = counter +incr;

    if (counter_temp < 0)    return COUNT_UNDERFLOW;
    if (counte_temp > 100)   return COUNT_OVERFLOW;

    counter = counter_temp;
    return counter;
}

现在,要检测错误,您可以检查返回值是否为&lt; 0:

cnt = counter_add(x);
if (cnt < 0) {
  fprintf(stderr,"There is a bug in the code\n");
}
....
if (counter_get() == 100) {
  printf("DONE!\n");
}

请注意,即使出现错误,也会保留counter的值。此外,最好不要使用counter_access()打印错误消息之类的功能,最好检查返回值并让调用者打印它(如果它是如此倾向)。

我添加了宏counter_get(),以避免让用户记住添加0会产生返回当前计数器值的副作用。

如前所述,在更复杂的情况下,您不应该使用静态变量(或等效的全局变量)。在这些情况下,正确的方法是为每个线程设置一个struct,并保留与该线程状态相关的变量。您必须将指针传递给该结构并让counter_access()函数接受它作为参数。

仔细观察,你可以看到我们在这里试图模仿封装数据和操作的面向对象的方法。在这种情况下,我们(隐式地)实现了一个对象(计数器)的单个实例,它有两个方法:一个用于更改值,另一个用于获取值。