NIM problems, C++ without fear :(

Hi, recently i bought a book called C++ without fear, and its great, however i do understand that it has some code errors. when i try to run the NIM exersise from the end of chapter 2, i get errors explaining that my break statements are not included within the loops, when i remove the break statements, i get an error: "system is declared with no type". ive probably just mucked up, but could somebody please show me the correct code or any edits to it that would make the following work? thanks.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <stdlib.h>

using namespace std;

int main(int argc, char *argv[])
{
    int total, n;
  cout << "Welcome to NIM. Pick a starting total: ";
  cin >> total;
  if ((total % 3) == 2) {
      total = total - 2;
      cout << "I am subtracting two." << endl;
  } else {
      total = total--;
      cout << "I am subtracting 1." << endl;
  }
  cout << "New total is " << total << endl;
  if (total == 0) {
      cout << "I WIN!!" << endl;
      break;
  }
  cout << "Enter a number to subtract (1 or 2): ";
  cin >> n;
  while (n < 1 || n > 2) {
      cout << "Input must be 1 or 2." << endl;
      cout << "Re - enter: " << endl;
      cin >> n;
  }
    total = total - n;
    cout << "New total is " << total << endl;
    if (total == 0) {
        cout << "You Win!" << endl;
        break;
    }
  }
  system("PAUSE");	
  return 0;
}
Last edited on
Whatever that book is "great" for, is not teaching C++.

The example you posted has multiple errors

line 15 (total = total--;) is an undefined expression in C++.
line 21 (break;) is invalid C++ (break outside of loop/switch)
line 34 (break;) is invalid C++ (break outside of loop/switch)
line 37-39 contain code outside of the main() function, which ended with the } on line 36

You or the book probably omitted a loop statement somewhere in the beginning of the main function, perhaps between lines 10 and 11 (which would explain the breaks and the closing } on line 36), but it doesn't excuse line 15.
Last edited on
The above code sample is a misquote.
hi, thanks a lot, i can see the problems in lines 21-39, but in line 15 i am using a decrement operator. thanks again :)
but in line 15 i am using a decrement operator.
Yes, and you're using it erroneously. If you wrote total--; or --total;, or total -= 1;, or total = total-1;, it would all be valid. total = total--; is an error. The behavior of your program is unpredictable (in practice, on some compilers/platforms it will decrement, on others it won't)

but in line 15 i am using a decrement operator.
Yes, and you're using it erroneously.

ok, i can see that your saying some environments wont allow it but all my statement is saying is "total is now equal to (total - 1)". surely this is equivalent to total = total - 1;?
Last edited on
No, total = total--; is not equivalent to total = total - 1;
is it not equal, or can a compiler simply not comprehend it? because i know my compiler supports this feature, whether or not this differs from environment to environment, i do not know.
Last edited on
See, basically, C++ does not allow two... "versions" if you may, of the same variable in the same statement.. It becomes compiler-dependent... (Something I learnt well from these very forums.. )
So its valid to have:
1
2
3
4
some_variable=some_other_variable-- ;
some_variable=--some_other_variable;
some_variable=some_other_variable++;
some_variable=++some_other_variable;


Also valid statements are:
1
2
3
4
5
int some_variable=5;
some_variable--;         //Value here is 5
some_variable++;       //Value here is 4
--some_variable;        //Value here is 4
++some_variable;      //Value here is 5 


It is however not valid to have:
some_variable=some_variable--;
or its variations...

Hope this helps... :)
Caprico is absolutly correct. You should not be doing this... ever.

To elaborate more on what he's saying, if you are modifying a variable, you should not read or write that variable anywhere else until the next sequence point (typically the next semicolon).

The reason for this is because the compiler has some liberties to rearrange things.

Take for instance the classic example:

1
2
3
4
int foo = 0;
int bar = ++foo + foo++;

cout << bar;  // what is bar? 


The prefix operator (++foo) increments foo and returns the NEW value (value after incrementing)
The postfix operator (foo++) increments foo and returns the OLD value (value before incrementing)

C++ says the above could be interpretted many ways. The compiler might choose to evaluate foo++ first, or it might choose to evaluate ++foo first.

Possible ways the compiler might interpret it are this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
++foo;  // prefix, foo = 1
int oldfoo = foo;
foo++;  // postfix
bar = foo + oldfoo; // bar = 2
// end result:  bar=2

// OR
int oldfoo = foo;
++foo;  // prefix, foo = 1
bar = foo + oldfoo;
foo++;  // postfix
// end result:  bar=1

// OR

int oldfoo = foo;
foo++;  // postfix (foo=1)
++foo;  // prefix, foo = 2
bar = foo + oldfoo;
// end result:  bar=3 


None of these results are "wrong". Yet they are all different. Which you get will depend on which version of which compiler you're using. What's more, you might get something completely different! The behavior is undefined! Anything goes!

So yeah, don't do this. It's bad bad bad.


More directly, your example:

1
2
int bar = 1;
bar = bar--;


Could be interpretted several ways:

1
2
3
4
5
6
7
8
9
10
int oldbar = bar;
bar--;  // bar=0
bar = oldbar;
// end result:  bar=1

// OR
int oldbar = bar;
bar = oldbar;
bar--;
// end result:  bar=0 


Again, neither is "wrong". The behavior is undefined.
Last edited on
ok, in the end i just typed loads of "erroneous" examples and compiled - im guessing this validity problem is similar to 1 = 2 - something that really shouldn't (and in most cases, doesn't,) work. thanks guys, really appreciated
Always welcome... :)
Topic archived. No new replies allowed.