在不丢失函数之前拥有的数据的情况下调用函数?
Calling a function without losing that data that the function had before?
我很早就染上了全局变量的坏习惯,所以我一直在尝试通过使用局部变量和学习 reference/value 的调用来拉近自己的距离,直到我 运行遇到这样的问题,假设我有一个函数 Menu(),它包含一个主菜单和一个数组,然后从菜单中我会转到一个函数并对数组做一些事情,现在我通常会卡在这里我的函数通常是 void 类型,但通常对于我的程序,我使用 if 选择返回菜单,例如 If(userinput ==2){Menu();}
通常这会导致两个问题 1. 当我进入菜单时,它会重置所有变量值
2.If 我在多个地方都有这个函数,它会开始给我参数错误。
这些问题让我很沮丧,让我倾向于全局变量。
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*/
}
一些伪代码没有变量 "reset" with 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 所说,是程序生命周期内的变量。静态变量也是如此,但在这种情况下,它不能在另一个函数中访问。此外,静态变量并不是真正的线程安全
"All non-local state must be accessed through atomic operations and
the data-structures must also be reentrant."
人们不鼓励过度使用全局变量的原因是这些变量将在程序(实际上是进程)的生命周期内占用内存。
但是,在这种特定情况下,这就是您想要的行为。你想记住调用之间菜单的状态,你可以自己实现一个结构并将状态保存在调用函数中,或者你可以简单地全局声明变量。
令人厌烦的是 每个 变量都是全局变量,无论它们是否需要。在像 C 这样的语言中,它基本上只能因为能够以最高效率手动管理内存而得以生存,看到人们浪费它会伤害我们的大脑。通常,看到任何不是常量的全局变量都是一种代码味道。正如一位评论者所指出的,还有 避免使用全局变量的其他原因。我不会遍历所有这些,而是将其留在这里:why globals are bad
请注意,我并不是刻薄,只是不确定这些页面中的哪一个是最好的资源,所以我把它们都给了 OP。
编辑:其他几点。您也可以通过传递一个指针来轻松完成您需要的操作,该指针包含您可以在函数中编辑或不可以编辑的值作为参数,但是根据您所说的,我可能会实施的解决方案如下:
int choice = menu();
case (choice ):
//logic here
如果你保存一个像static
这样的变量,你不会丢失函数之前的数据,因为如果函数和堆栈不被清理,变量不会在最后被销毁.示例:
static int var=0;
var++;
return var;
调用函数10次变量会增加10倍
您应该注意以下几点:
- 在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;
}
嗯,你打电话是这样的:
main()
{
menu();
}
menu()
{
yourfunction();
}
yourfunction()
{
if(userinput==2)
menu();
}
在这里,您可以观察到您再次调用 menu() 但没有 return 返回..
如果你在 menu() 的深度,如果你退出,将 return 到你的函数()而不是 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
}
这将帮助您 return 到 menu() 并要求您继续。
而且这些值将按照您的意愿保留。
编辑:
或者如果你想坚持你的编程习惯。
简单地告诉程序当用户输入为 1(即不等于 2)时要做什么
并且在输入 2 时不要定义任何内容。
它会自动return到menu()
menu()
{
yourfunction();
}
Yourfunction()
{
if(userinput==1)
{
// do this
}
}
或其他方式:
menu()
{
yourfunction();
}
Yourfuntion()
{
if(userinput!=2)
{
//do this
}
}
如果函数将用户输入设为 2,它将返回到 menu()。
结束..:-)
我很早就染上了全局变量的坏习惯,所以我一直在尝试通过使用局部变量和学习 reference/value 的调用来拉近自己的距离,直到我 运行遇到这样的问题,假设我有一个函数 Menu(),它包含一个主菜单和一个数组,然后从菜单中我会转到一个函数并对数组做一些事情,现在我通常会卡在这里我的函数通常是 void 类型,但通常对于我的程序,我使用 if 选择返回菜单,例如 If(userinput ==2){Menu();}
通常这会导致两个问题 1. 当我进入菜单时,它会重置所有变量值
2.If 我在多个地方都有这个函数,它会开始给我参数错误。
这些问题让我很沮丧,让我倾向于全局变量。
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*/
}
一些伪代码没有变量 "reset" with 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 所说,是程序生命周期内的变量。静态变量也是如此,但在这种情况下,它不能在另一个函数中访问。此外,静态变量并不是真正的线程安全
"All non-local state must be accessed through atomic operations and the data-structures must also be reentrant."
人们不鼓励过度使用全局变量的原因是这些变量将在程序(实际上是进程)的生命周期内占用内存。
但是,在这种特定情况下,这就是您想要的行为。你想记住调用之间菜单的状态,你可以自己实现一个结构并将状态保存在调用函数中,或者你可以简单地全局声明变量。
令人厌烦的是 每个 变量都是全局变量,无论它们是否需要。在像 C 这样的语言中,它基本上只能因为能够以最高效率手动管理内存而得以生存,看到人们浪费它会伤害我们的大脑。通常,看到任何不是常量的全局变量都是一种代码味道。正如一位评论者所指出的,还有 避免使用全局变量的其他原因。我不会遍历所有这些,而是将其留在这里:why globals are bad
请注意,我并不是刻薄,只是不确定这些页面中的哪一个是最好的资源,所以我把它们都给了 OP。
编辑:其他几点。您也可以通过传递一个指针来轻松完成您需要的操作,该指针包含您可以在函数中编辑或不可以编辑的值作为参数,但是根据您所说的,我可能会实施的解决方案如下:
int choice = menu();
case (choice ):
//logic here
如果你保存一个像static
这样的变量,你不会丢失函数之前的数据,因为如果函数和堆栈不被清理,变量不会在最后被销毁.示例:
static int var=0;
var++;
return var;
调用函数10次变量会增加10倍
您应该注意以下几点:
- 在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;
}
嗯,你打电话是这样的:
main()
{
menu();
}
menu()
{
yourfunction();
}
yourfunction()
{
if(userinput==2)
menu();
}
在这里,您可以观察到您再次调用 menu() 但没有 return 返回.. 如果你在 menu() 的深度,如果你退出,将 return 到你的函数()而不是 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
}
这将帮助您 return 到 menu() 并要求您继续。 而且这些值将按照您的意愿保留。
编辑:
或者如果你想坚持你的编程习惯。 简单地告诉程序当用户输入为 1(即不等于 2)时要做什么 并且在输入 2 时不要定义任何内容。 它会自动return到menu()
menu()
{
yourfunction();
}
Yourfunction()
{
if(userinput==1)
{
// do this
}
}
或其他方式:
menu()
{
yourfunction();
}
Yourfuntion()
{
if(userinput!=2)
{
//do this
}
}
如果函数将用户输入设为 2,它将返回到 menu()。
结束..:-)