调用函数而不丢失该函数之前的数据?

时间:2015-03-20 08:37:42

标签: c function variables

我很早就开始接受全局变量的坏习惯,所以我一直试图通过使用局部变量和通过引用/值学习来调整自己的距离,直到我遇到这样的问题时,我还没有那么糟糕,比如说我有一个功能Menu(),其中包含一个主菜单和一个数组,然后从菜单我去一个函数和做数组的东西,现在我经常卡在这里我的函数通常是无效类型,但通常对于我的程序,我使用if选项返回菜单,如If(userinput ==2){Menu();}通常会导致两个问题1.当我进入菜单时,它会重置所有变量值 2.如果我在多个地方使用此功能,它将开始给我参数错误。

这些问题使我灰心丧气,让我倾向于全局变量。

Example:

menu(){
    int array[100];
    functionadd(array);
}

functionadd(array[])
{
    int userinput;
    do{ 
        //lets the just say here the program does things to my array.
        // usually when I want to go back to the menu I'd do something like this
        printf("Again or back to menu?1(Again) or 2(Menu)")
            scanf_s("%d%[^\n]", &userinput); '\n'==getchar();
    } while(userinput == 1)
    if(userinput != 2){Menu();} /*this would bring me back to
        the menu but my array would be back to as its original state
        when it was called in Menu I understand why this happens I
        just need to learn how to counter act it*/
}

5 个答案:

答案 0 :(得分:3)

某些伪代码没有变量可以"重置"使用static关键字:

int Menu(){
    static int remember = 0;
    remember++;
    return remember;
}

int main(){
    printf("remember = %d\n", Menu());
    printf("remember = %d\n", Menu());
    printf("remember = %d", Menu());
}

输出:

记得= 1

记得= 2

记得= 3

注意,如Ron所说,全局变量是程序生命周期的变量。静态变量也是如此,但在这种情况下,它不能在另一个函数中访问。此外,静态变量并非真正的线程安全

  

"必须通过原子操作访问所有非本地状态   数据结构也必须是可重入的。"

答案 1 :(得分:0)

人们不鼓励过度使用全局变量的原因是因为这些变量将在程序的生命周期中占用内存(真正的过程)。

但是,在这种特定情况下,这就是你想要的行为。您想要记住调用之间菜单的状态,您可以自己实现一个结构并将状态保存在调用函数中,或者您可以简单地全局声明该变量。

每个变量是全局变量时,无论是否需要变量,人们都会感到烦恼。在像C这样的语言中,它基本上只能因为能够以最高效率手动管理内存而存活下来,所以看到人们浪费它会伤害我们的大脑。一般来说,查看任何不是常量的全局变量都会产生代码味道。正如评论者指出的那样,避免使用全局变量的其他原因。我不会遍历所有内容,而是将其留在此处:why globals are bad

请注意,我不是故意,只是不确定哪些页面是最好的资源,所以我给了OP所有这些。

编辑:其他几点。您也可以通过传递包含您可能或不可能在函数中编辑的值的指针作为参数来轻松完成您所需要的内容,但我可能会根据您所说的内容实现这样的解决方案:

int choice = menu(); 
case (choice ):
//logic here

答案 2 :(得分:0)

如果保存像static之类的变量,你不会丢失之前函数所拥有的数据,如果函数和堆栈赢了,那么变量就不会被破坏。 ;清洁。例如:

static int var=0;
var++;
return var;

如果你将函数调用10次,变量将增加十倍。

答案 3 :(得分:0)

您应该注意以下事项:

  • 在C中,所有参数都使用call by value传递。
  • 当您将数组作为参数传递给函数时,它会衰减为指向数组第一个元素的指针。

Call by value并不意味着你不能从另一个函数修改某个函数的局部变量。为此,您将指针作为参数传递,然后从被调用函数赋值传递给它取消引用的声明。

例如:

void f(int *c)
{
    *c = 7;
}

int main(void)
{
    int count = 4;
    f(&count);
    printf("%d", count);
    return 0;
}

答案 4 :(得分:0)

嗯,你打电话是这样的:

    main()
    {
       menu();
    }

    menu()
    {
       yourfunction();
    }

    yourfunction()
   {
      if(userinput==2)
           menu();
   }

在这里,您可以观察到您再次调用menu()但没有返回.. 如果你在菜单()的深度处,如果你退出,将返回你的函数()而不是main()。

我建议您使用类似以下的代码:

menu()
{

     do
     {
        yourfunction();//call your function
        //after the completion ask to continue
        printf("Do you want to continue? (Y/N) ");
        fflush(stdin);
        scanf(" %c",&choice);
     }while(choice=='y'||choice=='Y');

 }

 void yourfunction()
{
         //do only functional job
}

这将帮助您返回菜单()并要求您继续。 并且值也将保持原样。

修改

或者如果你想坚持编程的习惯。 当用户输入为1(即不等于2)时,只需告诉程序该怎么做 当输入2时,不要定义任何内容。 它会自动返回菜单()

 menu()
    {
       yourfunction();
    }

Yourfunction()
{
  if(userinput==1)
   {
    // do this
   }
}

或其他方式:

 menu()
    {
       yourfunction();
    }
Yourfuntion()
{
  if(userinput!=2)
   {
    //do this
   }
}

如果函数的userinput为2,它将返回menu()。

结束..: - )