作为程序员,我们必须做的最基本的事情之一就是学会将问题分解为更小的问题。您实际上遇到了一系列问题。
我将向您展示如何解决您的问题。您可能想为这个答案添加书签,因为我会先发制人一些问题,您将在接下来的几步中遇到问题,并让您准备 - 如果您注意 - 自己解决它们;)
让我们从剥离您的代码开始。
现场演示:http://ideone.com/aUCtmM
#include <iostream>
int main()
{
std::cout << "Enter a number: ";
int i;
std::cin >> i;
std::cout << "Enter a second number: ";
int j;
std::cin >> j;
std::cout << "i = '" << i << "', j = '" << j << "'\n";
}
我们在这里检查什么?我们正在检查是否可以向用户提出两个问题。效果很好。
接下来是你对 goto 的使用,我强烈建议你不要使用它。使用函数会更好。我将首先在这里演示您的 goto 案例:
#include <iostream>
int main()
{
int choice;
std::cout << "Enter choice 1 or 2: ";
std::cin >> choice;
if ( choice == 1 )
goto CHOSE1;
else if ( choice == 2 )
goto CHOSE2;
else {
std::cout << "It was a simple enough question!\n";
goto END;
}
CHOSE1:
std::cout << "Chose 1\n";
goto END;
CHOSE2:
std::cout << "Chose 2\n";
goto END;
END:
std::cout << "Here we are at end\n";
}
现场演示:http://ideone.com/1ElcV8
所以 goto 不是问题。
剩下的就是你对变量的使用了。通过第二组变量(mm,uu),您真的把事情搞砸了。您不仅不需要拥有这些,而且您正在做一些非常顽皮的事情,因为这些变量只存在于一个范围内,而不存在于另一个范围内。你可以“摆脱”它,但它会在以后再次困扰你。
两个主要代码流的区别在于变量名称。第二种转换情况如下所示:
MXNTUS:
int mm, uu;
cout << "Enter the amount of Pesos to Convert" << endl;
cout << "Amount: ";
cin >> mm;
uu = mm / 12.99;
cout << endl;
cout << "US Dollars: " << m << endl;
goto END;
这里的问题是您在输出中意外地使用了变量“m”。这就是我们所说的未初始化。
cout << "US Dollars: " << m << endl;
中间那个m应该是mm。
您的编译器实际上应该对此发出警告。如果不是,并且您只是开始学习,则应该弄清楚如何提高编译器警告级别。
最好做一个函数来进行转换;你可以为每个方向创建一个函数,但我已经创建了一个处理这两种情况的函数:
#include <iostream>
static const double US_TO_MXN = 12.99;
static const char DATA_DATE[] = "6/12/2014";
void convert(const char* from, const char* to, double exchange)
{
std::cout << "Enter the number of " << from << " to convert to " << to << ".\n"
"Amount: ";
int original;
std::cin >> original;
std::cout << to << ": " << (original * exchange) << '\n';
}
int main() // this is valid since C++2003
{
std::cout << "US/MXN Converter\n"
"1 US = " << US_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"\n";
int choice = 0;
// Here's a better demonstration of goto
GET_CHOICE:
std::cout << "Which conversion do you want to perform?\n"
"[1] US to MXN\n"
"[2] MXN to US\n"
"Selection: ";
std::cin >> choice;
if (choice == 1)
convert("US Dollars", "Pesos", US_TO_MXN);
else if (choice == 2)
convert("Pesos", "US Dollars", 1 / US_TO_MXN);
else {
std::cerr << "Invalid choice. Please try again.\n";
goto GET_CHOICE;
}
// this also serves to demonstrate that goto is bad because
// it's not obvious from the above that you have a loop.
}
ideone 现场演示:http://ideone.com/qwpRtQ
有了这个,我们可以继续清理一大堆东西并扩展它:
#include <iostream>
using std::cin;
using std::cout;
static const double USD_TO_MXN = 12.99;
static const double GBP_TO_MXN = 22.03;
static const char DATA_DATE[] = "6/12/2014";
void convert(const char* from, const char* to, double exchange)
{
cout << "Enter the number of " << from << " to convert to " << to << ".\n"
"Amount: ";
int original;
cin >> original;
cout << '\n' << original << ' ' << from << " gives " << int(original * exchange) << ' ' << to << ".\n";
}
int main() // this is valid since C++2003
{
cout << "Foreign Currency Converter\n"
"1 USD = " << USD_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"1 GBP = " << GBP_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"\n";
for ( ; ; ) { // continuous loop
cout << "Which conversion do you want to perform?\n"
"[1] USD to MXN\n"
"[2] MXN to USD\n"
"[3] GBP to MXN\n"
"[4] MXN to GBP\n"
"[0] Quit\n"
"Selection: ";
int choice = -1;
cin >> choice;
cout << '\n';
switch (choice) {
case 0:
return 0; // return from main
case 1:
convert("US Dollars", "Pesos", USD_TO_MXN);
break;
case 2:
convert("Pesos", "US Dollars", 1 / USD_TO_MXN);
break;
case 3:
convert("British Pounds", "Pesos", GBP_TO_MXN);
break;
case 4:
convert("Pesos", "British Pounds", 1 / GBP_TO_MXN);
break;
default:
cout << "Invalid selection. Try again.\n";
}
}
}
http://ideone.com/iCXrpU
这方面还有很多改进的余地,但我希望它对你有所帮助。
---- 编辑----
迟到的提示:您似乎正在使用基于 system("PAUSE") 的 Visual Studio。无需添加到您的代码中,只需使用 Debug -> Start without Debugging 或按 Ctrl-F5。它会自动为你做暂停:)
---- 编辑 2 ----
一些“你是怎么做到的”点。
cout << '\n' << original << ' ' << from << " gives " << int(original * exchange) << ' ' << to << ".\n";
我非常小心地没有执行using namespace std;,当您开始使用更多的 C++ 时,该指令将成为您存在的祸根。最好不要习惯它,等你对 C++ 编程更加熟悉,更重要的是调试奇怪的编译错误时,再让自己开始使用它。
但是通过添加 using std::cout 和 using std::cin,我节省了很多打字时间,而没有创建我必须避免的函数/变量名称的雷区。
那么这条线会做什么:
cout << '\n' << original << ' ' << from << " gives " << int(original * exchange) << ' ' << to << ".\n";
'\n' 是单个字符,一个回车符。这样做比std::endl 更有效,因为std::endl 必须去戳输出系统并强制写入;它不仅仅是行尾字符,它实际上终止了行,如果你愿意的话。
int(original * exchange)
这是一个让 C 程序员感到困惑的 C++ 特性。我实际上是在以original * exchange 的结果作为参数创建一个“临时”整数。
int i = 0;
int i(0);
两者是等价的,一些程序员建议养成使用第二种机制的习惯,这样你就可以理解当你以后遇到所谓的“最令人烦恼的解析”时会发生什么:)
convert("Pesos", "British Pounds", 1 / GBP_TO_MXN)
1 / x “反转”的值。
cout << "Foreign Currency Converter\n"
"1 USD = " << USD_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"1 GBP = " << GBP_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"\n";
这可能会令人困惑。我将隐喻与此混合在一起,我对此感到有些羞耻,但它读起来很好。同样,采用将问题分解为更小的问题的概念。
cout << "Hello " "world" << '\n';
(注意:“\n”和“\n”不同:“\n”实际上是一个字符串,而“\n”实际上只是回车符)
这会打印出来
Hello world
当 C++ 看到像这样由空格(或 cmets)分隔的两个字符串文字时,它会将它们连接起来,因此它实际上将“Hello world”传递给 cout。
所以你可以将这段代码重写为
cout << "Foreign Currency Converter\n1 USD = ";
cout << USD_TO_MXN;
cout << " MXN (";
cout << DATA_DATE;
cout << ")\n1 GBP = ";
cout << GBP_TO_MXN;
cout << " MXN (";
cout << DATA_DATE;
cout << ")\n\n";
<< 就是我们所说的“语义糖”。当你写
cout << i;
编译器将其翻译成
cout.operator<<(i);
这个看起来很奇怪的函数调用返回cout。所以当你写
cout << i << j;
它实际上是把它翻译成
(cout.operator<<(i)).operator<<(j);
括号(cout.operator<<(i))中的表达式返回cout,所以变成了
cout.operator<<(i); // get cout back to use on next line
cout.operator<<(j);
主指纹
int main()
int main(int argc, const char* argv[])
两者都是合法的。第一个是完全可以接受的 C 或 C++。第二个仅在您计划捕获“命令行参数”时有用。
最后,在 main
return 0;
请记住,main 被指定为返回 int。 C 和 C++ 标准为 main 提供了一个特殊情况,表示它是唯一一个不返回任何内容都不是错误的函数,在这种情况下,程序的“退出代码”可以是任何内容。
通常最好退货。在 C 和 C++ 中,“0”被认为是“假”,而其他任何东西(任何非零)都是“真”。因此,C 和 C++ 程序有一个约定,返回错误代码 0(假,无错误)以指示程序成功或退出没有问题,或任何其他指示(例如 1、2 ... 255)作为错误.
在 main 中使用“return”将结束程序。