Copyright 2004 by M. Uli Kusterer Tue, 30 Dec 1969 07:58:58 GMT Comments on article book6 at Zathras.de http://www.zathras.de/angelweb/book6.htm book6 Comments witness_dot_of_dot_teachtext_at_gmx_dot_net (M. Uli Kusterer) witness_dot_of_dot_teachtext_at_gmx_dot_net (M. Uli Kusterer) en-us Comment 34 by hobs http://masters-of-the-void.com/book6.htm#comment34 http://masters-of-the-void.com/book6.htm#comment34 hobs writes:
Wow. I had to read through this twice, but like the previous commenters were saying, I was having lightbulb comments all over the place. Thank you so much for this article.
Comment 33 by Uli Kusterer http://masters-of-the-void.com/book6.htm#comment33 http://masters-of-the-void.com/book6.htm#comment33 Uli Kusterer writes:
If by 'unspecified' you mean 'contains an arbitrary, random number that is not a valid address', then yes. That's exactly what's going on, yes :-)
Comment 32 by Jack http://masters-of-the-void.com/book6.htm#comment32 http://masters-of-the-void.com/book6.htm#comment32 Just to clarify, when you said: int * aAddress; that was declaring the pointer variable aAddress that points to an int variable that is currently unspecified, yes? And then after that when you say aAddress = &a; this then means that aAddress points to int variable a, is this also correct?
Comment 31 by Uli Kusterer http://masters-of-the-void.com/book6.htm#comment31 http://masters-of-the-void.com/book6.htm#comment31 Uli Kusterer writes:
Elijah,

If you were talking about the line breaks in the code samples that had disappeared, that should be fixed again now.
Comment 30 by Elijah http://masters-of-the-void.com/book6.htm#comment30 http://masters-of-the-void.com/book6.htm#comment30 I LOVE THIS! I've been interested in learning how to program for a few years now, and this is the single best, straightforward and intelligible tutorial I have ever read!

One request though; please add tables to your text boxes! I can't read without scrolling left and right to the end of each line.

THANKS!

Comment 29 by David Crooks http://masters-of-the-void.com/book6.htm#comment29 http://masters-of-the-void.com/book6.htm#comment29 David Crooks writes:
This is the best tutorial I've found for C on the mac. Thanks.

For what its worth, here's my version of the calculator,


#include <stdio.h>
#include <stdbool.h>

void GetArgument( int * leftNum,int * rightNum ) // read in user input, two integers
{
printf( "Enter the left argument: " );
scanf( "%d", leftNum );
fpurge( stdin );
printf( "Enter the right argument: " );
scanf( "%d", rightNum );
fpurge( stdin );
}




int main()
{
int vLeftArg, vRightArg;
char vOperation;
bool vFinished;

// Make sure our flag is initialized!
vFinished = false;

// Now loop until user doesn't want anymore:
while( vFinished != true )
{

printf( "What operation do you want to do? (+ ,/ ,* , q to quit)\n" ); // ask the user to select an operation
scanf( "%c", &vOperation );
fpurge( stdin );

switch( vOperation )
{
case '/': // test for division

GetArgument(&vLeftArg,&vRightArg); // get numbers from user


if (vRightArg != 0) //test for division by zero
{
printf( "\n%d / %d = %d\n",
vLeftArg,
vRightArg,
vLeftArg / vRightArg ); // if all is well, divide and display the result
}
else {
printf("infinity!!!!!! \n"); // bigger than you can possibly imagine
}

break;

case '+': //test for addition

GetArgument(&vLeftArg,&vRightArg); // get nunbers from user

printf( "\n%d + %d = %d\n",
vLeftArg,
vRightArg,
vLeftArg + vRightArg ); //add and display
break;

case '*': // test for multiplictaion


GetArgument(&vLeftArg,&vRightArg); // get nunbers from user
printf( "\n%d * %d = %d\n",
vLeftArg,
vRightArg,
vLeftArg * vRightArg ); // multiply and display
break;

case 'q': // test for quit
vFinished = true; // on q, quit
break;

default:
printf("I'm sorry, but I don't understand. Try again. \n"); // in case of gobbledygook
break;
}



}

printf( "Finished.\n" );

return 0;
}
Comment 28 by Tristan Moriarty http://masters-of-the-void.com/book6.htm#comment28 http://masters-of-the-void.com/book6.htm#comment28 By "parameter function", I just meant really the kind of function that we have here with GetArgument. I think about it like this because it was the first function we introduced with a parameter a couple of tutorials ago. Apologies, I'm new to programming and it seems quite easy to make up one's own jargon!
Comment 27 by Uli Kusterer http://masters-of-the-void.com/book6.htm#comment27 http://masters-of-the-void.com/book6.htm#comment27 Uli Kusterer writes:
Not sure what you mean by a "parameter function"? But yes, the idea here is to change a variable that is *outside* the current function. Every function can only change the variables declared within its { and } brackets, (or return a value, which the function that called it can then assign to one of its variables).

