# C++ (help me, please!!)

**URL:** <https://boards.straightdope.com/t/c-help-me-please/133287>\
**Category:** Factual Questions\
**Created:** [October 21, 2002, 8:33pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287 "2002-10-21T20:33:44Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![booklover](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@booklover](https://boards.straightdope.com/u/booklover)\
**Post date:** [October 21, 2002, 8:33pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287/1 "2002-10-21T20:33:44Z")

</div>

Long story short: I’m trying to do a sentinel-controlled loop, which is highly unclear in my book. Here’s the code & results----PLEASE tell me what’s wrong and how to fix it!

Code:  
#include \<iostream\>

using std::cout;  
using std::cin;  
using std::endl;

int main()  
{  
int hrworked, rate, grosspay, hourCounter;  
hourCounter=0;

```
while ( hrworked != -1) {
	hourCounter = hourCounter + 1;
	cout&lt;&lt;"Enter number of hours worked, -1 to end: ";
	cin&gt;&gt;hrworked;
	cout&lt;&lt;"Enter hourly rate: ";
	cin&gt;&gt;rate;
	if (hrworked &lt; 40)
		grosspay=hrworked*rate;
	else
		grosspay=(40*rate)+((hrworked-40)*(rate*1.5));
	cout&lt;&lt;"This is the total pay "&lt;&lt;grosspay&lt;&lt;endl;
}
return 0;
}

```

Results:  
Enter number of hours worked, -1 to end:  
10  
Enter hourly rate: 32  
This is the total pay 320  
Enter number of hours worked, -1 to end: -1  
Enter hourly rate: 10  
This is the total pay -10  
Press any key to continue  
Why is the darn -1 not working???

---

<div class="post-metadata">

**Author:** ![typo\_mna](https://avatars.discourse-cdn.com/v4/letter/t/eb8c5e/32.png) [@typo\_mna](https://boards.straightdope.com/u/typo_mna)\
**Post date:** [October 21, 2002, 9:04pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287/2 "2002-10-21T21:04:14Z")

</div>

It looks to me like it’s because it only checks to see if hrworked is -1 at the beginning of the while loop. You want to put another check in there immediately after it reads in a new value for hrworked.

---

<div class="post-metadata">

**Author:** ![Flymaster](https://avatars.discourse-cdn.com/v4/letter/f/c4cdca/32.png) [@Flymaster](https://boards.straightdope.com/u/Flymaster)\
**Post date:** [October 21, 2002, 9:13pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287/3 "2002-10-21T21:13:31Z")

</div>

hrworked is uninitialized when you first check its value in the while() statement.

What you want to do is read in a value BEFORE you enter the loop, then read in a new value at the very end of the loop.

---

<div class="post-metadata">

**Author:** ![William\_Ashbless](https://avatars.discourse-cdn.com/v4/letter/w/a87d85/32.png) [@William\_Ashbless](https://boards.straightdope.com/u/William_Ashbless)\
**Post date:** [October 21, 2002, 10:14pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287/4 "2002-10-21T22:14:13Z")

</div>

Another alternative is to use a do-while loop, putting the test at the bottom, but also within the loop use an if conditional to only process the rate and mathematical part of the loop in the event hr is not -1.

Personally, I prefer Flymaster’s solution asking for a first value of hrworked outside of (before) the loop and again inside but at the end of the loop, but as usual There Is More Than One Way To Do It (TIMTOWTDI).

Anyway, the reason the -1 entry didn’t work should be fairly evident. Everything happens in sequence. By the time the code that reads in the -1 is executed, the choice as to whether or not to enter the loop is already several statements previous. The loop does not stop _instantly_ and magically the moment hrworked is -1. It enters/reenters the loop based on a test at the top of the loop _when the top of the loop is reached_, and at no other time.

Also, of course, the comment has already been made about uninitialized variables. Variables do not have some magic default value when they are declared, unless you give them an initial value. If you do not fill them, they could be _anything_.

---

<div class="post-metadata">

**Author:** ![Khadaji](https://avatars.discourse-cdn.com/v4/letter/k/9e8a1a/32.png) [@Khadaji](https://boards.straightdope.com/u/Khadaji)\
**Post date:** [October 22, 2002, 1:16am UTC](https://boards.straightdope.com/t/c-help-me-please/133287/5 "2002-10-22T01:16:00Z")

</div>

Try this as your while loop:

while (1) {  
hourCounter = hourCounter + 1;  
cout\<\<"Enter number of hours worked, -1 to end: ";  
cin\>\>hrworked;  
if(hrworked == -1)  
break;  
cout\<\<"Enter hourly rate: ";  
cin\>\>rate;  
if (hrworked \< 40)  
grosspay=hrworked_rate;  
else  
grosspay=(40_rate)+((hrworked-40)_(rate_1.5));  
cout\<\<"This is the total pay "\<\<grosspay\<\<endl;  
}

---

<div class="post-metadata">

**Author:** ![Flymaster](https://avatars.discourse-cdn.com/v4/letter/f/c4cdca/32.png) [@Flymaster](https://boards.straightdope.com/u/Flymaster)\
**Post date:** [October 22, 2002, 1:51am UTC](https://boards.straightdope.com/t/c-help-me-please/133287/6 "2002-10-22T01:51:30Z")

</div>

Nah, don’t do that. Break is evil, and there’s (almost) never any reason to use it in a while loop. That’s why they invented do/while loops, or, more accurately, that’s why they invented the while loop. It builds that break right in to it.

---

<div class="post-metadata">

**Author:** ![Pleonast](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/pleonast/32/1183_2.png) [@Pleonast](https://boards.straightdope.com/u/Pleonast)\
**Post date:** [October 22, 2002, 3:11am UTC](https://boards.straightdope.com/t/c-help-me-please/133287/7 "2002-10-22T03:11:40Z")

</div>

Here’s how I would write it:

```auto

double hrworked, rate, grosspay;
int hourCounter;
for(hourCounter=0; true; ++hourCounter)
 {
  cout<<"Enter hours worked (-1 to end): ";
  cin>>hrworked;
  if(hrworked<0.0) break;
  cout<<"Enter hourly rate: ";
  cin>>rate;
  if(hrworked<=40.0)
    grosspay=hrworked*rate;
  else
    grosspay=(40.0+(hrworked-40.0)*1.5)*rate;
  cout<<"This is total pay: "<<grosspay<<endl;
 }

```

Comments:[ol][_]I use doubles for the hours, rate, pay because that seems more appropriate. I made the numerical constants doubles, likewise. I also factored the overtime pay calculation (reduces it from 5 to 4 ops).[_]I put hourCounters as the counter of a for loop, because that seems how you’re wanting to use it. It’s defined outside the loop, so you can access it outside the loop.I use a true condition on the loop, and place the condition check inside the loop (as **Khadaji** does). This is a reasonable place for it since you read the variable in the middle of the loop. As has been suggested, you could set the variable before the loop. I prefer to keep assignments and checks closer together for simpler code. As **Flymaster** suggested, you could read the value before entering the loop. But this then requires two separate read statements (this is a problem if you decide to change the code, then you must change it in two places). Using a break here is an easy way to make the logic very simple to understand.[/ol]

---

<div class="post-metadata">

**Author:** ![Ms2001](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/ms2001/32/18463_2.png) [@Ms2001](https://boards.straightdope.com/u/Ms2001)\
**Post date:** [October 22, 2002, 3:32am UTC](https://boards.straightdope.com/t/c-help-me-please/133287/8 "2002-10-22T03:32:06Z")

</div>

Pshaw, there’s nothing wrong with break. If you decide it’s “against the rules” to use break, you end up with code like this:

```auto

stopping = 0;
while (!stopping && the_real_condition) {
  ... code ...
  if (something_bad) stopping = 1;
  if (!stopping) {
    ... more code ...
  }
}

```

Is that really any clearer than this?

```auto

while (the_real_condition) {
  ... code ...
  if (something_bad) break;
  ... more code ...
}

```

---

<div class="post-metadata">

**Author:** ![Khadaji](https://avatars.discourse-cdn.com/v4/letter/k/9e8a1a/32.png) [@Khadaji](https://boards.straightdope.com/u/Khadaji)\
**Post date:** [October 22, 2002, 12:41pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287/9 "2002-10-22T12:41:42Z")

</div>

> [@](#):
>
> \*Originally posted by Flymaster \*  
> \*\*Nah, don’t do that. Break is evil, and there’s (almost) never any reason to use it in a while loop. That’s why they invented do/while loops, or, more accurately, that’s why they invented the while loop. It builds that break right in to it. \*\*

I disagree. Putting the break near where you want makes it much more readable. You want to break near the place you read the condition. And, when you are stepping through code with your debugger (something you shoud ALWAYS do, no matter how good you think you are) you can see exactly what caused the loop to break.

---

<div class="post-metadata">

**Author:** ![William\_Ashbless](https://avatars.discourse-cdn.com/v4/letter/w/a87d85/32.png) [@William\_Ashbless](https://boards.straightdope.com/u/William_Ashbless)\
**Post date:** [October 22, 2002, 3:43pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287/10 "2002-10-22T15:43:37Z")

</div>

At the risk of pointing out what we shouldn’t be posting full source code solutions to someone’s homework, and then breaking that myself, I’ll post my algorithm, which doesn’t involve breaks or additional booleans or anything else. I think this outlines the basic solution posted by Flymaster, and is possibly the most elegant solution:

read a value into x  
while (x is not the sentinel)  
{  
…  
…  
do something with x  
…  
…  
read a value into x  
}

One of the cleaner solutions. If I were to pick any other solution here… well, I probably would recommend something halfway between Khadaji and Pleonast:

set x to a non-sentinel value initially  
while (x is not the sentinel)  
{  
read a new value into x

if x is not the sentinel  
{  
…  
do something with x  
…  
}  
}

or better:

do  
{  
read a new value into x

if x is not the sentinel  
{  
…  
do something with x  
…  
}  
} while (x is not the sentinel)  
These are both relatively clean, don’t involve any additional awkward booleans, and say pretty much what is meant by the intent of the loop (translates from an English description of the intent of the problem quite well).

I can’t say I believe break is evil (judiciously used) or that falling out of a loop naturally by way of extra conditions is a problem (especially if its fairly clearly written, and you’re several layers deep in loops or switches). For whatever my opinion’s worth.

Except for possibly the treacherous overpowered goto, I tend to use the tools in a maintainable easy to read way… but then I have to write and maintain large amounts of code for a living, so I’m sensitive to overcleverness. 🙂 (Check the sig)

---

<div class="post-metadata">

**Author:** ![William\_Ashbless](https://avatars.discourse-cdn.com/v4/letter/w/a87d85/32.png) [@William\_Ashbless](https://boards.straightdope.com/u/William_Ashbless)\
**Post date:** [October 22, 2002, 3:45pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287/11 "2002-10-22T15:45:19Z")

</div>

damn, sig got munched. Let’s try again, cause I like it.

---

<div class="post-metadata">

**Author:** ![ftg](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/ftg/32/2801_2.png) [@ftg](https://boards.straightdope.com/u/ftg)\
**Post date:** [October 22, 2002, 4:00pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287/12 "2002-10-22T16:00:55Z")

</div>

As an ex-C++ instructor, let me say that the “officially preferred” method is what **Flymaster** suggests. It’s verbose but considered good practice for newbie programmers. The books will also suggest the “if”-protected loop body method a la **MR2001**. Note that “while(1)” is totally baffling to novices and generally avoided in beginner courses.

Both methods would be avoided in real life by real programmers who would use the break. Note that the verbose method means that if you change something about the sentinel you have to make the same change in two places.

**Booklover** , your compiler should have caught the unintialized value and warned you about it. (I know g++ would.) Check the flags to your compiler and and turn on those that give you warnings about such stuff.

---

<div class="post-metadata">

**Author:** ![William\_Ashbless](https://avatars.discourse-cdn.com/v4/letter/w/a87d85/32.png) [@William\_Ashbless](https://boards.straightdope.com/u/William_Ashbless)\
**Post date:** [October 22, 2002, 4:05pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287/13 "2002-10-22T16:05:10Z")

</div>

Funny, I’m a ‘real programmer’ writing ‘real programs’ and I still prefer what FlyMaster suggests (unless the cost of twice setting up the value being tested is truly onerous and then … I’d probably use the break method). 🆒

Oh well, TIMTOWTDI.  
😃

---

<div class="post-metadata">

**Author:** ![Pleonast](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/pleonast/32/1183_2.png) [@Pleonast](https://boards.straightdope.com/u/Pleonast)\
**Post date:** [October 22, 2002, 5:27pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287/14 "2002-10-22T17:27:39Z")

</div>

> [@](#):
>
> I still prefer what FlyMaster suggests (unless the cost of twice setting up the value being tested is truly onerous and then … I’d probably use the break method)

For me, it’s not a question of how onerous setting the value is. It’s more that I don’t like repeating code. Each repetition is a new place for a bug to enter whenever that repeated code needs to changed.

If I truly wanted to use Flymaster’s logic (and it does have some appeal), I’d create a small function that would read in the value. I could then call that one function from as many places as necessary. And, if the read process needed to change, fixing the function would have effect in both places.

> [@](#):
>
> At the risk of pointing out what we shouldn’t be posting full source code solutions to someone’s homework,

One homework problem won’t make a difference in the long run. And this thread is an excellent example of how real programmers can approach a problem from different angles.

---

<div class="post-metadata">

**Author:** ![William\_Ashbless](https://avatars.discourse-cdn.com/v4/letter/w/a87d85/32.png) [@William\_Ashbless](https://boards.straightdope.com/u/William_Ashbless)\
**Post date:** [October 22, 2002, 5:43pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287/15 "2002-10-22T17:43:02Z")

</div>

> [@](#):
>
> \*Originally posted by Pleonast \*  
> \*\*One homework problem won’t make a difference in the long run. And this thread is an excellent example of how real programmers can approach a problem from different angles. \*\*

\< philosophy \>  
‘Just one’ homework problem is just as bad as many – its a bad habit to get into. If everyone answers explicitly ‘just one’ homework problem, pretty much all the C++ questions that come to this board will be explicitly answered. There are more answerers than questioners by a wide margin.

I’ve learned over the years explicit examples are more valuable to some people than others when learning this stuff. Fair enough. Myself, I try to restrict myself to pseudocode where I can gloss over those bits of the code that don’t directly deal with the question at hand. I find pseudocode even helps some people in the mental process of translating their intent to code. Most of time time I try to nudge and hint before I even get to pseudocode. But that’s just me.  
\< /philosophy \>

Having vented a little, I agree – it is fascinating seeing the different angles of attack, and evaluating the benefits and detriments. Its rare in my workplace to have a fine debate on the academic and practical art we practice. I’m sure the original poster has a lot to chew on. 🙂

> [@](#):
>
> \*Originally posted by Pleonast \*  
> **For me, it’s not a question of how onerous setting the value is. It’s more that I don’t like repeating code. Each repetition is a new place for a bug to enter whenever that repeated code needs to changed.**

I agree with this, actually, so long as there’s enough code in which a bug may exist. A single output statement followed by a single input statement, duplicated as in the example, doesn’t leave a lot of room for a bug. But I suppose it doesn’t take much before I can no longer reasonably make that claim.

> [@](#):
>
> \*Originally posted by Pleonast \*  
> **If I truly wanted to use Flymaster’s logic (and it does have some appeal), I’d create a small function that would read in the value. I could then call that one function from as many places as necessary. And, if the read process needed to change, fixing the function would have effect in both places.**

I agree with this too. I’m not sure I’d go this far if it was as simple a situation as I just described. A one-line call to a function, or a two-line prompted input, isn’t much different in my books in terms of complexity. But once you start drifting outside of the extremely simple, I’m with you on non-duplication. I hate fixing things twice. 🙂

---

<div class="post-metadata">

**Author:** ![Flymaster](https://avatars.discourse-cdn.com/v4/letter/f/c4cdca/32.png) [@Flymaster](https://boards.straightdope.com/u/Flymaster)\
**Post date:** [October 22, 2002, 9:48pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287/16 "2002-10-22T21:48:20Z")

</div>

But, Pleonast, that “small function” has already been written for you. The extraction operator ( \>\> ), is nothing more than a function. You can overload it all you want, yadda yadda. There’s no need to write a function for this. If, for some reason, you wanted to change the way that you read in an integer to reading in an object of some kind, you just overload \>\> and it’ll be done for you. There’s no need for a separate wrapper.

---

<div class="post-metadata">

**Author:** ![William\_Ashbless](https://avatars.discourse-cdn.com/v4/letter/w/a87d85/32.png) [@William\_Ashbless](https://boards.straightdope.com/u/William_Ashbless)\
**Post date:** [October 22, 2002, 9:59pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287/17 "2002-10-22T21:59:16Z")

</div>

There would be if it were a more complex bootstrapping procedure for the loop, say something that needs to read in several variables, do lots of prompting, some calculations, etc.

In _this_ case (for the sake of the OP), you’re right. In a more complicated case, it might benefit wrapping up the mechanism being used, if you wanted to use the logic in question.

---

<div class="post-metadata">

**Author:** ![Pleonast](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/pleonast/32/1183_2.png) [@Pleonast](https://boards.straightdope.com/u/Pleonast)\
**Post date:** [October 23, 2002, 12:52am UTC](https://boards.straightdope.com/t/c-help-me-please/133287/18 "2002-10-23T00:52:10Z")

</div>

What **William\_Ashbless** said.

And actually, this example is sufficiently complex. We’re not only reading in a variable, we’re also outputing a prompt. What if you want to change the prompt? You’ll have to change the string in two places. Although mismatched prompts is not an especially nasty bug, it demonstrates the problem of have the “same” code in more than one place.

---

<div class="post-metadata">

**Author:** ![William\_Ashbless](https://avatars.discourse-cdn.com/v4/letter/w/a87d85/32.png) [@William\_Ashbless](https://boards.straightdope.com/u/William_Ashbless)\
**Post date:** [October 23, 2002, 3:43pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287/19 "2002-10-23T15:43:30Z")

</div>

Perhaps, but maybe the first time around you’d want a separate prompt. 😕

I dunno, at these nitpicky levels, its a matter of personal preference, I think. 😃

I think we’ve beaten the OP to death though.

---

<div class="post-metadata">

**Author:** ![William\_Ashbless](https://avatars.discourse-cdn.com/v4/letter/w/a87d85/32.png) [@William\_Ashbless](https://boards.straightdope.com/u/William_Ashbless)\
**Post date:** [October 23, 2002, 3:52pm UTC](https://boards.straightdope.com/t/c-help-me-please/133287/20 "2002-10-23T15:52:07Z")

</div>

Perhaps, but maybe the first time around you’d want a separate prompt. 😕

I dunno, at these nitpicky levels, its a matter of personal preference, I think. 😃

I think we’ve beaten the OP to death though.

[Next page](https://boards.straightdope.com/t/c-help-me-please/133287.md?page=2)
