Username [Register?]: | Password [Lost Password?]: Save Password?
Bottom of Page
INTL v5.0 > Site Comments > Archives > Archived Forums > Linux Corner: computers for something other than windows? WHAT > C Programming MEGA THREAD > Viewing Thread
Also Here: 1 guest.
Page: [ 1 2 ] [ Thread Views: 4285 | Total Posts: 42 ]
Rate This Thread: Reply to Thread | Create New Thread | Create New Poll | Convert To Poll | Subscribe To Thread
atlas sighed (at me)
User is currently banned until further notice.

(Originally posted on: 12-05-10 06:32:52 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Alright, seeing how active this place is..I have a few question about C for anyone who knows:

Trying to figure out a goto program but not getting anywhere:

Code:
main()
{
int dog,cat,pig;
goto real_start;
some_where:
printf("This is another line of the mess.\\n");
goto stop_it;
/* the following section is the only section with a useable goto */
real_start:
for(dog = 1;dog < 6;dog++) {
for(cat = 1;cat < 6;cat++) {
for(pig = 1;pig < 4;pig++) {
printf("Dog = %d Cat = %d Pig = %d\\n",dog,cat,pig);
if ((dog + cat + pig) > 8 ) goto enough;
};
};
};
enough: printf("Those are enough animals for now.\\n");
/* this is the end of the section with a useable goto statement*/
printf("\\nThis is the first line out of the spaghetti code.\\n");
goto there;
where:
printf("This is the third line of the spaghetti code.\\n");
goto some_where;
there:
printf("this is the second line of the spaghetti code.\\n");
goto where;
stop_it:
printf("This is the last line of the mess.\\n");
}



Output:
Dog = 1 Cat = 1 Pig = 1
Dog = 1 Cat = 1 Pig = 2
Dog = 1 Cat = 1 Pig = 3
Dog = 1 Cat = 2 Pig = 1
Dog = 1 Cat = 2 Pig = 2
Dog = 1 Cat = 2 Pig = 3
Dog = 1 Cat = 3 Pig = 1
Dog = 1 Cat = 3 Pig = 2
Dog = 1 Cat = 3 Pig = 3
Dog = 1 Cat = 4 Pig = 1
Dog = 1 Cat = 4 Pig = 2
Dog = 1 Cat = 4 Pig = 3
Dog = 1 Cat = 5 Pig = 1
Dog = 1 Cat = 5 Pig = 2
Dog = 1 Cat = 5 Pig = 3
Those are enough animals for now.

This is the first line out of the spaghetti code.
this is the second line of the spaghetti code.
This is the third line of the spaghetti code.
This is another line of the mess.
This is the last line of the mess.

What I don't get is why doesn't it add "Dog" by one with each line?
A witty saying proves nothing - Voltaire
This reply was last edited on 12-05-10 06:45:43 PM by atlas sighed (at me).
INTL Janitorial Services
Administrator

honestly i probably have Crohn's disease and should see a doctor

Ballkicks: (+360 / -80)
Posts: 1783 (0.263)
Reg. Date: Dec 2001
Location: My Pants
Gender: Female
Reply 1 of 42 (Originally posted on: 12-05-10 06:54:03 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Code:
// First of all, main() should always return
// something, or it should be set to void.
// Straight up "main()" will make most
// compilers barf.
void main()
{
// Looks like just lining out our variables
// These really should be set to some initial
// value unless you're ABSOLUTELY SURE
// that the code will "fill them in" before they're
// used for something
int dog,cat,pig;

// Gotos are dangerous in the sense that your code
// will very quickly become a huge unreadable mess.
// If you need to jump somewhere else in your code,
// either use a break inside a loop or design
// a function do to what you want.
goto real_start;

some_where:
printf("This is another line of the mess.\\n");
goto stop_it;

/* the following section is the only section with a useable goto */
real_start:
for(dog = 1;dog < 6;dog++)
{
for(cat = 1;cat < 6;cat++)
{
for(pig = 1;pig < 4;pig++)
{
printf("Dog = %d Cat = %d Pig = %d\\n",dog,cat,pig);

// Here is the answer to your question. The program
// never gets a chance to add anything to "dog",
// because it has to do this:
// pig + 1
// until pig is >= 4.
// So pig = 4
// Then it starts the next loop up
// cat + 1
// until cat is >= 6
// Then cat = 6
// 4 + 6 > 8
// Loop break
// Dog is never increased.
if ((dog + cat + pig) > 8 ) goto enough;
};
};
};

enough: printf("Those are enough animals for now.\\n");
/* this is the end of the section with a useable goto statement*/
printf("\\nThis is the first line out of the spaghetti code.\\n");

goto there;

where:
printf("This is the third line of the spaghetti code.\\n");

goto some_where;

there:
printf("this is the second line of the spaghetti code.\\n");

goto where;

stop_it:
printf("This is the last line of the mess.\\n");
}



If you're serious about learning C I would recommend not starting with a goto program unless you're just learning how to properly format code (tabs, quotes, brackets). Gotos suck hard and I have never seen then used anywhere in any real application.

C programming is also a bit boring unless you've got an idea in your head of something cool that you'd like to make. Look into the Nerdkit or Arduino microcontroller kits so you can write a program that flashes LEDs.
FUCK. YOU. VISSARIO.
Air Bud
Internet Superstar

Some plants even masturbate into their own vaginas in order to reproduce.

Ballkicks: (+918 / -56)
Posts: 6785 (0.987)
Reg. Date: Sep 2001
Location: TEH INTARNET!
Gender: Male
Reply 2 of 42 (Originally posted on: 12-05-10 06:54:21 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

There are three nested loops, and the "dog" variable is the iterator for the outer most loop. Since it exits out of the nested loops once dog+cat+pig is greater than 8 (by executing goto enough), it won't iterate dog whatsoever.
Air Bud
Internet Superstar

Some plants even masturbate into their own vaginas in order to reproduce.

Ballkicks: (+918 / -56)
Posts: 6785 (0.987)
Reg. Date: Sep 2001
Location: TEH INTARNET!
Gender: Male
Reply 3 of 42 (Originally posted on: 12-05-10 06:56:24 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Also, goto is the worst fucking shit ever. Never use goto. It's no longer 1965, so goto is not necessary.
C
Administrator

Level 90 Ginger

Ballkicks: (+723 / -204)
Posts: 6647 (1.01)
Reg. Date: Jun 2002
Location: Missouri
Gender: Male
Reply 4 of 42 (Originally posted on: 12-06-10 04:42:04 AM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Quoted from Sandamnit:
Also, goto is the worst fucking shit ever. Never use goto. It's no longer 1965, so goto is not necessary.

Came here pretty much only to say this.
"Remember, Jesus would rather constantly shame the gays than let orphans have families."
Trash Mod
Administrator
I wish I were dead.

i'm nick and i'm too stupid to read so i make unnecessary posts

Ballkicks: (+574 / -34)
Posts: 4454 (0.776)
Reg. Date: Oct 2004
Location: Trash
Gender: Male
Reply 5 of 42 (Originally posted on: 12-06-10 11:20:36 AM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

use functions you dumbass...

oh beaten by three people.

I love c btw because I hate bloat and you can compile c programs to be super tiny.
atlas sighed (at me)
User is currently banned until further notice.

Reply 6 of 42 (Originally posted on: 12-06-10 11:47:30 AM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

More cannon fodder:
int x = 11, z = 11
float r = 0.0
float s = 12.987

if (x = (r != s)) z = 1000; /*This will set x = some positive number and z = 1000 */

Now, for the "(r != s)" snippet, is it attempting to say that since 0 not equaling 12.987 is true (1), x will therefore be true (1) and z will in turn be 1000?

If I have this right, would (x = (r == s)) z = 1000 result in this?
x = 0
z = no change
A witty saying proves nothing - Voltaire
This reply was last edited on 12-06-10 11:53:04 AM by atlas sighed (at me).
Trash Mod
Administrator
I wish I were dead.

i'm nick and i'm too stupid to read so i make unnecessary posts

Ballkicks: (+574 / -34)
Posts: 4454 (0.776)
Reg. Date: Oct 2004
Location: Trash
Gender: Male
Reply 7 of 42 (Originally posted on: 12-06-10 01:04:29 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

(r != s) will evaluate to true. So it will set x to true. Since x is true, it will then evaluate z=1000.

In the end, the variables should be:

x=True (>0)
z=1000
r = 0.0
s = 12/987

----------------------------------
To tear you apart a little (since I hate being nice):

You should probably break up the evaluational part of the "if" statement from the result. Mostly because it's easier to read when you get large "then" blocks like this:

if (something)
{
lots of cool;
programmer;
shit;
happens;
here;
}

which are easier to read.
This reply was last edited on 12-06-10 01:11:16 PM by Trash Mod.
atlas sighed (at me)
User is currently banned until further notice.

Reply 8 of 42 (Originally posted on: 12-06-10 02:57:22 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Okay, so I thought this program would be easy but I am up against and error I have never seen before:

Code:
void main()
{
int count;
float inversion;
for(count = 0; count < 13; count = count + 1)
{
inversion = 1/count;
printf("%d %f\\n",count,inversion);
}
}



Output from terminal:

laptop:~/Documents/C/grams$ ./inversion
Floating point exception

any advice? I put %f explicitly for the decimal number!

edit: ignore that extra '\' in the text, it the tags added it in there for some reason
A witty saying proves nothing - Voltaire
This reply was last edited on 12-06-10 03:03:01 PM by atlas sighed (at me).
Trash Mod
Administrator
I wish I were dead.

i'm nick and i'm too stupid to read so i make unnecessary posts

Ballkicks: (+574 / -34)
Posts: 4454 (0.776)
Reg. Date: Oct 2004
Location: Trash
Gender: Male
Reply 9 of 42 (Originally posted on: 12-06-10 03:09:07 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

You're dividing by 0.

You set count = 0 for the first iteration of the loop and then the first statement is: inversion = 1 / count.
atlas sighed (at me)
User is currently banned until further notice.

Reply 10 of 42 (Originally posted on: 12-06-10 03:31:01 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Resolved that issue, but the program still doesn't work as intended:

Code:
void main()
{
int count;
float inversion;
for(count = 1; count < 13; count = count + 1)
{
inversion = 1/count;
printf("%d %f\\n",count,inversion);
}
}



output:

laptop:~/Documents/C/grams$ ./inversion
1 1.000000
2 0.000000
3 0.000000
4 0.000000
5 0.000000
6 0.000000
7 0.000000
8 0.000000
9 0.000000
10 0.000000
11 0.000000
12 0.000000

This has me stumped. The count works just fine; it gets all the way up to 12 like it should. The count used to define the variable inversion should also register the increments but, for some reason, it drops down to 0 for every interval other than 1.
A witty saying proves nothing - Voltaire
Trash Mod
Administrator
I wish I were dead.

i'm nick and i'm too stupid to read so i make unnecessary posts

Ballkicks: (+574 / -34)
Posts: 4454 (0.776)
Reg. Date: Oct 2004
Location: Trash
Gender: Male
Reply 11 of 42 (Originally posted on: 12-06-10 04:13:41 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Try casting count as a float for the calculation.

inversion = 1 / (float)count;

TBH I don't do a lot of math programming so I pretty much only use integers and strings.
atlas sighed (at me)
User is currently banned until further notice.

Reply 12 of 42 (Originally posted on: 12-06-10 04:22:12 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Wow, that was brilliant, it worked! Kudos..questions though..

using (float)count..did that change count from an integer to a float?

edit: also, sweet victory!

~/Documents/C/grams$ ./inversion
1 1.000000
2 0.500000
3 0.333333
4 0.250000
5 0.200000
6 0.166667
7 0.142857
8 0.125000
9 0.111111
10 0.100000
11 0.090909
12 0.083333
A witty saying proves nothing - Voltaire
Trash Mod
Administrator
I wish I were dead.

i'm nick and i'm too stupid to read so i make unnecessary posts

Ballkicks: (+574 / -34)
Posts: 4454 (0.776)
Reg. Date: Oct 2004
Location: Trash
Gender: Male
Reply 13 of 42 (Originally posted on: 12-06-10 09:46:51 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Only for that calculation. It doesn't permanently change the variable.

I'm waiting for you to try and tackle pointers.
Air Bud
Internet Superstar

Some plants even masturbate into their own vaginas in order to reproduce.

Ballkicks: (+918 / -56)
Posts: 6785 (0.987)
Reg. Date: Sep 2001
Location: TEH INTARNET!
Gender: Male
Reply 14 of 42 (Originally posted on: 12-06-10 10:59:30 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Ah, pointers. You're gonna love'em!


I suggest picking up K&R if you want to learn C. Read it. Do the exercises.
Air Bud
Internet Superstar

Some plants even masturbate into their own vaginas in order to reproduce.

Ballkicks: (+918 / -56)
Posts: 6785 (0.987)
Reg. Date: Sep 2001
Location: TEH INTARNET!
Gender: Male
Reply 15 of 42 (Originally posted on: 12-06-10 11:12:29 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Quoted from oirassiv:
questions though..

using (float)count..did that change count from an integer to a float?
The term you're looking for is "casting" (if you're gonna learn how to program, may as well learn the lingo so you can communicate with people properly).

Basically, it works like this.


"count" starts as an integer, which is a specific kind of variable encoding, which takes on, you guessed it, integer values, ..., -2, -1, 0, 1, 2, ... Whenever you write (float)count, the compiler then attempts to cast "count" to a floating-point variable. However, as Nick said, it's only temporary. It only works for that one line of code. However, you could have fixed it another way, by writing the line of code as 1.0/count.

Division is a binary operation, which means that there are two operands, the numerator and the denominator. When you divide two variables by each other, the result will be an integer if and only if both the numerator and denominator are both integers. Furthermore, if the result (according to standard arithmetic) is NOT an integer, for example, 1.2 or 1.75, the compiler will round down, effectively dropping the fractional part. This is why 1/count gave you 1 when count=1 and 0 when count>1, even though "inversion" was declared to be a float. However, if either of the operands are float, the result of division will be a float.

Does this clear things up? Questions?
atlas sighed (at me)
User is currently banned until further notice.

Reply 16 of 42 (Originally posted on: 12-07-10 03:15:07 AM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Yep, that makes senses exactly on why I kept receiving "0.00000" for 1/2 and et cetera. Appreciate it guys, and I'll look into getting K&R too.
A witty saying proves nothing - Voltaire
This reply was last edited on 12-07-10 03:23:44 AM by atlas sighed (at me).
C
Administrator

Level 90 Ginger

Ballkicks: (+723 / -204)
Posts: 6647 (1.01)
Reg. Date: Jun 2002
Location: Missouri
Gender: Male
Reply 17 of 42 (Originally posted on: 12-07-10 06:21:42 AM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Quoted from Sandamnit:
Ah, pointers. You're gonna love'em!


I suggest picking up K&R if you want to learn C. Read it. Do the exercises.

Pointers are what made me decide I never want to be a programmer for a living, so yeah... Maybe it's because I still don't understand the fucking point.
"Remember, Jesus would rather constantly shame the gays than let orphans have families."
atlas sighed (at me)
User is currently banned until further notice.

Reply 18 of 42 (Originally posted on: 12-07-10 06:39:18 AM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Good news; I "acquired" a copy of the book you mentioned Sandamnit.

Code:
main( )				/* This is the main program*/
{
int x,y;
for(x = 0;x < 7;x++)
{
y = squ(x); /* go get the value of x*x */
printf("The square of %d is %d\\n",x,y);
}
for (x = 0;x <= 7;++x)
printf("The value of %d is %d\\n",x,squ(x));
}
squ(in) /* function to get the value of in squared*/
int in;
{
int square;
square = in * in;
return(square); /* This sets squ() = square */
}



Is squ(x) actually a defined variable in and of itself? I initially thought it was a function as defined by squ(in), but I see that it is used in the last for statement as a variable.
A witty saying proves nothing - Voltaire
Air Bud
Internet Superstar

Some plants even masturbate into their own vaginas in order to reproduce.

Ballkicks: (+918 / -56)
Posts: 6785 (0.987)
Reg. Date: Sep 2001
Location: TEH INTARNET!
Gender: Male
Reply 19 of 42 (Originally posted on: 12-07-10 09:40:51 AM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

In this context, "squ" is a subroutine (or function). Functions are not variables, they are, loosely speaking, "code". They take input (or parameters) and may or may not return values.

What you're referring to in the last for-loop's usage of "squ" is not treating "squ" as a variable, but rather using the value of "x" as a parameter to a call to "squ". Once "squ" is done executing, it returns a value equal to x*x, which is then used, as a temporary value, in the printf statement.

K&R is a great book with very practical and reasonable exercises. The important thing is that you don't rush through it, it's not a race. It's more important to understand things as you progress through the book, no matter how trivial they seem. A common problem people have when learning how to program is marginalizing the importance of mastering the little things. While it can be frustrating and a bit insulting to be asked to write simplistic programs, it's incredibly important to remember that the program itself is ultimately irrelevant when you're learning, but rather the techniques you stand to gain in the process that are most important. I see this all the time as a CS major, people are always bitching about an assignment being stupid, while completely neglecting the fact that the assignment is intended to teach you a common and important technique. Instead, they just want to HACK TEH WORLD with every assignment and are dissatisfied when they're asked to sort a list of 20 random integers, but still can't manage to do it.


As far as pointers, they are rough, but extremely useful (and dangerous) when it comes to designing programs that utilize memory in an efficient way. There's a video that one of my CS professors showed us which I always thought was pretty good, although really cheesy (intentionally so) that sheds some light on the subject. Pointers actually begin to make a lot of sense if you take a step back and think about them abstractly, as opposed to the more traditional bang-your-head-against-a-wall technique that a lot of people seem to be accustomed to when it comes to programming.
This reply was last edited on 12-07-10 09:46:50 AM by Air Bud.
Trash Mod
Administrator
I wish I were dead.

i'm nick and i'm too stupid to read so i make unnecessary posts

Ballkicks: (+574 / -34)
Posts: 4454 (0.776)
Reg. Date: Oct 2004
Location: Trash
Gender: Male
Reply 20 of 42 (Originally posted on: 12-07-10 03:33:27 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

If you need a simpler explanation, it evaluates squ(x) first and then it evaluates printf() using the result.

Quote:
Pointers are what made me decide I never want to be a programmer for a living, so yeah... Maybe it's because I still don't understand the fucking point.


There are two primary uses of pointers. IMO, the most powerful use is to create dynamic variables. Basically, any veriable that you either a) don't know the size of ahead of time or b) are so big you don't want them taking up a shit load of memory at program execution.

A decent example might be a word processor document. You don't know how long any given document is going to be so you can't just have your word processor create a string with like ten million bytes or something for every new document it creates. Instead you have an array that starts with one byte and every time something changes, it can allocate more memory on the fly (until there's no memory left or whatever). The only way to access that memory is if you have the address. Since the memory is allocated while the program is executing, the address can change every time the program is executed. Hence, a variable is needed to hold that address.

The other use is to pass arguments to functions that you want to change directly (instead of creating a copy). You can pass the address of the variable instead of the variable itself. This is more of a structural C thing.

One excersize that I reacall doing which really helped me understand pointers was to create a stack program. Basically you create a struct and then several functions for working with it dynamically. You can write functions to push, pop, etc. on the stack (the struct was the variable holding the stack) and then you can play around with it and output the pointer values as well as the values the pointers are pointing to and shit. It was very illustrative.
atlas sighed (at me)
User is currently banned until further notice.

Reply 21 of 42 (Originally posted on: 12-08-10 05:37:38 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Oh boy, recursion, the output mystifies me:

Code:
main( )
{
int index;
index = 8;
count_dn(index);
}
count_dn(count)
int count;
{
count--;
printf("The value of the count is %d\\n",count);
if (count > 0)
count_dn(count);
printf("Now the count is %d\\n",count);
}



Output:

laptop:~/Documents/C/grams$ ./recursion
The value of the count is 7
The value of the count is 6
The value of the count is 5
The value of the count is 4
The value of the count is 3
The value of the count is 2
The value of the count is 1
The value of the count is 0
Now the count is 0
Now the count is 1
Now the count is 2
Now the count is 3
Now the count is 4
Now the count is 5
Now the count is 6
Now the count is 7

Now, it counting down to 0 from 7 is plainly obvious, but what I don't understand is how it then finds the rationale to count back up to 7.

No where in
Code:
if (count > 0)
count_dn(count);
printf("Now the count is %d\\\\n",count);



does it all mention a count++ or anything of the sort. In fact, count > 0 seems false in that count is now count == 0. This is like a rabbit coming out of the magician's hat.
A witty saying proves nothing - Voltaire
Air Bud
Internet Superstar

Some plants even masturbate into their own vaginas in order to reproduce.

Ballkicks: (+918 / -56)
Posts: 6785 (0.987)
Reg. Date: Sep 2001
Location: TEH INTARNET!
Gender: Male
Reply 22 of 42 (Originally posted on: 12-08-10 06:48:13 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

In order to fully understand how recursion works, you need to understand how the variables are stored in memory on the stack. That's not important right now though. What's important is how you actually interpret the information.

The function decrements count, then if count > 0, it calls itself with the newly decremented value. This continues until count = 0, in which case, it prints 0, then returns back to the callee (itself) where count = 1, which is then printed, returns back to its callee where count = 2, and so forth. It's best illustrated if you indent the output. For example:

Code:
The value of the count is 7
The value of the count is 6
The value of the count is 5
The value of the count is 4
The value of the count is 3
The value of the count is 2
The value of the count is 1
The value of the count is 0 // At this point the if-statement fails
Now the count is 0 // We now return to the callee
Now the count is 1 // Return to its callee
Now the count is 2 // Etc.
Now the count is 3
Now the count is 4
Now the count is 5
Now the count is 6
Now the count is 7



Basically, each instance of the count_dn function has its own copy of the local variable "count", each of which has its own, independent value for "count".
Trash Mod
Administrator
I wish I were dead.

i'm nick and i'm too stupid to read so i make unnecessary posts

Ballkicks: (+574 / -34)
Posts: 4454 (0.776)
Reg. Date: Oct 2004
Location: Trash
Gender: Male
Reply 23 of 42 (Originally posted on: 12-08-10 07:19:20 PM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Recursion kicks so much ass. Sandamnit's explanation is really good. It helps if you imagine the program executing line by line as well:

Keep in mind what Sandy said: Each time the function is called, it creates its own copy of "count".

So the main function calls count_dn with a value of 8 for the count argument. (Remember again: this is a copy. The variable index does not get changed at all). The function subtracts one and prints the result: 7. It then checks to make sure that count is greater than 0 (it is) and calls itself with 7 as the argument.

So it has now called the function again. That function creates a copy of count. Remember: it's not the actual count variable from the first count_dn () call. It is a copy. So it subtracts one from this copy and gets 6. It then prints out 6. It makes sure 6 is greater than 0 (it is) and then calls itself with 6 as the argument.

You can see how it counts all the way down this way. How does it count back up? Well, once count finally reaches 0, the functions start ending. What happens when the function ends? It prints out the value of count (0 at this point) and returns to the function that called it (itself) and then prints out the value of count in that function. Since the 0 was a copy specific to the function that ended, it uses the value of count in the function it is currently in (1) and prints that. Then ends the function, going to the next higher one up and prints the value of count in that (2). On up.

Recursion is really useful in sorting algorithms and stuff like that.
C
Administrator

Level 90 Ginger

Ballkicks: (+723 / -204)
Posts: 6647 (1.01)
Reg. Date: Jun 2002
Location: Missouri
Gender: Male
Reply 24 of 42 (Originally posted on: 12-09-10 06:22:26 AM)
Edit Post | Edit History | Send PM | Change Title | Reply w/Quote | Report Post | Ignore | Show All Posts

Code:
                                                                     







//**************************************************************************************
//December 2, 2010
//Program4.ccp
//
//
//
//**************************************************************************************

//**************************************************************************************
// The include section
//**************************************************************************************

#include
#include
#include

//**************************************************************************************
// The namespace section
//**************************************************************************************

using namespace std;

//**************************************************************************************
// Person Class
// This is the Person class which contains all of the information for the class.
//**************************************************************************************

class Person
{

friend ostream& operator<<(ostream&, Person&); //operator overloads
friend istream& operator>>(istream&, Person&); //operator overloads

public:
Person(); //constructor
Person(Person& obj); //other constructor
~Person(); //destructor
void Add(void); //Person::Add
void Update(void); //Person::Update
void Delete(void); //Person:[img="big grin"]/images/emoticons/biggrin.gif[/img]elete
void Print(void); //Person::Print
void Sort(void); //Person::Sort
void Search(void); //Person::Search
void PrintAll(); //Person::PrintAll
void DisplayMenu(); //Person:[img="big grin"]/images/emoticons/biggrin.gif[/img]isplayMenu
void Quit(); //Person::Quit

private:
char FirstName[32]; //Variable to hold user input
char MiddleName[32]; //Variable to hold user input
char LastName[32]; //Variable to hold user input
int x; //Variable to utilize key in the class
static int Key; //Variable to hold key value
Person* LinkedList; //data member that should point
//to another instance of the class
};

Person::Person() //constuctor for person class
{

LinkedList = 0; //LinkedList variable initialized to point to null
char none[] = {"none"}; //variable to initialize name values with
strcpy(FirstName, none); //initializes FirstName value
strcpy(MiddleName, none); //initializes MiddleName value
strcpy(LastName, none); //initializes LastName value
Key++; //increments Key value
x = Key; //x takes on value of Key

}

Person::Person(Person& myPerson) //other constructor
{ //the LinkedList variable in the object
//created by this constructor
//is supposed to point at myPerson,
//and it may or may not do so...
this->LinkedList = &myPerson;
char none[] = {"none"}; //variable to initialize name values with
strcpy(FirstName, none); //initializes FirstName value
strcpy(MiddleName, none); //initializes MiddleName value
strcpy(LastName, none); //initializes LastName value
Key++; //increments Key value
x = Key; //x takes on value of Key
}

Person::~Person() //destuctor for person class
{
cout << "Deleted." << endl;
system("pause");
}



//**************************************************************************************
// Person::Add
// This is allows the user to add names to the values.
//**************************************************************************************

void Person::Add(void)
{
char none[] = {"none"}; //holds the defualt value to check the name variables against
int result = ((strcmp(none, FirstName))
&&(strcmp(none, MiddleName))
&&(strcmp(none, LastName)));
//result holds the check value for the following if statement
//the string compares return either a 1 or 0 and result will equal that

if (result == 0)
{
cin >> *this;
}
else
{
cout << "Values already exist please use Update instead." << endl;
system("pause");
}
} //End of function Person::Add

//**************************************************************************************
// Person::Update
// This is allows the user to update existing values.
//**************************************************************************************

void Person::Update(void)
{
char none[] = {"none"}; //holds the defualt value to check the name variables against

int result = ((strcmp(none, FirstName))
&&(strcmp(none, MiddleName))
&&(strcmp(none, LastName)));
//result holds the check value for the following if statement
//the string compares return either a 1 or 0 and result will equal that

if (result != 0)
{
cout << *this;
cout << "Please enter your changes.\\n";
cin >> *this;
}
else
{
cout << "No values exist please use Add instead." << endl;
system("pause");
}
} //End of function Person::Update

//**************************************************************************************
// Person:[img="big grin"]/images/emoticons/biggrin.gif[/img]elete
// This is allows the user to delete existing values.
//**************************************************************************************

void Person:[img="big grin"]/images/emoticons/biggrin.gif[/img]elete(void)
{
char none[] = {"none"}; //holds the defualt value to check the name variables against

int result = ((strcmp(none, FirstName))
&&(strcmp(none, MiddleName))
&&(strcmp(none, LastName)));
//result holds the check value for the following if statement
//the string compares return either a 1 or 0 and result will equal that

if (result != 0)
{
cout << *this;
cout << "Are you sure you want to delete the entry? Y/N: ";
char yesno;
//holds the user input, used by the switch to determine where the program should follow
cin >> yesno;
char none[] = {"none"}; //holds the defualt value to replace name variables with
switch(yesno)
{
case 'y':
case 'Y':
cout << "The entry has been deleted.\\n";
strcpy(FirstName, none);
strcpy(MiddleName, none);
strcpy(LastName, none);
system("pause");
break;
case 'n':
case 'N':
cout << "Okay.\\n";
system("pause");
break;
default:
cout << "\\nPlease select a valid option.\\n";
break;
}
}
else
{
cout << "No values exist to delete." << endl;
system("pause");
}
} //End of function Person:[img="big grin"]/images/emoticons/biggrin.gif[/img]elete

//**************************************************************************************
// Person::Print
// This is allows the user to print the current values.
//**************************************************************************************

void Person::Print(void)
{
char none[] = {"none"}; //holds the defualt value to
//check the name variables agianst

int result = ((strcmp(none, FirstName))
&&(strcmp(none, MiddleName))
&&(strcmp(none, LastName)));
//result holds the check value for the following if statement
//the string compares return either a 1 or 0 and result will equal that

if (result != 0)
{
cout<<*this;
system("pause");
}
else
{
cout << "Person has no values to print." << endl;
system("pause");
}
} //End of function Person::Print

//**************************************************************************************
// Person::Search
// This is currently a stub function
//**************************************************************************************

void Person::Search(void)
{
cout << "Search called." << endl;
system("pause");
} //End of function Person::Search

//**************************************************************************************
// Person::Sort
// This is currently a stub function
//**************************************************************************************

void Person::Sort(void)
{
cout << "Sort called." << endl;
system("pause");
} //End of function Person::Sort

//**************************************************************************************
// Person:[img="big grin"]/images/emoticons/biggrin.gif[/img]isplayMenu
// This displays the menu to the screen and calls the other class functions
//**************************************************************************************

void Person:[img="big grin"]/images/emoticons/biggrin.gif[/img]isplayMenu()
{
int Option;

void (Person::*fptr[8])(void) = {&Person::Add, &Person::Update, &Person:[img="big grin"]/images/emoticons/biggrin.gif[/img]elete,
&Person::Sort, &Person::Print, &Person::Search,
&Person::PrintAll, &Person::Quit};
//array of function pointers

do
{
system("cls");
cout << "Please select an item from the list (numbers 1-8).\\n"
<< "1. Add\\n"
<< "2. Update\\n"
<< "3. Delete\\n"
<< "4. Sort\\n"
<< "5. Print\\n"
<< "6. Search\\n"
<< "7. Print All\\n"
<< "8. Quit\\n";
cin >> Option;

if(Option<1||Option>8)
{
cout << "Please enter an appropriate option." << endl;
system("pause");
}
else
{
(this->*fptr[Option-1])();
}
}while(Option!=8);
} //End of function Person:[img="big grin"]/images/emoticons/biggrin.gif[/img]isplayMenu

//**************************************************************************************
// Person::PrintAll
// This doesn't do what it's supposed to do. The function should display all
// person objects through the use of pointers (we believe). As is, it displays
// the location that the first object points to (000...), and another location
// which may or may not be the location of the second object.
//**************************************************************************************

void Person::PrintAll()
{
cout << this->LinkedList << endl;
cout << &this->LinkedList << endl;
system("pause");
} //End of function Person::PrintAll

//**************************************************************************************
// Person::Quit
// This function allows the program to quit
//**************************************************************************************

void Person::Quit()
{
} //End of function Person::Quit

//**************************************************************************************
//Overloaded Operators
//**************************************************************************************

ostream& operator<<(ostream& myOut, Person& Person) //overloads cout
{
myOut << "Person " //displays the object
<< Person.x
<< " is named "
<< Person.FirstName
<< " " << Person.MiddleName
<< " " << Person.LastName
<< "." << endl;
myOut << "Person " //displays what Linked list
<< Person.x //points to
<< " has a LinkedList pointing at "
<< Person.LinkedList
<< endl;
return myOut;
}

istream& operator>>(istream& myIn, Person& Person) //overloads cin
{
cout << "Please enter a first name: ";
myIn >> Person.FirstName;
cout << "Please enter a middle name: ";
myIn >> Person.MiddleName;
cout << "Please enter a last name: ";
myIn >> Person.LastName;

return myIn;
}

//**************************************************************************************
//The function prototype section
//**************************************************************************************

void StartUp(void);
void WrapUp(void);

//**************************************************************************************
//The global variable declaration section
//**************************************************************************************

char ProgramName[] = "Program3.cpp"; //Used to hold the program name
int Person::Key = 0; //initializing Key value

//**************************************************************************************
// The enumeration section
//**************************************************************************************

enum Status {Success, Failure}; // Used to test or return
// value for program
// success or failure

//**************************************************************************************
// main
// This is the entry point for this program. It controls
// the flow of execution.
//**************************************************************************************

int main()
{
StartUp();

Person *person1 = new Person; //this instantiates a person object
Person *person2 = new Person(*person1); //this instantiates a person object
//which should have its LinkedList
//variable pointing to the other object
person1->DisplayMenu();

delete person1;
delete person2;

WrapUp();
return Success;
} //End of function main



//**************************************************************************************
// StartUp
// Currently this is an empty module or stub. It will be used
// to perform any needed initialization.
//**************************************************************************************

void StartUp(void)
{
} //End of function StartUp

//**************************************************************************************
// WrapUp
// It is used to perform any end of program processing needed.
//**************************************************************************************

void WrapUp(void)
{
cout << "Program "
<< ProgramName
<< " ended successfully."
<< endl;
} //End of function WrapUp



This thing doesn't do everything it's supposed to, and I can't make it work because I hate programming wheeeeeeee. I'll grab the details, but I figured I'd post the code before I logged off and grab the actual description out of my car around lunch.
"Remember, Jesus would rather constantly shame the gays than let orphans have families."
Quick Reply
Page: [ 1 2 ] Reply to Thread | Create New Thread | Create New Poll | Convert To Poll | Subscribe To Thread
[ Thread Views: 4285 | Total Posts: 42 ]