Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

mac2x

macrumors 65816
Original poster
Sep 19, 2009
1,146
0
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:

Code:
#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:

Code:
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! :)
 
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
 
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... :eek:

Code:
/*
 *  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;
	
}
 
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"?

Code:
program2.cpp: In function ‘int main(int, char**)’:
program2.cpp:16: error: ‘end1’ was not declared in this scope
 
OK, I got rid of the second error because I had mistakenly placed a "z" instead of myCharacter. So "end1" should be "endl"?

Code:
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
 
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...
 
Changing to 'endl' fixed the problem; it compiled and produced this output:

Code:
The datatype is 4 bytes! 
The variable has a value of z

Implementing Cromulent's suggestion reduced the size to 1 byte:

Code:
The datatype is 1 bytes! 
The variable has a value of z
 
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
 
Thanks, Lee. I'll think about that. I know I still have a lot to learn, but this is so much fun! :)
 
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!
 
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! :)
 
OK, I fixed all the problems.

Code:
/*
 *  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:

Code:
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:
 
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.
 
Thanks again! That worked as expected. :cool:


Code:
/*
 *  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;
	
}

Code:
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.
 
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!
 
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.

Code:
/*
 *  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:

Code:
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:
 
Code:
int x = 1, y = 3, z = 4;

Declares three ints. x, y and z with the values 1, 3 and 4 respectively.

Code:
int *num;

Declares a pointer to int with an undefined value.

Code:
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).

Code:
z*=y;

Just a short hand for:

Code:
z = z * y;

Code:
y = x + (int)pi;

x + the value of pi as an int (which is 3). This is called casting.

Code:
num = &y;

Make num point to the address of y.

Code:
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:

Code:
cout << "Z: " << z << endl;
cout << "Y: " << y << endl;

Print the values of z and y to the standard output.

Code:
cout << "The base memory address of Y: " << num << end

Print the address of y by printing the value of num (which is a pointer).

Code:
cout << "The value pointed to by num: " << *num << endl;

Print the value stored in the address pointed to by num via indirection.
 
<snip>
Code:
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:
Code:
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.
 
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.
 
Thanks, guys. More good study material for when I sit down in a few minutes to work on programming. :D
 
[...]
So this code could be:
Code:
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.

Code:
/*
 *  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;
		
}

Code:
Z: 1 <= Y: 3
Z: 1
Y: 3
The base memory address of Y: 0xbffffa9c
The value pointed to by num: 3
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.