问题描述
#include <bits/stdc++.h>
using namespace std;
int exp(int b){
try{
throw b;
}
catch(int b){
cout<<"Enter b again : ";
cin>>b;
}
if(b==0)
exp(b); //this is the part where I think a logical error is occuring
return b;
}
int main(){
system("cls");
int a,b;
cout<<"Enter a: ";
cin>>a;
cout<<"Enter b: ";
cin>>b;
if(b==0)
exp(b);
cout<<"Division a/b = "<<a/b<<endl;
return 0;
}
我试图避免在这个程序中使用 goto 函数,而是在这个程序中使用异常作为递归函数,但它显示的输出是这样的
Enter a: 6
Enter b: 0
Enter b again : 0
Enter b again : 7
Enter b again : 5
Enter b again :
解决方法
你可以用 C++ 做很多事情。这并不意味着您应该这样做。对非异常事件使用异常就是其中之一。正如 the C++ Core Guidelines 中所说:
将错误处理与“普通代码”分开。 C++ 实现往往基于异常罕见的假设进行优化。
简而言之,异常处理非常慢。异常对许多 C++ 程序员很有用,因为它们启用了不会减慢正常执行速度的错误处理;仅在错误实际发生时花费时间。
,您显然不了解 try - catch
语句的工作原理。当程序的执行流程到达 throw
语句时,将考虑最近输入的 try-catch 语句的适当 catch() 块。在您的情况下,您有一个无条件的 throw
,因此您的函数相当于此代码,不需要 try-catch:
int exp(int b)
{
cout<<"Enter b again : ";
cin>>b;
if(b==0)
exp(b); //this is the part where I think a logical error is occuring
return b;
}
因此,您要求再次输入 b,如果 b 为零,则要求再次输入...并在 b 不为零时退出循环,但它总是提示输入一个值。所有这些都可以通过单个 do .. while
完成而不需要递归,显然你必须在输入提示之前检查 b 的值,你会错过第一次输入的结果。
第二,您实际上并没有返回用户值,也没有通过引用传递它,因此 main() 函数中的 b 将保持为零。你也可以使用类似
void exp(int& b)
{
while(b==0) {
std::cout << "Enter b again : ";
std::cin >> b;
}
}
请注意,这仍然存在缺陷,没有考虑用户输入错误的非数字输入的情况。
try-catch
很慢,因为它可以展开调用堆栈并且不适合作为流控制语句。 throw
可以在任何地方调用的任何函数中遇到,在 try
和 catch
之间的任何嵌套级别,但从 catch 返回将优雅地退出堆栈中所有函数的范围,然后将执行传递给 {{ 1}}。