如何在else-if中使用(或不使用?)goto
How to use (or not to use?) goto in a else - if
每次我将if
与goto
一起使用以绕过进程并直接转到退出时,它都不会通过命令绕过某些内容,而是一直到最后。这里有一个例子:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string k;
cout <<"What would you like to do ?n"<<"Continue or Exitn";
cin >> k;
if (k = "exit","Exit") goto s;
else (k = "Continue","continue");
cout << "You continued...";
s:
return 0
}
问题是,即使您键入"退出"或"继续",它也只是简单地关闭。有人能看到问题吗?另外,我该如何避免使用goto?
第一个if
总是true
,因为在赋值之后,逗号运算符的RHS上的测试将是true
。
您的简单程序不能保证使用goto
。不过,我更喜欢处理这样的任务:函数表。
我完成了一个例子。我们从一个简单的回调类开始。回调接口附带了一个默认实现,该实现抱怨输入。
struct Callback {
virtual ~Callback () {}
virtual void operator () (std::string k) const {
std::cout << "Unrecognized input: " << k << 'n';
}
};
这部分定义了函数表数据结构,声明了一个API来初始化一个,以及调用回调的驱动程序代码:
typedef std::map<std::string, const Callback *> CallbackMap;
static void init_table (CallbackMap &cbmap);
static void invoke_table (const CallbackMap &cbmap, std::string k)
{
CallbackMap::const_iterator i = cbmap.find(k);
if (i != cbmap.end()) (*i->second)(k);
else Callback()(k);
}
int main ()
{
CallbackMap cbmap;
std::string k;
init_table(cbmap);
std::cout << "What would you like to do?nContinue or Exitn";
std::cin >> k;
invoke_table(cbmap, k);
return 0;
}
单独的回调实现是通过以下帮助宏实现的:
#define CONST_SINGLETON(Name)
public:
static const Name & instance () {
static const Name one;
return one;
}
private:
Name () {}
Name (const Name &);
void operator = (const Name &)
每个回调实现都执行示例程序中介绍的简单操作:
class ExitCallback : public Callback {
void operator () (std::string) const { std::exit(0); }
CONST_SINGLETON(ExitCallback);
};
class ContinueCallback : public Callback {
void operator () (std::string) const {
std::cout << "You continued...n";
}
CONST_SINGLETON(ContinueCallback);
};
初始化例程用对应于适当回调的字符串填充函数表:
static void init_table (CallbackMap &cbmap)
{
static struct { const char *s; const Callback *cb; } init[] = {
{ "exit", &ExitCallback::instance() },
{ "Exit", &ExitCallback::instance() },
{ "continue", &ContinueCallback::instance() },
{ "Continue", &ContinueCallback::instance() },
{ 0, 0 }
};
for (int i = 0; init[i].s; ++i) {
cbmap[init[i].s] = init[i].cb;
}
};
1(这里不要使用goto
:在现代C++代码中使用它几乎从来都不合适。
2(使用==
比较字符串(=
用于string
分配(
if (k == "exit","Exit")
^^^^
//Here
else (k == "Continue","continue")
^^^^
// And here
3(,
不是"and"运算符,请使用:
if (k == "exit" || k == "Exit")
4(如果有无用的大括号,请缩进代码以正确查看真正需要的块。
您需要学习如何使用调试器,还需要了解有关C++的更多信息
if (k = "exit","Exit") goto s; //VERY WRONG
并不意味着你想要什么:
- CCD_ 13的CCD_
- 逗号被理解为逗号运算符
至少编码if (k == "exit" || k == "Exit")
,尽可能避免使用goto
。
此外,启用所有警告(和调试信息(。也许你的编译器可以警告你。
我建议您阅读一些来自自由软件的源代码(例如,在sourceforge或其他地方(。这将教会你很多。
适当的缩进和样式将帮助您看到您的一些努力。
首先,我强烈建议将字符串转换为小写或大写。这就不需要检查字符串中大写字母和小写字母的所有排列:
cout << "What would you like to do ?n"
<< "Continue or Exitn";
cin >> k;
std::transform(k.begin(), k.end(), k.begin(), tolower);
要退出main
函数,return
需要一个值,例如exit_SUCCESS或exit_FAILURE。
if (k == "exit")
{
return EXIT_SUCCESS;
} // No goto's necessary
// The code continues here.
记住"="是赋值,"=="是比较。
没有必要比较"continue",因为如果响应不是"exit",它会"自动"进行比较。
使用goto
不建议在此实例中使用goto
如果你真的必须使用goto,你将需要不止一个标签。
int main(void)
{
string k;
top_of_loop: // Label for your goto
cout << "What would you like to do ?n"
<<"Continue or Exitn";
cin >> k;
std::transform(k.begin(), k.end(), k.begin(), tolower);
if (k == "exit")
{
goto end_of_program;
}
// Execution continues here automatically.
else
{
if (k == "continue")
{
goto program_continuation;
}
else
{
cout << "Unknown response, try again.n";
goto top_of_loop;
}
}
program_continuation:
cout << "You continued...";
goto top_of_loop;
end_of_program:
return 0
}
作为while
循环
cout << "What would you like to do ?n"
<<"Continue or Exitn";
cin >> k;
std::transform(k.begin(), k.end(), k.begin(), tolower);
while (k != "exit")
{
// Your program stuff here.
cout << "Program continued.n";
// Prompt the User again.
cout << "n"
<< "What would you like to do ?n"
<< "Continue or Exitn";
cin >> k;
std::transform(k.begin(), k.end(), k.begin(), tolower);
}
return 0; // Exit main().
您的代码反映了您的意图,但这些意图不是用C++编写的。它们是一个有效的C++程序——当然是编译的——但你的意思并不是你所写的。
它在这里,固定做你想做的事。
int main()
{
string k;
cout << "What would you like to do ?nContinue or Exit" << endl;
cin >> k;
if (! (k == "exit" || k == "Exit")) {
if (k == "Continue" || k == "continue") {
cout << "You continued...";
}
}
return 0
}
你也可以做:
int main()
{
string k;
cout << "What would you like to do ?nContinue or Exit" << endl;
cin >> k;
if (k == "exit" or k == "Exit") return 0;
if (k == "Continue" or k == "continue") {
cout << "You continued...";
}
return 0
}
变化如下:
要检查多个条件中的一个是否为真,请使用逻辑或运算符加入测试。运算符被写成
||
,或者简单地说,写成or
。比较运算符为
==
。您使用的运算符=
是一个赋值运算符。它执行赋值,其结果值就是赋值。逗号运算符用于分隔要计算的多个表达式。其结果值是最后一个表达式,即使所有表达式都已求值。例如,
(1, 2, 3)
的值为3
。
- 在 C++ 中的 if-else if- else 语句期间更改变量
- 如何改进一堆在已知值范围内评估变量的 else-if 条件?
- 我需要把 constexpr 放在 else-if 之后吗?
- 我们可以在第一个else-if条件结束后使用另一个else-if条件吗
- 如何在 C++17 中将 "else-if" 与初始值设定项一起使用?
- if, else if, else 函数未准确显示结果
- 使用 if/else if 的函数输出问题
- 需要消除这些"else if"并优化代码
- 不必要的 else 语句:当可以使用 IF 时,使用 ELSE IF 有什么缺点吗?
- MQL4:我的if/else if liop只有一半导致当前执行
- 如何在 else-if 语句中正确使用 or 语句 (||)
- if else-if else 语句 c++ 的替代项
- 具有"else if"方法问题 C++ 的基本计算器
- 如果/else-if语句将如何处理此操作
- If和else-If语句.它是如何在下面的代码中工作的
- 优化代码/实现"for"循环而不是长"if - else if - else"
- "if"块没有大括号,使后续"else if"嵌套
- 试图编写一个只使用if和else-if语句对两个数字进行排序的程序
- if else-if梯形图和编译器优化
- 如何在else-if中使用(或不使用?)goto