Teaching Myself C++ and getting stuck with a few syntax problems

C

Cliff

Greetings,

I have been trying to teach myself C++ over the past few weeks and
have finally came across a problem I could not fix. I made a simple
program that prints out a square or rectangle using the * character.
The program was just for practice but I am having problems.

My main problem is, in my program I use 4 functions to change or
access two variables in my code. The variables are

itsHeight;
itsWidth;

The functions are
getHeight(), getWidth()
and
setHeight(), setWidth()

Now for some reason the value that gets stored in itsHeight and
itsWidth goes haywire and saves an astronomically huge number. It
makes my square huge to where you cant see it on a screen and takes a
long time to print. If I move the two variables outside of the class
and make them global, they work like normal. I know I must be doing
something wrong.

I am also having problems creating prototypes of my functions. I could
not create a prototype of my functions that needed to access my
Rectangle class. I was forced to define all the functions above the
Main and then define an object for each one. I was sure there was a
way to use prototypes so you could define your function later, but
somehow force the function to recognize my class ahead of time. Does
this make sense? Right now only my menu function has a prototype. I
know defining a function before main is perfectly fine and that making
a prototype makes no difference but for the sake of learning, and the
sake of organization any help would rock!

The programs not done and there might be a few things in here that I
am not using at the very moment. That stuff should be commented out. I
also have not defined my variables very well between INT, Unsigneds,
longs and shorts. This is because I had it all nice and neatly
organized to what I think I would need for each function, but then
when I hit this brick wall I started changing them to INT to see if it
would make a difference. I will go back and make the appropriate
changes when I know what im doing wrong. Please lend advise to a newb!



#include <iostream>
using namespace std;

//Define Variable types
typedef unsigned short int USI;
typedef unsigned long int ULI;
enum BOOL {FALSE, TRUE};
enum uchoose {print=1, area, perimeter, resize, salir};

//declare rectangle class
class Rectangle {
private: //Private Class Variables
int itsWidth;
int itsHeight;

public: //Public Variables and Functions
ULI printArea(){return itsHeight*itsWidth;}
ULI printPerimeter(){return itsHeight*2+itsWidth*2;}
int getHeight() const {return itsHeight;}
int getWidth() const {return itsWidth;}
int setHeight(int);
int setWidth(int);
};

int Rectangle::setHeight(int h) {
itsHeight=h;
}

int Rectangle::setWidth(int w) {
itsWidth=w;
}

void getMenu();

int printRect() {
Rectangle rect;
int h=rect.getHeight(),w=rect.getWidth();
for (USI x=0; x<h; x++) {
for (USI y=0; y<w; y++) {
cout << "*";
}
cout << endl;
}

}

void setSize() {
Rectangle rect;
int h,w;
cout << "\nInput the Height: ";
cin >> h;
rect.setHeight(h);
cout << "\nInput the Width: ";
cin >> w;
rect.setWidth(w);
}

void Area() {
Rectangle rect;
cout << rect.printArea();
}

void Perimeter() {
Rectangle rect;
cout << rect.printPerimeter();
}

int main() {
Rectangle rect;
USI choice;
BOOL x=FALSE;
while (!x) {
getMenu();
cin >> choice;
switch (choice)
{
case 1:
printRect();
break;
case 2:
Area();
break;
case 3:
Perimeter();
break;
case 4:
setSize();
break;
case 5:
x=TRUE;
break;
}
cout << endl;
}
}

void getMenu() {
cout << "Print the Rectangle\t(1)\n";
cout << "View the Area\t\t(2)\n";
cout << "View the Perimeter\t(3)\n";
cout << "Resize\t\t\t(4)\n";
cout << "Exit\t\t\t(5)\n";
}
 
G

Gernot Frisch

class Rectangle {

public:

// You want a constructor:
Rectangle()
{
itsWidth= 0;
itsHeight=0;
}
};
 
T

Thes

class Rectangle {

public:

// You want a constructor:
Rectangle()
{
itsWidth= 0;
itsHeight=0;



}
};- Hide quoted text -