To change any other variable, you need to use a pointer.

Oh, of course global variables can also be changed by any old function, that is their purpose, after all, and their curse.
Comment 26 by Tristan Moriarty http://masters-of-the-void.com/book6.htm#comment26 http://masters-of-the-void.com/book6.htm#comment26 Hi Uli, and thankyou again for a great set of tutorials! I also found this lesson trickier than what has gone before. Am I right in thinking that essentially what we learn here is a new way of changing a variable using a pointer, and that what makes this useful is that by putting a pointer into a parameter function, we can call that function with any variable we like (provided it is a variable of the same kind as the pointer type) and change it's value to one in line with our parameter function? Apologies if that seems like just a long winded way of saying something that should have made sense anyway, but that's how I'm thinking about it!

Thanks again for these articles- they really are very very helpful!
Comment 25 by Aman http://masters-of-the-void.com/book6.htm#comment25 http://masters-of-the-void.com/book6.htm#comment25 Roope, your code should be like this, else it doesnt add up

.....

GetArgument( true, &a);

GetArgument( false, &b);

sum = *aAddress+*bAddress;

printf("%d plus %d equals %d", *aAddress, *bAddress, *sumAddress);

}
Comment 24 by Roope http://masters-of-the-void.com/book6.htm#comment24 http://masters-of-the-void.com/book6.htm#comment24 Got it! It was before calls afterwards works a bit better :D
Comment 23 by Roope http://masters-of-the-void.com/book6.htm#comment23 http://masters-of-the-void.com/book6.htm#comment23 This is what I have now, and I get 1+2=0?



#include <stdio.h>
#include <stdbool.h>

int GetArgument( bool isLeft, int * outPut)
{
if( isLeft )
printf( "Enter the left argument: " );
else
printf( "Enter the right argument: " );
scanf( "%d", outPut );
fpurge( stdin );
}


int main()
{
int a;
int * aAddress = &a;

int b;
int * bAddress = &b;

int sum;
int * sumAddress = &sum;

sum = *aAddress+*bAddress;

GetArgument( true, &a);

GetArgument( false, &b);

printf("%d plus %d equals %d", *aAddress, *bAddress, *sumAddress);

}
Comment 22 by Roope http://masters-of-the-void.com/book6.htm#comment22 http://masters-of-the-void.com/book6.htm#comment22 #include <stdio.h>
#include <stdbool.h>

int GetArgument( bool isLeft, int * outPut)
{
if( isLeft )
printf( "Enter the left argument: " );
else
printf( "Enter the right argument: " );
scanf( "%d", outPut );
fpurge( stdin );
}


int main()
{
int a;
int * aAddress = &a;

int b;
int * bAddress = &b;

int sum = *aAddress + *bAddress;

*aAddress = GetArgument( true, &a);


*bAddress = GetArgument( false, &b);

printf("%d plus %d equals %d", *aAddress, *bAddress, sum);

}


That's my code, what's wrong coz I get 0 plus 0 equals 0. ?


Great tutorial! Thanks!
Comment 21 by College student http://masters-of-the-void.com/book6.htm#comment21 http://masters-of-the-void.com/book6.htm#comment21 I also will admit the past two chapters of this tutorial were a tad confusing. I myself have taken two semesters of JAVA, and this C business isn't bad at all. To those of you out there that are learning this stuff without any prior experience to programming, I must give you kudos; this stuff isn't easy at first.
Comment 20 by Richard Howell http://masters-of-the-void.com/book6.htm#comment20 http://masters-of-the-void.com/book6.htm#comment20 Ha! It works. And right now, Hex is a blessing :)
Thanks
Comment 19 by Uli Kusterer http://masters-of-the-void.com/book6.htm#comment19 http://masters-of-the-void.com/book6.htm#comment19 Uli Kusterer writes:
Well, an int* isn't really an int. it's a pointer to an int. It is a number, but marked specially. There's a special format for those, %p, but that prints the number in hexa-decimal. Alternately, you could typecast it, (see later chapters), and write

(int) address

