View Full Version : n00b C++ problem
mac2x
Nov 13, 2009, 01:19 AM
Some of you might remember my previous thread about Interface Builder...well I've been trying to get back to the basics and actually learn C++.
I'm using Xcode 3.1 in OS 10.5.8.
Basically I'm trying to compile this, and then subsequently change things to get a different output:
#include<iostream>
using namespace std;
int main( int argc, char *argv[]) {
char myCharacter = 'z';
cout << "The datatype is " << sizeof(int) << " bytes!" << endl;
cout << "The variable has a value of " << myCharacter << endl;
return 0;
}
I'm compiling in Terminal using g++. However, g++ returns these errors:
program2.cpp: In function ‘int main(int, char**)’:
program2.cpp:16: error: ‘end1’ was not declared in this scope
program2.cpp:17: error: ‘z’ was not declared in this scope
Bear in mind that I'm a pretty rank n00b at this. I can't figure out what needs to be done to fix the errors, or if I'm missing a syntax error or have done something in my code. I know that these things should be declared, but how?
Many thanks for any help/advice! :)
lloyddean
Nov 13, 2009, 01:37 AM
There is nothing wrong with the code as posted. Perhaps the code being compile is different than what's here?
lee1210
Nov 13, 2009, 08:37 AM
Those errors will not result from compiling the code you posted. At some point you accidentally typed end1, ending with the the number 1, instead of endl, ending with the letter l. Also, the code you posted has 10 lines, so it's definitely not what you compiled if there are errors on lines 16 and 17. The z thing probably means you tried something similar to the code above, but didn't have the z in single or double quotes.
Post the command line you ran, and maybe just "ll *.cpp" to see all of the cpp files in the directory you're compiling in.
-Lee
mac2x
Nov 13, 2009, 09:36 AM
Ooops. I was tired when I posted this and forgot to get all the lines! And I accidentally removed a line as well. :rolleyes: Apologies... :o
/*
* program2.cpp
*
*
* Created by [redacted] on 11/12/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include<iostream>
using namespace std;
int main( int argc, char *argv[]) {
char myCharacter = 'z';
cout << "The datatype is " << sizeof(int) << " bytes! " << end1;
cout << "The variable has a value of " << myCharacter << end1;
return 0;
}
mac2x
Nov 13, 2009, 09:43 AM
Those errors will not result from compiling the code you posted. At some point you accidentally typed end1, ending with the the number 1, instead of endl, ending with the letter l. Also, the code you posted has 10 lines, so it's definitely not what you compiled if there are errors on lines 16 and 17. The z thing probably means you tried something similar to the code above, but didn't have the z in single or double quotes.
Post the command line you ran, and maybe just "ll *.cpp" to see all of the cpp files in the directory you're compiling in.
-Lee
OK, I got rid of the second error because I had mistakenly placed a "z" instead of "myCharacter". :rolleyes: So "end1" should be "endl"?
program2.cpp: In function ‘int main(int, char**)’:
program2.cpp:16: error: ‘end1’ was not declared in this scope
sammich
Nov 13, 2009, 09:45 AM
OK, I got rid of the second error because I had mistakenly placed a "z" instead of myCharacter. So "end1" should be "endl"?
program2.cpp: In function ‘int main(int, char**)’:
program2.cpp:16: error: ‘end1’ was not declared in this scope
It's endl as in end line
Cromulent
Nov 13, 2009, 09:49 AM
I'm probably being pedantic but it should be
sizeof(char)
instead of
sizeof(int)
mac2x
Nov 13, 2009, 10:36 AM
It's endl as in end line
Got it, thanks. :) I type out everything by hand, so I imagine that is introducing little misunderstandings like that. Makes more sense than 'end1', too! Will edit my code and recompile...
mac2x
Nov 13, 2009, 10:37 AM
I'm probably being pedantic but it should be
sizeof(char)
instead of
sizeof(int)
I wouldn't know! But it would be worth trying both to see if it makes any difference.
mac2x
Nov 13, 2009, 10:41 AM
Changing to 'endl' fixed the problem; it compiled and produced this output:
The datatype is 4 bytes!
The variable has a value of z
Implementing Cromulent's suggestion reduced the size to 1 byte:
The datatype is 1 bytes!
The variable has a value of z
lee1210
Nov 13, 2009, 11:34 AM
ah, but now bytes doesn't make sense. Maybe change it to byte(s), or get fancier and decide if the s belongs conditionally.
-Lee
mac2x
Nov 13, 2009, 11:39 AM
Thanks, Lee. I'll think about that. I know I still have a lot to learn, but this is so much fun! :)
Sander
Nov 13, 2009, 12:39 PM
Thanks, Lee. I'll think about that. I know I still have a lot to learn, but this is so much fun! :)
If you seriously feel that printing out the contents of a single variable, along with the fact that it takes 1 byte in memory, is fun... then you have a bright future ahead in programming.
I'm serious.
I've seen so many times that beginners think they'll start off with writing a simple 3D first person shooter ("a simple one, without network playing and all that") and then be seriously desillusioned after the first few days.
But let's be clear about it: if you consider what a huge amount of stuff is going on inside your computer when you run that simple first program, it's mind boggling. And fun!
mac2x
Nov 13, 2009, 01:21 PM
If you seriously feel that printing out the contents of a single variable, along with the fact that it takes 1 byte in memory, is fun... then you have a bright future ahead in programming.
I'm serious.
I've seen so many times that beginners think they'll start off with writing a simple 3D first person shooter ("a simple one, without network playing and all that") and then be seriously desillusioned after the first few days.
But let's be clear about it: if you consider what a huge amount of stuff is going on inside your computer when you run that simple first program, it's mind boggling. And fun!
Sander, this made me smile. :) Thanks for the support.
I've seen a goodly number of those threads here, too. I know exactly what you mean. I successfully wrote using Objective-C a simple screen saver that draws and shades 2d polygons, but it was a lot of work doing things I only barely understood! How could any n00b like me hope to write a first person shooter in 3d when it's a lot of work just to get a 2d screensaver to work?!?? I realized from my fiddling in Objective-C that I need the basics, so here I am!
It is mind-boggling to think of how complex this stuff is; and that's why it's fun! :)
mac2x
Nov 13, 2009, 06:40 PM
OK, I fixed all the problems.
/*
* program2.cpp
*
*
* Created by [redacted] on 11/12/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include<iostream>
using namespace std;
int main( int argc, char *argv[]) {
int myCharacter = 'z';
cout << "The datatype is " << sizeof(char) << " byte(s)! " << endl;
cout << "The variable has a value of " << myCharacter << endl;
return 0;
}
When compiled and run:
The datatype is 1 byte(s)!
The variable has a value of 122
I don't understand exactly where it's getting the 122, though. :confused:
lee1210
Nov 13, 2009, 06:57 PM
The datatype of myCharacter is int. This holds a signed numerical value. You are assigning a char, and it is getting implicitly (without you explicitly stating it should be done) promoted/cast to an int. In this case, the ASCII value of lowercase z is 122. In C++ operator<< on cout allows for many types to be passed to it, and it handles each type appropriately. You are passing it a signed integer value, and it's happily printing its value.
Change the type of myCharacter to char and you should get the behavior you expect.
-Lee
Edit:
Wrote something up about the primitives:
The primitive types you'll need to familiarize yourself with are:
char - holds a signed integer value, normally in a single byte. This means it can hold values from -128 to 127 on a system using two's complement. Used to store character values, generally ASCII. Constants can be written as: 'x'.
short (int) - holds a signed integer value, it is generally stored in 2 bytes, holding values from -32768 to 32767. It could hold a wider range larger, but this is implementation specific.
int - holds a signed integer value, it is generally stored in 4 bytes, holding values from -2147483648 to 2147483647. It isn't required to be this large, but is on most modern implementations.
long int - holds a signed integer value, it is generally stored in... something. it needs to hold at least as much as i stated for int above (it's required to be as big as i said, whereas int is only required to be 2 bytes, but is normally 4 now). On my machine it's 4 bytes, so not any bigger than an int.
long long int - holds a signed integer value, it is stored in 8 bytes (or more), generally holding values from -9223372036854775808 to 9223372036854775807.
There are unsigned versions of each(you can prepend unsigned in a declaration), such that only values greater than 0 can be stored, and the positive range is higher.
Next are floating point values:
float - low precision floating point value. Generally 4 bytes on modern platforms, implemented with IEEE-754. The range is difficult to express because of the means of storage. This should only be used for very low precision calculations.
double - higher precision floating point value. Generally 8 bytes, implemented as above. Offers much better precision that a float, but you always need to be aware of rounding errors that accumulate with floating point calculations.
long double - generally higher precision floating point value, but may be the same size as double.
The other primitive types are pointers to the above types (plus the unspecified type pointer, void *). A pointer can hold a memory address. The size will vary from system to system. There are a few other things that are considered "primitive", but these are amalgams of the above, such as enums, unions, structures, and arrays.
Others are free to correct the generalizations made above, as these aren't verbatim from the standard, but I tried to get close while being practical about the systems one is likely to encounter.
mac2x
Nov 14, 2009, 01:16 AM
Thanks again! That worked as expected. :cool:
/*
* program2.cpp
*
*
* Created by [redacted] on 11/12/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include<iostream>
using namespace std;
int main( int argc, char *argv[]) {
char myCharacter = 'z';
cout << "The datatype is " << sizeof(char) << " byte(s)! " << endl;
cout << "The variable has a value of " << myCharacter << endl;
return 0;
}
The datatype is 1 byte(s)!
The variable has a value of z
That summary about primitives is much appreciated! I'll copy and paste it for a reference.
Cromulent
Nov 14, 2009, 09:41 AM
One thing I have found very handy is my O'reilly pocket references. I have one for C and Java and my Dad has one for Objective-C and they are in constant use. I'd recommend getting one for C++ as they enable you to find answers to questions without searching the internet high and low. They also tend to be quite good quality - plus they only cost about £5, bargain!
mac2x
Nov 14, 2009, 08:01 PM
One thing I have found very handy is my O'reilly pocket references. I have one for C and Java and my Dad has one for Objective-C and they are in constant use. I'd recommend getting one for C++ as they enable you to find answers to questions without searching the internet high and low. They also tend to be quite good quality - plus they only cost about £5, bargain!
That's a good idea. I must look into it. :)
Thanks for all the help with the program above! It's working as expected now. I've moved on to a slightly more complicated one. Fortunately, I was able to spot a couple of errors and fix them, so it's working as it should. However, I 'm not certain I entirely understand what it is doing.
/*
* program3.cpp
*
*
* Created by [redacted] on 11/14/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include<iostream>
using namespace std;
int main( int argc, char *argv[] )
{
int x = 1, y = 3, z = 4;
int *num;
const float pi = 3.14;
z*=y;
y = x + (int)pi;
num = &y;
if( ++z <= y-- ) {
cout << "Z: " << z << " <= Y: " << y << endl;
} else {
cout << "Z: " << z << " > Y: " << y << endl;
}
cout << "Z: " << z << endl;
cout << "Y: " << y << endl;
cout << "The base memory address of Y: " << num << endl;
cout << "The value pointed to by num: " << *num << endl;
return 0;
}
Give the following output in Terminal:
Z: 13 > Y: 3
Z: 13
Y: 3
The base memory address of Y: 0xbffffa9c
The value pointed to by num: 3
The tutorial I'm working from is one of the more involved ones I've found, yet it still doesn't explain as fully as it might. :mad:
Cromulent
Nov 14, 2009, 08:22 PM
int x = 1, y = 3, z = 4;
Declares three ints. x, y and z with the values 1, 3 and 4 respectively.
int *num;
Declares a pointer to int with an undefined value.
const float pi = 3.14;
Declares a float with a constant value of 3.14 (the value can't be changed after it has been assigned).
z*=y;
Just a short hand for:
z = z * y;
y = x + (int)pi;
x + the value of pi as an int (which is 3). This is called casting.
num = &y;
Make num point to the address of y.
if( ++z <= y-- ) {
cout << "Z: " << z << " <= Y: " << y << endl;
} else {
cout << "Z: " << z << " > Y: " << y << endl;
}
If 1 + z is less than or equal to y + 1 then:
else:
cout << "Z: " << z << endl;
cout << "Y: " << y << endl;
Print the values of z and y to the standard output.
cout << "The base memory address of Y: " << num << end
Print the address of y by printing the value of num (which is a pointer).
cout << "The value pointed to by num: " << *num << endl;
Print the value stored in the address pointed to by num via indirection.
lee1210
Nov 14, 2009, 09:01 PM
<snip>
if( ++z <= y-- ) {
cout << "Z: " << z << " <= Y: " << y << endl;
} else {
cout << "Z: " << z << " > Y: " << y << endl;
}
If 1 + z is less than or equal to y + 1 then:
else:
<snip
Everything Cromulent said was right on, except this one odd bit. I don't know why one would want to do this, but:
++z means:
Before this expression is evaluated, increment the value of z
y-- means:
After this expression is evaluated, decrement the value of y
So this code could be:
z = z + 1;
if( z <= y) {
y = y-1;
...
} else {
y = y-1;
}
So If z is less than y before it gets to this block, the if portion will be executed, otherwise the else part will be executed. I also think Cromulent meant "If 1 + z is less than or equal to y - 1 then", but because of the silly pre-increment and post-drecrement here this was a little off.
One additional note about casting any integer type to a floating point type (float, double, long double)... the cast will result in truncation of the decimal portion, NOT rounding. This can be a sticky point. There are standard functions to round floats and doubles, but it's trivial to come up with a way to do so yourself. These are not fit for round-to-even applications, etc. (.5 rounds away from 0, so up for positives, down for negatives).
-Lee
One more edit:
By the time that print statements in the block above run, the value of y has changed. This means you could have some weird results. In this case the values are fixed, but in the general case if z were to be 1 before the block, and y were to be 2, things would go like this:
Increment z to 2
If z is less than or equal to y (it is, they are both 2)
then, decrement y, then print: "Z: 2 <= Y: 1".
Which is, clearly, nonsense.
Cromulent
Nov 14, 2009, 09:24 PM
Everything Cromulent said was right on, except this one odd bit. I don't know why one would want to do this, but:
++z means:
Before this expression is evaluated, increment the value of z
y-- means:
After this expression is evaluated, decrement the value of y
Oops. I completely misread that. Thanks for the correction.
mac2x
Nov 14, 2009, 11:48 PM
Thanks, guys. More good study material for when I sit down in a few minutes to work on programming. :D
Jethrotoe
Nov 15, 2009, 08:11 AM
Good question, great answers. You guys really broke it down nicely.
Thanks,
Another Noob
mac2x
Nov 16, 2009, 08:31 PM
[...]
So this code could be:
z = z + 1;
if( z <= y) {
y = y-1;
...
} else {
y = y-1;
}
So If z is less than y before it gets to this block, the if portion will be executed, otherwise the else part will be executed. I also think Cromulent meant "If 1 + z is less than or equal to y - 1 then", but because of the silly pre-increment and post-drecrement here this was a little off.
One additional note about casting any integer type to a floating point type (float, double, long double)... the cast will result in truncation of the decimal portion, NOT rounding. This can be a sticky point. There are standard functions to round floats and doubles, but it's trivial to come up with a way to do so yourself. These are not fit for round-to-even applications, etc. (.5 rounds away from 0, so up for positives, down for negatives).
-Lee
One more edit:
By the time that print statements in the block above run, the value of y has changed. This means you could have some weird results. In this case the values are fixed, but in the general case if z were to be 1 before the block, and y were to be 2, things would go like this:
Increment z to 2
If z is less than or equal to y (it is, they are both 2)
then, decrement y, then print: "Z: 2 <= Y: 1".
Which is, clearly, nonsense.
I got rid of the pre-increment and post-decrement.
/*
* program3.cpp
*
*
* Created by [redacted] on 11/14/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include<iostream>
using namespace std;
int main( int argc, char *argv[] )
{
int x = 1, y = 3, z = 4;
int *num;
const float pi = 3.14;
z*=y;
y = x + (int)pi;
num = &y;
z = z =1;
if( z <= y ) {
y = y-1;
cout << "Z: " << z << " <= Y: " << y << endl;
} else {
y = y-1;
cout << "Z: " << z << " > Y: " << y << endl;
}
cout << "Z: " << z << endl;
cout << "Y: " << y << endl;
cout << "The base memory address of Y: " << num << endl;
cout << "The value pointed to by num: " << *num << endl;
return 0;
}
Z: 1 <= Y: 3
Z: 1
Y: 3
The base memory address of Y: 0xbffffa9c
The value pointed to by num: 3
lee1210
Nov 16, 2009, 08:47 PM
z = z =1;
You meant:
z = z + 1
or
z++;
There's no reason NOT to have the preincrement and postdecrement in the if condition, it is just a bit obtuse. In the if and else, in the print statements, you may want to print y+1 instead of y, since that will be the value when the if is evaluated. That would make more sense to me, at least. This is changing the behavior of the original code, but the behavior of the original was silly, IMO.
-Lee
mac2x
Nov 16, 2009, 08:55 PM
Ooops, thanks for the catch. I fixed it.
Is this what you had in mind? I do want to learn the difference between well thought out code, and code that works but needs improvement. :)
/*
* program3.cpp
*
*
* Created by [redacted] on 11/14/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include<iostream>
using namespace std;
int main( int argc, char *argv[] )
{
int x = 1, y = 3, z = 4;
int *num;
const float pi = 3.14;
z*=y;
y = x + (int)pi;
num = &y;
z = z =1;
if( z <= y ) {
y = y-1;
cout << "Z: " << z << " <= Y+1: " << y << endl;
} else {
y = y-1;
cout << "Z: " << z << " > Y+1: " << y << endl;
}
cout << "Z: " << z << endl;
cout << "Y: " << y << endl;
cout << "The base memory address of Y: " << num << endl;
cout << "The value pointed to by num: " << *num << endl;
return 0;
}
Z: 1 <= Y+1: 3
Z: 1
Y: 3
The base memory address of Y: 0xbffffa9c
The value pointed to by num: 3
lee1210
Nov 16, 2009, 09:04 PM
Saying you're printing Y+1 doesn't mean you are =). I would just say you're printing Y, and print y+1. I am saying this because the impression one gets from the print statements is *why* that statement is being printed, which is why i think it's best to print the value when the if was evaluated. Certainly it is a lie to say that y is its previous value, but i'm not that interested in the current value of y in this case. In fact, it would be just as well to decrement y after the if and else if you'd rather print what y was during the comparison.
When i was writing the explanation previously, i was writing something that would result in the same behavior as the original, but divided up the steps so they were (hopefully) more clear. That's why i stuck the y - 1 in both the if and else.
To design this code well, you need to know what you're trying to do. If you're just trying to learn C++ syntax, there is no good design here. Reading and understanding any piece of code will get you closer to that goal, even if it's nonsensical. Learning why it's nonsensical is what counts.
-Lee
mac2x
Nov 16, 2009, 09:28 PM
Well, I'm going to have to think on it a while. I'm sure you're right, that it doesn't matter so much when you are learning syntax.
lee1210
Nov 16, 2009, 09:47 PM
I just worked with the first copy of the code you posted. Since the values are fixed, there's no input, etc. you can pare it down to this:
#include<iostream>
int main( int argc, char *argv[] ) {
int y = 3;
int *num = &y;
std::cout << "Z: 13 > Y: 3" << std::endl << "Z: 13" <<
std::endl << "Y: 3" << std::endl <<
"The base memory address of Y: " << num << std::endl <<
"The value pointed to by num: 3" << std::endl;
return 0;
}
The only part of this program that wasn't completely fixed was the memory address of a variable. I left the initialization to 3 for y, but it's not necessary.
The rest of it is always going to go exactly the same way, and produce exactly the same output.
You may want to move on to another example. The only thing to really understand from this one, as far as I can see, is the use of a pointer to reference a position in memory, and the preincrement and postdecrement. If you understand those, move on. If you don't, what's confusing about them?
-Lee
mac2x
Nov 25, 2009, 09:35 PM
So sorry I haven't responded...been really busy with chemistry these days.
I'll have a look through that example and get back, hopefully tonight. :)
mac2x
Dec 1, 2009, 11:03 PM
OK, that chem is keeping me busy, but I had time to move to another example the other day.
/*
* program7.cpp
*
*
* Created by [redacted] on 11/26/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include <iostream>
using namespace std;
int main( int argc , char *argv[] ) {
int number ;
cout << "Enter an integer: " ;
cin >> number ;
if( number % 2 == 0 ) {
cout << number << " is even." << endl;
} else {
cout << number << " is odd." << endl;
}
return 0;
}
This one went down smoothly, so to speak. As best as I can tell, this code takes a user-supplied integer, and determines if the remainder when divided by 2 is zero (number % 2 is equal to 0). If yes, the number is even. Else, the number is odd. I think that makes good sense. :D
Anything you guys would like to point out here before I move on to another example?
BTW, I obtained an older book called C++ From The Ground Up by Herbert Schildt from a friend. It's old, but I think at this point it will be better than internet-based tutorials.
lee1210
Dec 1, 2009, 11:24 PM
As far as I can tell this is just to give you a modulus example, and it looks fine. It's not important, but:
if((x & 1) == 0) {
//even
} else {
//odd
}
is probably a bit faster. In practice it likely doesn't matter, but modulus requires a divide which is "costly", while a bitmask is "cheap". You should rarely need to worry about this, but I like to know what's really happening.
-Lee
mac2x
Dec 1, 2009, 11:45 PM
OK, thanks. I'll move on, then.
Stratoukos
Dec 2, 2009, 07:01 PM
As far as I can tell this is just to give you a modulus example, and it looks fine. It's not important, but:
if((x & 1) == 0) {
//even
} else {
//odd
}
is probably a bit faster. In practice it likely doesn't matter, but modulus requires a divide which is "costly", while a bitmask is "cheap". You should rarely need to worry about this, but I like to know what's really happening.
-Lee
I am pretty sure that any modern compiler would optimize %2 to a bit shift instead of doing a division. Aside from that, I am now actually curious as of how modulus works in a processor. I know that doing a devision in x86 assembly stores the result in one register and the remainder in another, but is there a way to get just the remainder if you want to?
As for the OP, i found this (http://cplusplus.com/doc/tutorial/) tutorial a tremendous help when I was learning C++. The site has also very good documentation for functions in the standard libraries.
mac2x
Dec 2, 2009, 11:53 PM
That looks good. Thanks for the link! :)
mac2x
Dec 19, 2009, 09:59 PM
Hey guys,
As I said before, I obtained an older C++ book from a friend. However, it shows its age because I've had to do some slight rewriting of the examples to make them work. I know a new book is better, but I haven't gotten around to it thanks to school. Any suggestions there would be most helpful. :)
Anyhoo, the current book is helping me better understand things; much better than most of the internet resources I've seen.
This one example of returning a value caused a few problems:
/*
* return.cpp
*
*
* Created by [redacted] on 12/18/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
//Returning a value
#include <iostream.h>
mul(int x, int y); //mul's prototype
main()
{
int answer;
answer = mul(10, 11); //assign return value
cout << "The answer is " << answer;
return 0;
}
//This function returns a value
mul(int x, int y)
{
return x * y; //return product of x and y
}
Obviously, some rewrite was required:
/*
* return.cpp
*
*
* Created by [redacted] on 12/18/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
//Returning a value
#include <iostream>
using namespace std;
mul(int x, int y); //mul's prototype
main()
{
int answer;
answer = mul(10, 11); //assign return value
cout << "The answer is " << answer;
return 0;
}
//This function returns a value
mul(int x, int y)
{
return x * y; //return product of x and y
}
However, despite what the books says about int being the assumed default if no type is declared, it still did not compile.
return.cpp:16: error: expected constructor, destructor, or type conversion before ‘;’ token
return.cpp: In function ‘int main()’:
return.cpp:22: error: ‘mul’ was not declared in this scope
return.cpp: At global scope:
return.cpp:30: error: ISO C++ forbids declaration of ‘mul’ with no type
After declaring int, it works as expected. Are you indeed now not allowed to leave a variable undeclared and have it assumed to be an int?
/*
* return.cpp
*
*
* Created by [redacted] on 12/18/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
//Returning a value
#include <iostream>
using namespace std;
int mul(int x, int y); //mul's prototype
main()
{
int answer;
answer = mul(10, 11); //assign return value
cout << "The answer is " << answer;
return 0;
}
//This function returns a value
int mul(int x, int y)
{
return x * y; //return product of x and y
}
The answer is 110
lloyddean
Dec 19, 2009, 10:13 PM
It's just that the C89 standard requires that 'main' returns an 'int', so compilers provide feedback that you forgot to meet that requirement.
And yes functions must declare their returns types.
mac2x
Dec 19, 2009, 10:18 PM
It's just that the C89 standard requires that 'main' returns an 'int', so compilers provide feedback that you forgot to meet that requirement.
And yes functions must declare their returns types.
OK, thanks. The book does indeed say that one can explicitly declare int; that must have been made the standard since then. I'll keep that in mind as I plow ahead...
sheepopo39
Dec 20, 2009, 07:19 AM
One thing I have found very handy is my O'reilly pocket references. I have one for C and Java and my Dad has one for Objective-C and they are in constant use. I'd recommend getting one for C++ as they enable you to find answers to questions without searching the internet high and low. They also tend to be quite good quality - plus they only cost about £5, bargain!
Oh yes, those pocket references are great, I've got one for Java, Python, and Obj-c
lloyddean
Dec 20, 2009, 11:28 AM
Bruce Eckel makes his book "Thinking in C++" available as a PDF download free of charge in hopes you'll buy his print version. His books were done based on feedback gleaned form students of his payed seminars.
mac2x
Feb 6, 2010, 07:17 PM
Hey all,
Just wanted to let those that helped me know that I haven't forgotten about programming. Haven't had much time for it lately, but I've picked C++ back up again today and I amazed myself with how little I had forgotten. Still working through that old book.
grodier
Feb 6, 2010, 08:03 PM
Don't mind if you keep the examples coming! I myself am learning the language as well. I've taken a class and have some of the basics down, but am now exploring more powerful tools such as recursion, multiple inheritance, polymorphism, templates, etc.
I'd be glad to help where I can, and learn new things as well.
mac2x
Feb 6, 2010, 10:00 PM
Don't mind if you keep the examples coming! I myself am learning the language as well. I've taken a class and have some of the basics down, but am now exploring more powerful tools such as recursion, multiple inheritance, polymorphism, templates, etc.
I'd be glad to help where I can, and learn new things as well.
I will be after I get back up to speed a little more. :cool:
mac2x
Feb 10, 2010, 12:31 AM
OK, back to the grindstone. :) Working on blocks.
I've run into a baffling issue with an example in my book. Please note that this is not the original; I added the a > b and a = b blocks. Here's the code:
/*
* blocks.cpp
*
*
* Created by [redacted] on 2/9/10.
* Copyright 2010 __MyCompanyName__. All rights reserved.
*
*/
//This program demonstrates blocks of code
#include <iostream>
using namespace std;
main()
{
int a, b;
cout << "enter first number: ";
cin >> a;
cout << "enter second number: ";
cin >> b;
if(a < b) {
cout << "First number is less than second.\n";
cout << "Their difference is: " << b-a;
}
if(a > b) {
cout << "First number is greater than second.\n";
cout << "Their sum is: " << a+b;
}
if(a = b) {
cout << "First number equals second.\n";
cout << "Their product is: " << a*b;
}
return 0;
}
The weird thing is that if int a, b are different numbers (say 4 and 5), the first block's condition is satisfied and it runs. However, it also takes the square of b!!
$ ./output
enter first number: 4
enter second number: 5
First number is less than second.
Their difference is: 1First number equals second.
Their product is: 25
Am I missing something about using more than one block?
lloyddean
Feb 10, 2010, 01:07 AM
This is a typical beginner mistake in that 'a' is being assigned the value of 'b'. The if then evaluates to true for any value of 'b' that is non zero.
if(a = b) {
should be changed as follows to perform a test of equivalence:
if(a == b) {
lee1210
Feb 10, 2010, 01:08 AM
= is assignment. An assignment is a binary operator, which evaluates to its right operand. If the right operand is non-zero, and you evaluate as a condition it will be true.
== is equivalence. It is also a binary operator, but only evaluates to true if its left and right operands are equal.
You are using one of these. You meant to use the other.
-Lee
edit: lloyddean beat me this time.
mac2x
Feb 10, 2010, 01:54 AM
This is a typical beginner mistake in that 'a' is being assigned the value of 'b'. The if then evaluates to true for any value of 'b' that is non zero.
if(a = b) {
should be changed as follows to perform a test of equivalence:
if(a == b) {
OK, big DUH moment here. I knew that. :o Sometimes, it takes someone else to spot your mistakes. Thank you, both. :) == it is!
mac2x
Feb 10, 2010, 01:58 AM
Yep, it surely works perfectly. I appreciate you guys taking the trouble to help me out, spotting little things like this. Won't make that mistake again.
Stratoukos
Feb 11, 2010, 09:08 AM
Won't make that mistake again.
Oh, yes you will. At the worst possible moment. I am not a professional programmer, but after years of programming I still sometimes forget the second =. I am pretty sure that everyone does. It happens very rarely, but when it does you don't get a compilation error. You only get obviously wrong results and in a sufficiently complex program the cause could be in a million different places, so I hope you like debugging.
A trick that some people do is to reverse the order of the comparison. So instead of 'if(a==4)', you would write 'if(4==a)'. Now if you forget the second = the compiler will get 'if(4=a)' and will throw an error (this works only if you compare with constants). I personally don't like this, since I find it decreases the code readability, but you may find it useful.
mac2x
Feb 12, 2010, 10:20 AM
Oh, yes you will. At the worst possible moment. I am not a professional programmer, but after years of programming I still sometimes forget the second =. I am pretty sure that everyone does. It happens very rarely, but when it does you don't get a compilation error. You only get obviously wrong results and in a sufficiently complex program the cause could be in a million different places, so I hope you like debugging.
A trick that some people do is to reverse the order of the comparison. So instead of 'if(a==4)', you would write 'if(4==a)'. Now if you forget the second = the compiler will get 'if(4=a)' and will throw an error (this works only if you compare with constants). I personally don't like this, since I find it decreases the code readability, but you may find it useful.
Yeah, you are probably right. :o
Thanks for the hint, I might give that a try. ;)
mac2x
Feb 21, 2010, 02:59 AM
OK, got a fresh problem for the experts here. :) As I've said, the book I'm using is quite old. Usually I'm able to determine what works and what doesn't. But an example related to global and local variables has me stumped. I'm afraid I may be missing something that's out-of-date or otherwise unsupported by the latest standards. :o Or a simple syntax error I can't see to save my life. :rolleyes:
g++ kicks back the following errors:
$ g++ -o globalvar globalvar.cpp
globalvar.cpp: In function ‘int main()’:
globalvar.cpp:26: error: ‘count’ was not declared in this scope
globalvar.cpp: In function ‘void func1()’:
globalvar.cpp:35: error: ‘count’ was not declared in this scope
The source code:
/*
* globalvar.cpp
*
*
* Created by [redacted] on 2/20/10.
* Copyright 2010 __MyCompanyName__. All rights reserved.
*
*/
//This program demostrates global variables
#include <iostream>
using namespace std;
void func1();
void func2();
int count; //global variable
main()
{
int x; //local variable
for(x=0; x<10; x++) {
count = x * 2;
func1();
}
return 0;
}
void func1()
{
cout << "count: " << count; //access global count
cout << '\n';
func2();
}
void func2()
{
int count; //local variable
for(count=0; count<3; count++) cout << '.';
}
[edit] I'm pretty certain the "=" operators are correct here; that's the way the example is written in the book.
Detrius
Feb 21, 2010, 09:45 AM
I don't know why your error messages are so terse (maybe it's a GCC version thing), but here's what I got when I tried to compile your code--it's a LOT more informative.
[Blackie:~/Documents] (0) whschultz% g++ globalvar.cpp
globalvar.cpp: In function ‘int main()’:
globalvar.cpp:26: error: reference to ‘count’ is ambiguous
globalvar.cpp:19: error: candidates are: int count
/usr/include/c++/4.2.1/bits/stl_algo.h:424: error: template<class _InputIterator, class _Tp> typename std::iterator_traits::difference_type std::count(_InputIterator, _InputIterator, const _Tp&)
globalvar.cpp:26: error: reference to ‘count’ is ambiguous
globalvar.cpp:19: error: candidates are: int count
/usr/include/c++/4.2.1/bits/stl_algo.h:424: error: template<class _InputIterator, class _Tp> typename std::iterator_traits::difference_type std::count(_InputIterator, _InputIterator, const _Tp&)
globalvar.cpp: In function ‘void func1()’:
globalvar.cpp:35: error: reference to ‘count’ is ambiguous
globalvar.cpp:19: error: candidates are: int count
/usr/include/c++/4.2.1/bits/stl_algo.h:424: error: template<class _InputIterator, class _Tp> typename std::iterator_traits::difference_type std::count(_InputIterator, _InputIterator, const _Tp&)
globalvar.cpp:35: error: reference to ‘count’ is ambiguous
globalvar.cpp:19: error: candidates are: int count
/usr/include/c++/4.2.1/bits/stl_algo.h:424: error: template<class _InputIterator, class _Tp> typename std::iterator_traits::difference_type std::count(_InputIterator, _InputIterator, const _Tp&)
and for reference:
[Blackie:~/Documents] (1) whschultz% g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646) (dot 1)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Anyway, this is a perfect example for why global variables tend to be considered a Bad Thing™. You try to reference it as "count," but that has already been used. Try something less arbitrary, like "counting_sheep."
EDIT: I got the same error as you using "g++-4.0".
EDIT2: Changing the name of "count" to "counting_sheep" worked for me, and I got this:
[Blackie:~/Documents/test] (0) whschultz% ./a.out
counting_sheep: 0
...counting_sheep: 2
...counting_sheep: 4
...counting_sheep: 6
...counting_sheep: 8
...counting_sheep: 10
...counting_sheep: 12
...counting_sheep: 14
...counting_sheep: 16
...counting_sheep: 18
mac2x
Feb 21, 2010, 11:14 AM
Thanks! Seems my version of g++ is a bit out of date:
$ g++ -v
Using built-in specs.
Target: i686-apple-darwin9
Configured with: /var/tmp/gcc/gcc-5493~1/src/configure --disable-checking -enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.0/ --with-gxx-include-dir=/include/c++/4.0.0 --with-slibdir=/usr/lib --build=i686-apple-darwin9 --with-arch=apple --with-tune=generic --host=i686-apple-darwin9 --target=i686-apple-darwin9
Thread model: posix
gcc version 4.0.1 (Apple Inc. build 5493)
However, I will be upgrading my MBP (which the computer I primarily use for this) to Snow Leopard this summer, and that will mean Xcode 3.2 which I assume will have newer compilers. Perhaps there's also an option for verbose output...wait, you didn't use the -o option, so maybe that's it!
I will make recommended adjustments to see what happens. Thanks for compiling it for me to get a better error message. :)
mac2x
Feb 21, 2010, 12:11 PM
By changing "count" to "counting_sheep" I got the same result you did, with no errors.
Detrius
Feb 21, 2010, 11:55 PM
Just because GCC 4.0 is your default doesn't mean you can't use GCC 4.2. It's been part of the developer tools since at least 10.5 (maybe 10.4?). I thought there was a "gcc-select" tool to change the default, but I'm not seeing it in 10.6. Regardless, you can still use "gcc-4.2" at the command line.
mac2x
Feb 22, 2010, 01:44 AM
Just because GCC 4.0 is your default doesn't mean you can't use GCC 4.2. It's been part of the developer tools since at least 10.5 (maybe 10.4?). I thought there was a "gcc-select" tool to change the default, but I'm not seeing it in 10.6. Regardless, you can still use "gcc-4.2" at the command line.
Thanks for the hint! :)
mac2x
Jul 25, 2010, 03:12 PM
Hey guys!!! No, I haven't dropped off the face of the earth. :D
I was wondering, since this thread is a bit old now, what you guys thought was the best book for C++ out there? I have an old book as I stated above, but it's hopelessly out of date. :(
Thanks!
Acorn
Jul 25, 2010, 03:25 PM
If you seriously feel that printing out the contents of a single variable, along with the fact that it takes 1 byte in memory, is fun... then you have a bright future ahead in programming.
I'm serious.
I've seen so many times that beginners think they'll start off with writing a simple 3D first person shooter ("a simple one, without network playing and all that") and then be seriously desillusioned after the first few days.
But let's be clear about it: if you consider what a huge amount of stuff is going on inside your computer when you run that simple first program, it's mind boggling. And fun!
I agree with this. Its really bad. I wont say which forum but a popular gaming forum there are people who have used c++ for less then 3 months asking for help for a mmorpg. not even a regular rpg. but a mmorpg lol.
If a single person would ever attempt a mmorpg is tells exactly how much they dont know.
mac2x
Aug 31, 2010, 02:31 PM
I'm pleased to say that I'm taking a class in C this fall. I hope that I will take a lot away from it; I really like the instructor, who has 30+ years of experience as a programmer.
Also, I got me a nice load of up-to-date books on C and C++ (as well as shell scripting), as well as some of the O'Reilly pocket references.
mac2x
Sep 3, 2010, 04:40 PM
Oh, and rest assured I won't be asking for help with homework under the guise of being a total noob. :D
vBulletin® v3.8.6, Copyright ©2000-2012, Jelsoft Enterprises Ltd.