- Show quoted text -

Or use an initialisation list.

The bigger problem in the code is that Cliff creates a Rectangle
object in his main() loop, but doesn't pass it to his various
functions, instead he creates temporary objects in the functions.
These temporaries obviously bear no relation to that in the main loop.

So, to fix the problem, Cliff, pass your Rectangle object by reference
to your functions. For example,
void printRect(Rectangle& rect); etc.

To clear up your problems with prototyping, perhaps now is a good time
to learn about header files.

HTH.
Thes.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Greetings,

I have been trying to teach myself C++ over the past few weeks and
have finally came across a problem I could not fix. I made a simple
program that prints out a square or rectangle using the * character.
The program was just for practice but I am having problems.

My main problem is, in my program I use 4 functions to change or
access two variables in my code. The variables are

itsHeight;
itsWidth;

The functions are
getHeight(), getWidth()
and
setHeight(), setWidth()

Now for some reason the value that gets stored in itsHeight and
itsWidth goes haywire and saves an astronomically huge number. It
makes my square huge to where you cant see it on a screen and takes a
long time to print. If I move the two variables outside of the class
and make them global, they work like normal. I know I must be doing
something wrong.

I am also having problems creating prototypes of my functions. I could
not create a prototype of my functions that needed to access my
Rectangle class. I was forced to define all the functions above the
Main and then define an object for each one. I was sure there was a
way to use prototypes so you could define your function later, but
somehow force the function to recognize my class ahead of time. Does
this make sense? Right now only my menu function has a prototype. I
know defining a function before main is perfectly fine and that making
a prototype makes no difference but for the sake of learning, and the
sake of organization any help would rock!

The programs not done and there might be a few things in here that I
am not using at the very moment. That stuff should be commented out. I
also have not defined my variables very well between INT, Unsigneds,
longs and shorts. This is because I had it all nice and neatly
organized to what I think I would need for each function, but then
when I hit this brick wall I started changing them to INT to see if it
would make a difference. I will go back and make the appropriate
changes when I know what im doing wrong. Please lend advise to a newb!



#include <iostream>
using namespace std;

//Define Variable types
typedef unsigned short int USI;
typedef unsigned long int ULI;