This will work as long as you're on a 32-bit Mac. If your Mac runs in 64 bits, addresses are 64-bit long and won't fit in a shorter int. They do fit in a "long int" with format "%d" in that case, though.
Comment 18 by Richard Howell http://masters-of-the-void.com/book6.htm#comment18 http://masters-of-the-void.com/book6.htm#comment18 OK. But when I replaced the misplaced '*'s in my printf statements...we get a new problem in that the compiler tells me:

Format 'd%' expects type 'int', but argument 'n' has type 'int *'.

When you used a char to store the address in your example, you were able to use '%c'. Why can't I use %d?
Comment 17 by steven http://masters-of-the-void.com/book6.htm#comment17 http://masters-of-the-void.com/book6.htm#comment17 steven writes:
I have read these last two chapters twice, and now I am four times as confused.

^_^

Anyway, thanks for a really great tutorial.

So, A=15
and aAddress= the place in memory where I can find the location of A, which contains 15?
Comment 16 by Uli Kusterer http://masters-of-the-void.com/book6.htm#comment16 http://masters-of-the-void.com/book6.htm#comment16 Uli Kusterer writes:
You're using the * operator in all your print statements. That operator means "follow the address to its value". That's why it's printing the value again, not the address.
Comment 15 by Richard Howell http://masters-of-the-void.com/book6.htm#comment15 http://masters-of-the-void.com/book6.htm#comment15 OK. I wrote this:

#include <stdio.h>

int main () {

int number;
int newNumber;
int * address = &number;

printf( "Give me a number to store in memory: " );
scanf( "%d", &number );
fpurge( stdin );

printf( "\nThe number %d can be found at memory location %d", number,* address);

newNumber = *address = +1;
printf( "\nThe new number stored in location %d is %d", * address, newNumber);
return 0;
}

And I had this output:

Give me a number to store in memory: 123

The number 123 can be found at memory location 123
The new number stored in location 1 is 1

I think I'm missing the point here. Shouldn't I be printing a memory location, and not just a repeat of what I typed in?
Comment 14 by Gordon http://masters-of-the-void.com/book6.htm#comment14 http://masters-of-the-void.com/book6.htm#comment14 Uli,

First thanks for the tutorials. This one definitely takes a few reads.

I think this particular chapter needs some more visuals. The part that is really confusing for me is the part about

int * bAddress = &a;

and the ambiguity. Some visuals illustrating pointer relationships and why this is ambiguous might be helpful to cement the problem in our minds.

But otherwise a fairly clear explanation.
Comment 13 by Mk12 http://masters-of-the-void.com/book6.htm#comment13 http://masters-of-the-void.com/book6.htm#comment13 I still don't get the point of the pointers (no pun intended). Why not just pass the actual variables and set those instead of using the pointers and addresses (except for the fact that scanf needs addresses)?
Comment 12 by Uli Kusterer http://masters-of-the-void.com/book6.htm#comment12 http://masters-of-the-void.com/book6.htm#comment12 Uli Kusterer writes:
Bruno, thanks for the kind words. I'd love to do a Spanish version, but sadly I know about three words of Spanish, so this isn't very likely to happen.
Comment 11 by Bruno Gätjens González http://masters-of-the-void.com/book6.htm#comment11 http://masters-of-the-void.com/book6.htm#comment11 Hi!!!

First of all thanks for this amazing tutorial for us the C beginner, thank you for take the time to prepare and write all that. I am from Costa Rica and i was thinking if there is the possibility in the future to make it in Spanish too? :)

Thank you so much again.
Bruno
Comment 10 by Uli Kusterer http://masters-of-the-void.com/book6.htm#comment10 http://masters-of-the-void.com/book6.htm#comment10 Uli Kusterer writes:
TJ, I have to admit I don't really understand your question. But I'll try:

