/*
* Write a program that prints out the entire lyrics to a full rendition of "99 bottles of beer"
*/
#include <iostream>
using namespace std;
int main (void)
{
int bottle = 99;
while (bottle > 0)
{
cout << bottle << " bottles of beer on the wall, "
<< bottle << " bottles of beer." << endl;
bottle--;
cout << "Take one down and pass it around, " << bottle << " "
<< "bottles of beer on the wall.\n" << endl;
if (bottle == 1)
{
break;
}
}
cout << "1 bottle of beer on the wall, 1 bottle of beer." << endl
<< "Take one down and pass it around, no more bottles of beer on the wall.\n" << endl
<< "No more bottles of beer on the wall, no more bottles of beer." << endl
<< "Go to the store and buy some more, 99 bottles of beer on the wall.";
return 0;
}
#1 楼
一些简短的注释:不要使用命名空间std:
出于某些原因这很糟糕,但是总之:如果您是
using namespace std;
,您可能会遇到大名冲突。有关更多信息:为什么使用namespaec std被认为是不好的做法?中断条件:
在这里的外观很好: br />
这可能会更简单:
while (bottle > 0)
{
//print the lyrics
if (bottle == 1)
{
break;
}
}
命名:一个柜台。将其命名为
bottle
,bottleCount
或其他名称,但不要命名为leftBottles
。因为不是瓶子... 评论
\ $ \ begingroup \ $
我正在学习一本C ++书籍,作者建议使用命名空间std。感谢您指出我的错误。
\ $ \ endgroup \ $
–大会
14年8月14日在11:50
\ $ \ begingroup \ $
@Amession在教学初学者时很常见,因为它使操作更简单,但是有点像避免与孩子进行性爱,因为这很困难。
\ $ \ endgroup \ $
– Davidmh
14年8月14日在12:11
\ $ \ begingroup \ $
@面向学生的书籍通常会建议您在现实世界中不应该做的事情,以使事情变得更简单。不幸的是,在学校学习到的不良习惯不会在进入现实世界时被神奇地抹去。使用命名空间std;在C ++中,还不如在PHP中使用mysql_pwn_my_server()系列数据库函数那么糟糕;但是任何阅读技术新闻的人都会定期看到主要站点,这些站点被错误的人通过SQL Injection破坏了。
\ $ \ endgroup \ $
–丹在火光中摆弄
2014年8月14日14:51
\ $ \ begingroup \ $
@DanNeely我同意(我读了很多有关C和C ++的学生书,而且我对它完全了解了)。除了尝试和失败之外,是否还有其他用于学习适当C或C ++的良好资源?
\ $ \ endgroup \ $
–加拿大卢克
14年8月14日在18:24
\ $ \ begingroup \ $
@CanadianLuke首先要知道的是,学习C的适当资源不是学习C ++的适当资源。
\ $ \ endgroup \ $
–莫文
2014年8月15日在12:49
#2 楼
除了其他答案中的注释以外,我建议您创建一个在屏幕上打印句子的功能。类似
while (bottles > 0)
{
printLyrics(bottles);
bottles--;
}
在这种情况下,只剩下一个瓶子就需要处理特殊情况。案例在正确的抽象级别上显示。
评论
\ $ \ begingroup \ $
好主意,我现在正在调整代码,谢谢!
\ $ \ endgroup \ $
–大会
14年8月14日在11:52
\ $ \ begingroup \ $
随机花絮:我知道在VB中,他们希望if块中更常见的情况首先出现。 C ++是相同的方式还是性能相同?
\ $ \ endgroup \ $
–加拿大卢克
14年8月14日在18:25
\ $ \ begingroup \ $
@CanadianLuke在几乎所有编程语言中它都是相同的,因为它可以使您免于引擎盖下的跳转/分支指令。但是在大多数情况下,您不需要这样的微观优化。如果确实需要这种微优化,那么您就不想使用此答案的建议,因为它会将不必要的分支指令放入循环中。
\ $ \ endgroup \ $
– jliv902
14年8月14日在20:37
\ $ \ begingroup \ $
@CanadianLuke据我所知,这并不是为了进行优化,而是为了提高可读性。首先放置更常见的场景,使读者先阅读该书:让读者先阅读特殊情况,可能会使他们很难理解它们,因为读者还没有看清楚大图就可以理解为什么它们是例外。也就是说,在处理琐碎的单行if实体时,我认为该规则不适用。作为一个极端的例子,我从未见过有人将ArgumentNullException等的引发异常的语句放在VB.NET的函数结尾。
\ $ \ endgroup \ $
–hvd
2014年8月16日在22:15
\ $ \ begingroup \ $
如果更改为while(瓶数> 1),则可以保存比较和分支在此答案中,尤其是如代码所示,它将打印“ 1瓶...”然后是“ 1瓶...”
\ $ \ endgroup \ $
–詹姆斯·斯内尔(James Snell)
2014-10-28 8:35
#3 楼
这似乎是模板元编程有用的地方(毕竟,我们不想在可能经常执行的程序中浪费宝贵的运行时间)。#include <iostream>
template<int N>
struct song {
inline static void sing() {
std::cout << N << " bottles of beer on the wall, "
<< N << " bottles of beer.\nTake one down, pass it around, "
<< N - 1 << " bottles of beer on the wall.\n\n";
song<N - 1>::sing();
}
};
template<>
struct song<1> {
inline static void sing() {
std::cout << "1 bottle of beer on the wall, 1 bottle of beer.\n"
<< "Take it down and pass it around, no more bottles of beer on the wall.\n\n"
<< "No more bottles of beer on the wall, no more bottles of beer.\n"
<< "Go to the store and buy some more, 99 bottles of beer on the wall.\n";
}
};
template<>
struct song<2> {
inline static void sing() {
std::cout << "2 bottles of beer on the wall, "
<< "2 bottles of beer.\nTake one down, pass it around, "
<< "1 bottle of beer on the wall.\n\n";
song<1>::sing();
}
};
int main() {
song<99>::sing();
return 0;
}
尽管模板的顺序(首先是通用模板,然后是
1
的专业化,最后是2
的专业化)可能看起来很奇怪并且很随意,但实际上是有必要的。一般情况必须在进行任何专业化处理之前进行。 2
的专业化使用1
的专业化,因此必须遵循它。否则,2
的专业化将尝试使用1
的通用模板,只有在这样做之后,才能找到1
的模板,从而使该模板无效。编写代码,这不会减少代码的大小。 OTOH,我相信它至少可以使语法正确。评论
\ $ \ begingroup \ $
您在那里使用的逻辑很好。保存此程序以供将来参考。
\ $ \ endgroup \ $
–大会
14年8月15日在7:54
\ $ \ begingroup \ $
我想看看您的性能基准…和呼吸测试仪结果。
\ $ \ endgroup \ $
– 200_success
2014年8月15日在7:56
\ $ \ begingroup \ $
OP是一个自白的初学者-这会吓到他们!
\ $ \ endgroup \ $
–user3791372
2014年8月15日13:10
\ $ \ begingroup \ $
@ user3791372:我无法想象这怎么会吓到任何人。从字面上看,这是完成这项工作的最简单的程序-它的循环复杂度为1(不是其中的单个if语句或其他流控制语句)。
\ $ \ endgroup \ $
–杰里·科芬(Jerry Coffin)
2014年8月15日13:31
\ $ \ begingroup \ $
@JerryCoffin:听到有多少初学者对递归概念感到困惑,您会感到惊讶。
\ $ \ endgroup \ $
–没人远离SE
2014年8月28日上午10:42
#4 楼
不需要的代码:您实际上可以删除此代码:
if (bottle == 1)
{
break;
}
您处于while循环中,因此只要
bottle
为大于0。所以我猜您为最后一个瓶子插入了该代码。
while (bottle > 0)
获得相同的结果。
命名:
虽然您没有太多要调用的var =>我喜欢你已经指向瓶子了。
我仍然认为
bottleCount
可能是一个更好的var名称。同时循环:
没什么大的不同,但为了您自己,请使用for循环。
您不要忘了减去一个。
while (bottle > 1)
摘要:
虽然我不是c ++编码器,但它看起来很不错。
如果您真的想得分很高,可以对for循环使用递归。
评论
\ $ \ begingroup \ $
当然,现在我正在使用for循环,它可以工作。使用if是毫无意义的,我对C ++不满意,因此感谢您的信息和帮助。
\ $ \ endgroup \ $
–大会
14年8月14日在11:51
\ $ \ begingroup \ $
我刚刚编辑了for循环,因为其中有一个复制粘贴错误,我的目的是:)
\ $ \ endgroup \ $
– chillworld
14年8月14日在11:57
\ $ \ begingroup \ $
请使用--bottleCount而不是bottleCount--。应该已经将此语言命名为++ C。每次让我哭泣:-(
\ $ \ endgroup \ $
–AurélienOoms
14年8月15日在7:30
\ $ \ begingroup \ $
oke的性能问题:stackoverflow.com/a/24904/2853637
\ $ \ endgroup \ $
– chillworld
14年8月15日在8:39
#5 楼
输出错误您有一个多元错误:
墙上有2瓶啤酒,有2瓶啤酒。
倒下一瓶并通过它周围有1瓶啤酒。
此外,通常用换行符结束程序的输出。
问题的结构和分解
单瓶经文有一种特殊情况。也许可以将其概括一下。一种可能的策略是将其视为国际化问题。
但是,将其作为C ++编程实践来进行会更有趣和更具启发性。因此,我认为知道如何正确进行复数化和大写的对象是一个好主意。
建议的解决方案
评论
\ $ \ begingroup \ $
为什么我现在找不到杰夫·阿特伍德(jeff atwoods)关于多元“虫子”的评论?
\ $ \ endgroup \ $
–Vogel612♦
14年8月14日在22:22
\ $ \ begingroup \ $
喝完98瓶啤酒后,就尝试正确地语法。
\ $ \ endgroup \ $
– CashCow
2014年8月15日上午11:13
#6 楼
Chillworld提到了该解决方案,我将做一点扩展。有效地进行操作,并且不需要if块。如果您设置while语句以说出
while (bottle > 1)
并删除if代码块,它将看起来像这样。当您只剩下一个瓶子时,仍然会有瓶子的复数形式的问题,我想尽管在喝完98瓶啤酒之后,即使唱完最后一句话也要有科学奇迹。评论
\ $ \ begingroup \ $
要修复瓶子的复数形式,唯一的解决方案是使用(bottleCount> 2)中断循环,并使用std :: cout函数在循环外部打印出来。
\ $ \ endgroup \ $
–大会
14年8月16日在7:37
\ $ \ begingroup \ $
@Amession您如何得出这个结论?
\ $ \ endgroup \ $
–马拉奇♦
16年8月29日在13:03
评论
最好将“ \ n”替换为std :: endl。不是代码,而是语法问题:在您离开循环之前,您将打印“ ...并传递,一瓶啤酒...”;该行可能应该与其他行一起循环打印,因此它可以是单数
RE:“ \ n”与std :: endl ... @ LokiAstari提出的观点是endl强制刷新流。这对于调试信息很有用,因此您可以获取直到崩溃的输出,但否则会干扰缓冲的自然性能。 (只是要明确一点,这不是决定审美偏好的问题,因为我认为endl更具“文人化”的感觉。)
我不知道代码,但是啤酒瓶非常好...
您可以使用for循环而不是一会儿,这样可以省去手动递减(int i = 99; i> 1; i-){...}