代码之家  ›  专栏  ›  技术社区  ›  user193116

在C程序中,是否可以将所有全局变量重置为默认值?

  •  3
  • user193116  · 技术社区  · 15 年前

    我有一个遗留的C Linux应用程序需要重用。这个应用程序使用了很多全局变量。我想重用这个应用程序的main方法并在循环中调用它。我发现,当我在循环中调用main方法(重命名为callableMain)时,应用程序的行为并不一致,因为在上一次迭代中设置的全局变量的值会影响新迭代中的程序流。

    例如,原来的程序是这样的

    原文C

    #include <stdio.h>
    
    int global = 3; /* This is the global variable. */
    
    void doSomething(){     
             global++; /* Reference to global variable in a function. */    
    }    
    
         // i want to rename this main method to callableMain() and
         // invoke  it in a loop 
         int main(void){    
           if(global==3) {    
           printf(" All  Is Well \n");    
    
           doSomething() ;  
         }
         else{
    
           printf(" Noooo\n");  
    
           doNothing() ;
    
         }
         return 0;
    }
    

    我更改了上面的文件,将main()重命名为callableMain()

    我新的主要方法如下:

    int main(){  
    
         for(int i=0;i<20;i++){  
    
             callableMain();
    
             // this is where I need to reset the value of global vaiables
            // otherwise the execution flow  changes
         }    
    }   
    

    简而言之,没有神奇的api调用可以重置全局变量。全局变量必须被缓存和重用。

    7 回复  |  直到 15 年前
        1
  •  0
  •   karlphillip    15 年前

    我认为你必须改变看待问题的方式。

    在callableMain()的主体中声明callableMain()使用的所有变量,这样它们就不再是全局变量,并且在执行函数并在下一次迭代调用callableMain()时使用默认值再次创建之后会被销毁。

    编辑:

    好的,如果您有callableMain()的源代码,您可以这样做:在函数的开头,添加一个检查来验证函数是否是第一次被调用。在该检查中,您将把所有全局变量的值复制到另一组 静止的

    这样,您将保留所有全局变量的初始值,并在callableMain()的每次迭代中使用它们。这对你有意义吗?

    void callableMain()
    {
      static bool first_iter = true;
    
      if (first_iter)
      {  
        first_iter = false;
        static int my_global_var1 = global_var1;
        static float my_global_var2 = global_var2;
        ..
      }
    
      // perform operations on my_global_var1 and my_global_var2, 
      // which store the default values of the original global variables.
    
    }
    
        2
  •  8
  •   David M.    15 年前

    其思想是将遗留程序从新程序中分离出来,将其降级到自己的进程中。那你就把两者完全分开了。此外,每次运行旧程序时,它都会重置为干净状态。

    首先,修改程序,使其从一个文件中读取输入数据,并将其输出以机器可读的格式写入另一个文件,文件在命令行中给出。

    然后可以创建命名管道(使用 mkfifo system ,在命令行上将命名管道传递给它。然后你给它输入并读回它的输出。

    fork . 然而,分离遗留代码并将其作为子进程调用的基本思想可能是这里最好的方法。

        3
  •  5
  •   DigitalRoss    15 年前

    早到了吗?

    fork(2)

    事实上,也许 fork() 至少两次,一次设置工作控制器并保存初始化(但不要太初始化:-)全局状态,然后使用此工作控制器 叉子()

    一个更简单的变体可能是只修改代码,以便进程可以在“工作模式”下启动,然后使用 system() 在顶部启动应用程序,但使用一个参数将其置于从属模式。

        4
  •  3
  •   Praetorian Luchian Grigore    15 年前

    在某些平台/编译器上有一种方法可以做到这一点,您基本上要执行编译器在调用之前执行的相同初始化 main() .

    我已经为一个tidsp做了这件事,在这种情况下,我把globals映射到内存的一个特定部分,并且有链接器指令可以用来声明指向这个部分开始和结束的变量(所以你可以 memset() memcpy() 输入目标地址以初始化所有全局变量。

    非常特定于编译器,所以希望您使用的编译器允许您执行类似的操作。

        5
  •  1
  •   Alex Hart    15 年前

    简言之,没有。在这个例子中,我要做的是创建定义,如果你愿意的话,创建常量,然后用它们来重置全局变量。

    基本上

    #define var1 10
    int vara = 10
    

    等。。。基本C对吗? 然后,您可以继续并将重新初始化包装到一个方便的函数中(=)

        6
  •  0
  •   pmg    15 年前
    for (int i = 0; i < 20; i++) {
        int saved_var1 = global_var1;
        char saved_var2 = global_var2;
        double saved_var3 = global_var3;
    
        callableMain();
    
        global_var1 = saved_var1;
        global_var2 = saved_var2;
        global_var3 = saved_var2;
    }
    

    memcpy 他们。但我总是在开始循环时畏缩。。。

    for (int i = 0; i < 20; i++) {
        static unsigned char global_copy[SIZEOFGLOBALDATA];
        memcpy(global_copy, STARTOFGLOBALDATA, SIZEOFGLOBALDATA);
    
        callableMain();
    
        memcpy(STARTOFGLOBALDATA, global_copy, SIZEOFGLOBALDATA);
    }
    

        7
  •  0
  •   Shautieh    15 年前