"if" simply does the upper thing if the thing between the brackets ends up being "true". Otherwise it does the second thing. The things between the brackets are parameters, that is, they're local variables, but they get filled in when the function is called, right before any of the code between the { and } is run. If you call it as GetArgument( true, &vMyNumber );, isLeft will be set to true, if you call GetArgument( false, &vMyNumber );, isLeft will be set to false. Whatever we specify as the first parameter value in the call will end up in the first parameter here, because we wrote "bool isLeft" as the first item between the brackets. That's the magic of parameters. Regular local variables are declared lower down between { and }, but the parameters are special "mailboxes" through which data from the outside gets into our function, just like the return value (which we're not using here, hence the "void") can pass data back out again.

Now, when the code actually gets run, the "if( isLeft )" line does the same thing it would do in other cases: Compare what's in the brackets to true and do one thing or the other.

Did that help? Or did I misunderstand your problem?
Comment 9 by TJ Leeland http://masters-of-the-void.com/book6.htm#comment9 http://masters-of-the-void.com/book6.htm#comment9 I'm confused on a different point.

void GetArgument( bool isLeft, int * outNum ) //Creates a function(?) named
GetArgument using the void
data type that uses an
arguement that is creating
a boolean variable named
isLeft, then a creates a
integer of the pointer
data type named outNum
{
if( isLeft ) //here is where I am
confused. How does the
program know if
"if ( isLeft )" is indeed
isLeft?
printf( "Enter the left argument: " );
else
printf( "Enter the right argument: " );
scanf( "%d", outNum );
fpurge( stdin );
}
Comment 8 by Uli Kusterer http://masters-of-the-void.com/book6.htm#comment8 http://masters-of-the-void.com/book6.htm#comment8 Uli Kusterer writes:
John, your code is certainly also correct. It's just a different level of re-use. You *can* use this notation to return several values, but I wanted to show that this is *completely equivalent* to returning a value. I'll think about ways to make this clearer.
Comment 7 by John David Dunson http://masters-of-the-void.com/book6.htm#comment7 http://masters-of-the-void.com/book6.htm#comment7 well, it took me three days to figure all of this out.

to jaxerell:

"a" and "aAddress" are two different variables.

"a" is a normal variable.
"aAddress" is a variable that stores the memory address of another variable (in this case, "a"). this type of variable is called a pointer.

so there are two ways to change "a".
you could go the normal route and say: a = 15;
or you could go the technical route and say: *aAddress = 15

the first route is saying: go to the place in memory where the variable named "a" is stored and change the value stored there to 15.
the second route is saying: go to "this specific address in memory" and change the value stored there to 15.

here's my explanation of his example:

char a = 'X'; // declare a character-type variable named "a" and initialize it to the value X.
char * aAddress = &a; /* declare a pointer-type variable named "aAddress" and initialize it to the address of the variable "a".
(a character-type can also hold an integer.)*/
*aAddress = 'Y'; /* go to the place in memory that "aAddress" points to and change the value stored there to Y.
in other words, change the variable "a" to the value Y (it used to be X and now it's Y).*/
printf("%c %c\n", a, *aAddress); /* print the value of the variable "a" to the console, then print the value stored at "aAddress" to the console.
basically, you're accessing the same sopt in memory using two different methods. Y Y would be the result.
if you left off the third line, then X X would be the result.
if you left off the asterisk in the last line, then Y 32 (or whatever the address of "a" is) would result.*/


what i don't get is why you taught us the ability to do more than one thing in a function, then you give us an example that will require the function to be called twice. so here's how it should look… although, this method is still not as efficient for this simple program as my original code was that i posted on page 4. A Crude Calculator… but here it is anyway, using pointers, address-of, and a function:

void GetArgument(int* outFirstArg, int* outSecondArg)
{
printf("Enter left argument: ");
scanf("%d", outFirstArg);
fpurge(stdin);

printf("Enter right argument: ");
scanf("%d", outSecondArg);
fpurge(stdin);
}


then the call would look like this:

GetArgument(&vFirstArg, &vSecondArg);
Comment 6 by Jaxerell http://masters-of-the-void.com/book6.htm#comment6 http://masters-of-the-void.com/book6.htm#comment6 This page is way confusing, didn't understand half of it.

Is the lowercase a in aAddress supposed to be a letter or replaced with a number?
Comment 5 by Josh http://masters-of-the-void.com/book6.htm#comment5 http://masters-of-the-void.com/book6.htm#comment5 Josh writes:
Marc is right, it should be &vFirstArg, not &leftArgument.

Regardless, thank you very much for writing these tutorials!
Comment 4 by Marc Davidson http://masters-of-the-void.com/book6.htm#comment4 http://masters-of-the-void.com/book6.htm#comment4 I believe "GetArgument( true, &leftArgument );" should read "GetArgument( true, &vFirstArg );
" to be consistent with the variable names used previously, right?
Comment 3 by Jason http://masters-of-the-void.com/book6.htm#comment3 http://masters-of-the-void.com/book6.htm#comment3 Jason writes:
I agree the last two lessons were tough, a little confusing, but after reading them over twice, I think I now get them. Real brain exercise, that's for sure. Thanks for doing this.
Comment 2 by Cameron Cooke http://masters-of-the-void.com/book6.htm#comment2 http://masters-of-the-void.com/book6.htm#comment2 This tutorial is fantastic. I had so many light bulb moments! It makes total sense.
Comment 1 by Colton http://masters-of-the-void.com/book6.htm#comment1 http://masters-of-the-void.com/book6.htm#comment1 These last two lessons got really confusing, really fast.