Just a tip, for most practical intents and purposes a normal int will do
just fine, or unsigned int if the values are all positive (for values
indicating size I usually use the type size_t which is an unsigned
integer). While it at first might seem like a good idea to use short for
values that will never be large the truth is that on some machines it
takes more time working with a short (since it's not the natural size)
and any space savings can be eaten up by padding. So a good tip is to
not use other types unless you have a good reason. The same is true for
double vs float, double is usually preferable.
enum BOOL {FALSE, TRUE};

No, no no. In C++ we have this wonderful type called bool specially
designed for this.
enum uchoose {print=1, area, perimeter, resize, salir};

You don't use this one.
//declare rectangle class
class Rectangle {
private: //Private Class Variables
int itsWidth;
int itsHeight;

public: //Public Variables and Functions

You probably want to add a constructor which initializes the value when
you create a new rectangle:

Rectangle() : itsWidth(0), itsHeight(0) { }

That's an initialization list, it does the same thing as

itsWidth = 0;
itsHeight = 0;

but is more efficient. It might also be convenient to be able to tell
the size of the rectangle when it's created, so lets add a constructor
for that also.

Rectangle(int w, int h) : itsWidth(w), itsHeight(h) { }

It is possible to combine these two constructors into one using default
parameters, but I leave that as homework for you to look into.
ULI printArea(){return itsHeight*itsWidth;}
ULI printPerimeter(){return itsHeight*2+itsWidth*2;}
int getHeight() const {return itsHeight;}
int getWidth() const {return itsWidth;}
int setHeight(int);
int setWidth(int);
};

int Rectangle::setHeight(int h) {
itsHeight=h;
}

int Rectangle::setWidth(int w) {
itsWidth=w;
}

Out of curiosity, is there some special reason that you chose to define
those two methods outside of the class declaration? Not that it's wrong,
either way works.
void getMenu();

int printRect() {
Rectangle rect;

As Thes said, your problem is that you create a new rectangle in the
function (and since you didn't initialize the values you got weird
results) instead of passing the rectangle to print as an argument to the
function. So rewrite the above two lines to

void printRect(const Rectangle& rect) {

Three things to notice: the first is that since the method does not
return any value I changed the return type to void.
The second thing is the & after Rectangle, this means that the rectangle
is passed as a reference this means that any changes you make in this
function will affect the rectangle you supplies as argument to the
function. If you omit the & you will pass by value, which means that any
changes you make in this function will be made on a copy (which will be
discarded at the end of the function) of the argument, and will not
affect the rectangle passed as argument.
The last thing is the word const, since we pass by reference you could
change the argument, but since we will only print the rectangle we add
the word const which means that 'rect' will be constant (not changeable)
in this function, and the compiler will complain if you try to modify it.
int h=rect.getHeight(),w=rect.getWidth();
for (USI x=0; x<h; x++) {
for (USI y=0; y<w; y++) {
cout << "*";
}
cout << endl;
}

}

void setSize() {
Rectangle rect;

Once again, you can replace these two lines, but since we do change the
rectangle in this function you must skip the const. I'm sure you by now
can figure out the last two.
int h,w;
cout << "\nInput the Height: ";
cin >> h;
rect.setHeight(h);
cout << "\nInput the Width: ";
cin >> w;
rect.setWidth(w);
}

void Area() {
Rectangle rect;
cout << rect.printArea();
}

void Perimeter() {
Rectangle rect;
cout << rect.printPerimeter();
}

int main() {
Rectangle rect;

If you want to set some specific size use the constructor like so:

Rectangle rect(10, 10); // A 10 by 10 rectangle
USI choice;
BOOL x=FALSE;

Here I would go
size_t choice;
bool x = false;

While the usage of size_t is mostly a matter of style and opinion you
really should be using the built-in type bool for x.
while (!x) {
getMenu();
cin >> choice;
switch (choice)
{
case 1:
printRect();

Since we have a Rectangle object and have modified our functions we can
now use them by passing that object to the functions:

printRect(rect);
 
C

Cliff

Thanks for the help guys! I cant beleive the amount of help I got. I
might have to stop in from time to time for more guidance. I probably
do alot of things that wouldnt be conciderd "good programming". It's
hard when your teaching yourself but I find this to be a fun past time
and a fun hobby.

Again thanks for the help I'll post again if I hit another roadblock!

Cliff
 
C

Cliff

Thanks for the help guys! I cant beleive the amount of help I got. I
might have to stop in from time to time for more guidance. I probably
do alot of things that wouldnt be conciderd "good programming". It's
hard when your teaching yourself but I find this to be a fun past time
and a fun hobby.

Again thanks for the help I'll post again if I hit another roadblock!

Cliff


























- Show quoted text -

Based on your guyses advise here is what I have

#include <iostream>
using namespace std;

//Define Variable types
typedef unsigned int UI;
enum uchoose {print=1, area, perimeter, resize, salir};

//declare rectangle class
class Rectangle {
private:
UI itsWidth;
UI itsHeight;

public: //Public Variables and Functions
Rectangle(UI h, UI w);
~Rectangle();
UI printArea(){return itsHeight*itsWidth;}
UI printPerimeter(){return itsHeight*2+itsWidth*2;}
int setHeight(int h) {itsHeight=h;}
int setWidth(int w) {itsWidth=w;}
int getHeight() const {return itsHeight;}
int getWidth() const {return itsWidth;}
};

Rectangle::Rectangle(UI height, UI width){
itsHeight=height;
itsWidth=width;
}

Rectangle::~Rectangle() {}

void getMenu();
void printRect(Rectangle);
void Area(Rectangle);
void Perimeter(Rectangle);
void setSize(Rectangle);

int main() {
bool x=false;
Rectangle rect(2,2);
UI choice;
while (!x) {
getMenu();
cin >> choice;
switch (choice)
{
case print:
printRect(rect);
break;
case area:
Area(rect);
break;
case perimeter:
Perimeter(rect);
break;
case resize:
setSize(rect);
break;
case salir:
x=true;
break;
}
cout << endl;
}
}

void getMenu() {
cout << "Print the Rectangle\t(1)\n";
cout << "View the Area\t\t(2)\n";
cout << "View the Perimeter\t(3)\n";
cout << "Resize\t\t\t(4)\n";
cout << "Exit\t\t\t(5)\n";
}

void printRect(Rectangle rect) {
int h=rect.getHeight(),w=rect.getWidth();
for (UI x=0; x<h; x++) {
for (UI y=0; y<w; y++) {
cout << "*";
}
cout << endl;
}
}

void Area(Rectangle rect) {
cout << rect.printArea();
}

void Perimeter(Rectangle rect) {
cout << rect.printPerimeter();
}

void setSize(Rectangle rect){
int h,w;
cout << "\nInput the Height: ";
cin >> h;
cout << "\nInput the Width: ";
cin >> w;
rect.setHeight(h);
rect.setWidth(w);
}


I still am having problems with the output of hte square but a least I
learned how to pass a referance of a class through the variables. When
I get home I look closer to how I pass my values through the
variables. I need to get more information on how making certain things
a "const" benefits your program. Any how its all learning.

Thanks for the help guys!
 
J

John Harrison

void setSize(Rectangle rect){
int h,w;
cout << "\nInput the Height: ";
cin >> h;
cout << "\nInput the Width: ";
cin >> w;
rect.setHeight(h);
rect.setWidth(w);
}


I still am having problems with the output of hte square but a least I
learned how to pass a referance of a class through the variables. When
I get home I look closer to how I pass my values through the
variables. I need to get more information on how making certain things
a "const" benefits your program. Any how its all learning.

Thanks for the help guys!

setSize is wrong. The rect parameter is a *copy* of the rectangle you
created in main. You change the size of the copy, but the original in
main is untouched. You must pass the parameter by reference

void setSize(Rectangle& rect){ // the & is really important

Now setSize will change the size of the rectangle passed to it, not to a
copy of the rectangle.

john
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Thanks for the help guys! I cant beleive the amount of help I got. I
might have to stop in from time to time for more guidance. I probably
do alot of things that wouldnt be conciderd "good programming". It's
hard when your teaching yourself but I find this to be a fun past time
and a fun hobby.

Again thanks for the help I'll post again if I hit another roadblock!

If you do post again, take care to avoid top-post, it is generally
frowned upon. You can also take some time to read through section 5 of
the FAQ: http://www.parashift.com/c++-faq-lite/how-to-post.html

Also, a good way of learning is by using a good book. Many here will
recommend Accelerated C++ by Koenig and Moo, which will teach you "good
C++" from the start.
 
C

Cliff

If you do post again, take care to avoid top-post, it is generally
frowned upon. You can also take some time to read through section 5 of
the FAQ:http://www.parashift.com/c++-faq-lite/how-to-post.html

Also, a good way of learning is by using a good book. Many here will
recommend Accelerated C++ by Koenig and Moo, which will teach you "good
C++" from the start.

ahh ok gotcha, will post on the bottom for now. Ill go read the faq
now.

Yea I realise teaching myself is probably not the best way to go about
this. I have found many useful resources on lines and small books
through torrents and what not. My problem is I am a Peace Corp
Volunteer in Honduras and all the books here are in spanish, what few
books there are... I could get one shipped to me but it is very
expensive.

Any how I got the program to work, I had to use the referance symnol &
when passing the rectangle class through the functions to make sure I
was using the same copy of a rectangle I guess.

Thanks
 
J

Jim Langston

Thanks for the help guys! I cant beleive the amount of help I got. I
might have to stop in from time to time for more guidance. I probably
do alot of things that wouldnt be conciderd "good programming". It's
hard when your teaching yourself but I find this to be a fun past time
and a fun hobby.

Again thanks for the help I'll post again if I hit another roadblock!
[SNIP old code]

Based on your guyses advise here is what I have

#include <iostream>
using namespace std;

//Define Variable types
typedef unsigned int UI;
enum uchoose {print=1, area, perimeter, resize, salir};

//declare rectangle class
class Rectangle {
private:
UI itsWidth;
UI itsHeight;

public: //Public Variables and Functions
Rectangle(UI h, UI w);
~Rectangle();
UI printArea(){return itsHeight*itsWidth;}
UI printPerimeter(){return itsHeight*2+itsWidth*2;}
int setHeight(int h) {itsHeight=h;}

Personal choice, does the user care if it's set or get? And you aren't
returning a value, so why have a return value of int? In the least make it:
void setHeight( int h) { itsHeight=h; }
but, personally, I would just do:
void Height( int h ) { itsHeight = h; }
int setWidth(int w) {itsWidth=w;}

Same here.
void Width( int w ) { itsWidth = w; }
int getHeight() const {return itsHeight;}

Okay, now we actually do return an int, and it is const. But I would still
rename it (personal choice).
int Height() const { return itsHeight; }
int getWidth() const {return itsWidth;}

Again.
int Width() const { return itsWidth; }
};

Rectangle::Rectangle(UI height, UI width){
itsHeight=height;
itsWidth=width;
}

Rectangle::~Rectangle() {}

void getMenu();
void printRect(Rectangle);
void Area(Rectangle);
void Perimeter(Rectangle);
void setSize(Rectangle);

int main() {
bool x=false;
Rectangle rect(2,2);
UI choice;
while (!x) {
getMenu();
cin >> choice;

If someone enters a letter here instead of a number you'll go into an
endless loop. look at std::cin.ignore()
switch (choice)
{
case print:
printRect(rect);
break;
case area:
Area(rect);
break;
case perimeter:
Perimeter(rect);
break;
case resize:
setSize(rect);
break;
case salir:
x=true;
break;
}
cout << endl;
}
}

void getMenu() {
cout << "Print the Rectangle\t(1)\n";
cout << "View the Area\t\t(2)\n";
cout << "View the Perimeter\t(3)\n";
cout << "Resize\t\t\t(4)\n";
cout << "Exit\t\t\t(5)\n";
}

void printRect(Rectangle rect) {

You are passing a copy of the Rectangle here. Since you're not chaning it,
that's okay, but then it's not const correct either. A const reference
would be better, however, so you wouldn't have to waste time copying.

void printRect( const Rectangle& rect ) {
int h=rect.getHeight(),w=rect.getWidth();

Personal choice. I'll only put one assignment on it's own line so I would
make this:
int h = rect.Height();
int w = rect.Width();
( remember I would change the method names).
for (UI x=0; x<h; x++) {
for (UI y=0; y<w; y++) {
cout << "*";
}
cout << endl;
}
}

void Area(Rectangle rect) {

Again.
void Area( const Rectangle& rect ) {
cout << rect.printArea();
}

void Perimeter(Rectangle rect) {

void Perimeter( const Rectangle& rect ) {
cout << rect.printPerimeter();
}

void setSize(Rectangle rect){

Problem. You are passing the Rectangle by value, that is, a copy. This
makes a local copy of Rectangle that will only be visible in this method.
So here we absolutely need a reference, but this time we are going to change
it, so do not make it const.

void setSize( Rectangle& rect ) {
int h,w;
cout << "\nInput the Height: ";
cin >> h;
cout << "\nInput the Width: ";
cin >> w;

Enter a character for h and you get garbage for height and width. Enter a
character for width, you get garbage for width. In the least, initialize h
and w to something (such as 0) so at least a known value will be entered.
At most, check for error conditions and look at std::cin.ignore();
rect.setHeight(h);

Since I would of renamed the methods, I would simply do:
rect.Height( h );
rect.setWidth(w);

Again, personal choice.
rect.Width( w );
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top