如何调用函数并结束当前函数
How to call a function and end the current function
我有一个菜单程序,它通过调用每个菜单页面作为一个函数来工作。但是如果用户重复选择 'Back' 和 'Next' 调用堆栈将继续增加,这意味着我相信程序理论上可能会崩溃。
在这段代码和我的程序中,一旦调用下一个菜单函数,我想从堆栈中删除当前函数,因为我不再需要它。这样的事情可能吗?
这是一些示例代码:
void menu1()
{
//Get user input
if (input == 0) //Go to menu2
menu2();
else //Invalid input try again
menu1();
}
void menu2()
{
//Get user input
if (input == 0) //Do something
else if (input == 1) //Go back
menu1();
else //Invalid input try again
menu2();
}
可以看出,如果用户输入“0, 1, 0, 1...”,那么堆栈会继续增长。
为什么不能将代码放入循环中并重复输入?这应该有效,除非我遗漏了关于你的问题的一些东西......
#include <stdio.h>
#include <stdlib.h>
void menu1(){
printf("You chose menu1\n");
}
void menu2(){
printf("You chose menu2\n");
}
int main(){
long linput = 0;
do{
char cinput[3] = {0};
printf("Choose a menu (1) or (2) or 0 to exit:");
fgets(cinput, sizeof(cinput), stdin);
linput = strtol(cinput, NULL, 10);
switch (linput) {
case 1:
menu1();
break;
case 2:
menu2();
break;
default:
break;
}
}while(linput!=0);
}
没有将用户选择入口和跳转到相应功能集成到每个功能体中。重构您的代码:
- 要求用户输入
- 调用相应的函数
- Return 给调用者(或
main()
),并要求另一个输入。
- 调用相应的函数
并根据需要继续,或结束流程。这样,每次选择都会调用一个函数,然后返回。
函数调用不是实现这种控制流的正确方法。你需要 State Machines.
除了函数,您还需要考虑 状态,它代表每个菜单。然后你需要定义actions/tasks你到达或离开一个状态时需要做的事情。您的程序需要跟踪它当前所处的状态。
如果我理解你的问题是正确的,你有 N 个不同的菜单页面,并且你希望在每个页面上能够
- select具体操作
或
- 转到另一个菜单页面
正如您正确地注意到的那样,您当前的方法存在问题。您的代码不断调用其他菜单函数或相同的菜单函数(即像递归调用)。那不是编写代码的方式。在调用下一个函数之前需要让当前函数return。可以使用 while
循环来完成在获得特定输入之前保持相同的功能。
菜单系统可以通过多种方式实现。
下面是一个非常简单的例子,有 3 个菜单页面。
该代码绝不是最佳方法。它有意保持非常简单,以展示一种避免不断进行递归调用的方法。
#include <stdio.h>
#include <stdlib.h>
int menu0()
{
while(1)
{
puts("--- Menu 0 ---");
puts("Enter 0-9 to switch menu");
puts("Enter a for operation A");
puts("Enter b for operation B");
puts("Enter e to exit");
char input;
if (scanf(" %c", &input) != 1) exit(1); // Get input
if (input >= '0' && input <= '9')
{
// Go to another menu page
return input - '0';
}
if (input == 'e')
{
// Exit program
return 999;
}
if (input == 'a')
{
puts("Doing operation A");
}
else if (input == 'b')
{
puts("Doing operation B");
}
}
}
int menu1()
{
while(1)
{
puts("--- Menu 1 ---");
puts("Enter 0-9 to switch menu");
puts("Enter a for operation X");
puts("Enter b for operation Y");
puts("Enter e to exit");
char input;
if (scanf(" %c", &input) != 1) exit(1); // Get input
if (input >= '0' && input <= '9')
{
// Go to another menu page
return input - '0';
}
if (input == 'e')
{
// Exit program
return 999;
}
if (input == 'a')
{
puts("Doing operation X");
}
else if (input == 'b')
{
puts("Doing operation Y");
}
}
}
int menu2()
{
while(1)
{
puts("--- Menu 2 ---");
puts("Enter 0-9 to switch menu");
puts("Enter a for operation S");
puts("Enter b for operation T");
puts("Enter e to exit");
char input;
if (scanf(" %c", &input) != 1) exit(1); // Get input
if (input >= '0' && input <= '9')
{
// Go to another menu page
return input - '0';
}
if (input == 'e')
{
// Exit program
return 999;
}
if (input == 'a')
{
puts("Doing operation S");
}
else if (input == 'b')
{
puts("Doing operation T");
}
}
}
int main() {
int next = 0; // Start in menu0
while(1)
{
if (next == 0)
{
next = menu0();
}
else if (next == 1)
{
next = menu1();
}
else if (next == 2)
{
next = menu2();
}
else if (next == 999)
{
break; // End program
}
else
{
next = 0; // Unknow menu selected so go to menu0
}
}
return 0;
}
每个菜单页面都处于循环状态(while
),直到输入为 0、1、.. 、9,在这种情况下,函数 return 是数字,因此 main
可以调出相应的菜单页。
此外,每个菜单页面都接受像 a、b 这样的输入来执行特定的操作,而 e 则用来退出。
我有一个菜单程序,它通过调用每个菜单页面作为一个函数来工作。但是如果用户重复选择 'Back' 和 'Next' 调用堆栈将继续增加,这意味着我相信程序理论上可能会崩溃。 在这段代码和我的程序中,一旦调用下一个菜单函数,我想从堆栈中删除当前函数,因为我不再需要它。这样的事情可能吗? 这是一些示例代码:
void menu1()
{
//Get user input
if (input == 0) //Go to menu2
menu2();
else //Invalid input try again
menu1();
}
void menu2()
{
//Get user input
if (input == 0) //Do something
else if (input == 1) //Go back
menu1();
else //Invalid input try again
menu2();
}
可以看出,如果用户输入“0, 1, 0, 1...”,那么堆栈会继续增长。
为什么不能将代码放入循环中并重复输入?这应该有效,除非我遗漏了关于你的问题的一些东西......
#include <stdio.h>
#include <stdlib.h>
void menu1(){
printf("You chose menu1\n");
}
void menu2(){
printf("You chose menu2\n");
}
int main(){
long linput = 0;
do{
char cinput[3] = {0};
printf("Choose a menu (1) or (2) or 0 to exit:");
fgets(cinput, sizeof(cinput), stdin);
linput = strtol(cinput, NULL, 10);
switch (linput) {
case 1:
menu1();
break;
case 2:
menu2();
break;
default:
break;
}
}while(linput!=0);
}
没有将用户选择入口和跳转到相应功能集成到每个功能体中。重构您的代码:
- 要求用户输入
- 调用相应的函数
- Return 给调用者(或
main()
),并要求另一个输入。 - 调用相应的函数
并根据需要继续,或结束流程。这样,每次选择都会调用一个函数,然后返回。
函数调用不是实现这种控制流的正确方法。你需要 State Machines.
除了函数,您还需要考虑 状态,它代表每个菜单。然后你需要定义actions/tasks你到达或离开一个状态时需要做的事情。您的程序需要跟踪它当前所处的状态。
如果我理解你的问题是正确的,你有 N 个不同的菜单页面,并且你希望在每个页面上能够
- select具体操作
或
- 转到另一个菜单页面
正如您正确地注意到的那样,您当前的方法存在问题。您的代码不断调用其他菜单函数或相同的菜单函数(即像递归调用)。那不是编写代码的方式。在调用下一个函数之前需要让当前函数return。可以使用 while
循环来完成在获得特定输入之前保持相同的功能。
菜单系统可以通过多种方式实现。
下面是一个非常简单的例子,有 3 个菜单页面。
该代码绝不是最佳方法。它有意保持非常简单,以展示一种避免不断进行递归调用的方法。
#include <stdio.h>
#include <stdlib.h>
int menu0()
{
while(1)
{
puts("--- Menu 0 ---");
puts("Enter 0-9 to switch menu");
puts("Enter a for operation A");
puts("Enter b for operation B");
puts("Enter e to exit");
char input;
if (scanf(" %c", &input) != 1) exit(1); // Get input
if (input >= '0' && input <= '9')
{
// Go to another menu page
return input - '0';
}
if (input == 'e')
{
// Exit program
return 999;
}
if (input == 'a')
{
puts("Doing operation A");
}
else if (input == 'b')
{
puts("Doing operation B");
}
}
}
int menu1()
{
while(1)
{
puts("--- Menu 1 ---");
puts("Enter 0-9 to switch menu");
puts("Enter a for operation X");
puts("Enter b for operation Y");
puts("Enter e to exit");
char input;
if (scanf(" %c", &input) != 1) exit(1); // Get input
if (input >= '0' && input <= '9')
{
// Go to another menu page
return input - '0';
}
if (input == 'e')
{
// Exit program
return 999;
}
if (input == 'a')
{
puts("Doing operation X");
}
else if (input == 'b')
{
puts("Doing operation Y");
}
}
}
int menu2()
{
while(1)
{
puts("--- Menu 2 ---");
puts("Enter 0-9 to switch menu");
puts("Enter a for operation S");
puts("Enter b for operation T");
puts("Enter e to exit");
char input;
if (scanf(" %c", &input) != 1) exit(1); // Get input
if (input >= '0' && input <= '9')
{
// Go to another menu page
return input - '0';
}
if (input == 'e')
{
// Exit program
return 999;
}
if (input == 'a')
{
puts("Doing operation S");
}
else if (input == 'b')
{
puts("Doing operation T");
}
}
}
int main() {
int next = 0; // Start in menu0
while(1)
{
if (next == 0)
{
next = menu0();
}
else if (next == 1)
{
next = menu1();
}
else if (next == 2)
{
next = menu2();
}
else if (next == 999)
{
break; // End program
}
else
{
next = 0; // Unknow menu selected so go to menu0
}
}
return 0;
}
每个菜单页面都处于循环状态(while
),直到输入为 0、1、.. 、9,在这种情况下,函数 return 是数字,因此 main
可以调出相应的菜单页。
此外,每个菜单页面都接受像 a、b 这样的输入来执行特定的操作,而 e 则用来退出。