Copyright 2004 by M. Uli Kusterer Tue, 30 Nov -1901 08:00:00 GMT Comments on article book4 at Zathras.de http://www.zathras.de/angelweb/book4.htm book4 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 28 by Uli Kusterer http://masters-of-the-void.com/book4.htm#comment28 http://masters-of-the-void.com/book4.htm#comment28 Uli Kusterer writes:
Withan, it's a warning about good style, but shouldn't really cause you any trouble. Book 11 will explain what a prototype is and how to add one.
Comment 27 by Withan http://masters-of-the-void.com/book4.htm#comment27 http://masters-of-the-void.com/book4.htm#comment27 my Xcode is giving a warning on the "int GetArgument ( bool isLeft)" line "NO PREVIOUS PROTOTYPE FOR THE FUNCTION 'GETARGUMENT'

It still runs perfectly, but why am I getting this warning, and can I turn it off?

xCode 4.2
Comment 26 by Jonathan Decktor http://masters-of-the-void.com/book4.htm#comment26 http://masters-of-the-void.com/book4.htm#comment26 Hi Katrine.
Hope this is still relevant, seems like you have a { inside the getargument that doesn't have a matching }.
Comment 25 by Katrine http://masters-of-the-void.com/book4.htm#comment25 http://masters-of-the-void.com/book4.htm#comment25 Hi,

can someone explain how get rid of this error:

Calculator.c: In function ‘getArgument’:
Calculator.c:19: error: nested functions are disabled, use -fnested-functions to re-enable
Calculator.c:60: error: expected declaration or statement at end of input

My code is the following:

#include "stdio.h"
#include "stdbool.h"

int getArgument( bool isLeft ){
int vNum;

if(isLeft)
printf("Enter left argument: ");

else{
printf("nEnter right argument: ");

scanf("%d", &vNum);
fpurge(stdin);

return vNum;
}

int main() {
int vFirstArg, vSecondArg;
char vOperation;
bool vFinished;

vFinished = false;

while(vFinished != true){
printf("n What operation do you want to do?n");
scanf("%c", &vOperation);
fpurge(stdin);

if(vOperation == '+'){
vFirstArg = getArgument(true);
vSecondArg = getArgument(false);

printf("n%d + %d = %dn" , vFirstArg, vSecondArg, vFirstArg + vSecondArg);
}
else if(vOperation == '-'){
vFirstArg = getArgument(true);
vSecondArg = getArgument(false);

printf("n%d - %d = %dn" , vFirstArg, vSecondArg, vFirstArg - vSecondArg);
}
else if(vOperation == '*'){
vFirstArg = getArgument(true);
vSecondArg = getArgument(false);

printf("n%d * %d = %dn" , vFirstArg, vSecondArg, vFirstArg * vSecondArg);
}
else if(vOperation == '/'){
vFirstArg = getArgument(true);
vSecondArg = getArgument(false);

printf("n%d / %d = %dn" , vFirstArg, vSecondArg, vFirstArg / vSecondArg);
}
else
vFinished = true;
}
printf("Finished.n");
return 0;
}
Comment 24 by Caroline http://masters-of-the-void.com/book4.htm#comment24 http://masters-of-the-void.com/book4.htm#comment24 Great tute! I have only done a little programming in basic, and the way the commands are contained in functions is new to me. Your tute is making it really easy to follow.
Comment 23 by Mike Polinske http://masters-of-the-void.com/book4.htm#comment23 http://masters-of-the-void.com/book4.htm#comment23 Isaac Senior,

The scant and fpurge are outside of the scope of the if statement.

It will always do the scant and fpurge whether isLeft is true or false. For clarity you could write:


if (isLeft)
{
printf("Enter left argument: ");
}
else
{
printf("Enter right argument: ");
}
scanf("%d", &vNum);
fpurge(stdin);

But why would you want to do that when the commands in the if/else are only one statement.
Comment 22 by Rafael Estrella http://masters-of-the-void.com/book4.htm#comment22 http://masters-of-the-void.com/book4.htm#comment22 I find it very confusing when you use the term "the functions that called you". What does that mean exactly.
Comment 21 by isaac Senior http://masters-of-the-void.com/book4.htm#comment21 http://masters-of-the-void.com/book4.htm#comment21 I have a quick question.
Why don't you write the
scanf and fpurge under if( isLeft )
if its suppose to represent it all:
the printf the scanf and the fpurge ??
Comment 20 by isaac Senior http://masters-of-the-void.com/book4.htm#comment20 http://masters-of-the-void.com/book4.htm#comment20 I have a quick question.
Why don't you write the
scanf and fpurge under if( isLeft )
if its suppose to represent it all:
the printf the scanf and the fpurge ??
Comment 19 by Supermouse http://masters-of-the-void.com/book4.htm#comment19 http://masters-of-the-void.com/book4.htm#comment19 Hi Steven, I don't know how old this is, but to answer your question:

you need elses after each if in your function. The program as it's written will change vFinished to true anytime your input is not *. If you put an else after each if, the programa will change vFinished to true only if your input is not +, -, / or *.

Hope it helped.
Comment 18 by Steve http://masters-of-the-void.com/book4.htm#comment18 http://masters-of-the-void.com/book4.htm#comment18 Hi Uli, thanks for the tutorials.
When I use the + - and / operations, my program performs the calculation then finishes, only when I perform the * operation it gives me the option to calculate again. I can't figure out why, here is my code.
#include <stdio.h>
#include <stdbool.h>

int GetArgument( bool isLeft) //a function and a place to store (parameter)
{
int vNum; //a variable for the integer

if( isLeft ) //isLeft gets its value later
printf("Enter a number: ");
else
printf("Enter another number: ");
scanf( "%d", &vNum ); //puts the number into vNum
fpurge( stdin ); //makes sure any extra character entered after numb are discarded


return vNum;
}

int main()
{
int vFirstArg, vSecondArg;
char vOperation;
bool vFinished;

vFinished = false; //make sure the flag is initialised

while ( vFinished != true ) //loop until flag is initialised
{
printf( "What operation do you want to do? (+,-,/,*) \n");
scanf("%c", &vOperation);
fpurge( stdin );

if( vOperation == '+')
{
vFirstArg = GetArgument(true);
vSecondArg = GetArgument(false);

printf( "\n %d + %d = %d \n", vFirstArg, vSecondArg, vFirstArg + vSecondArg);

}


if( vOperation == '-')
{
vFirstArg = GetArgument(true);
vSecondArg = GetArgument(false);

printf( "\n %d - %d = %d \n", vFirstArg, vSecondArg, vFirstArg - vSecondArg);

}

if( vOperation == '/')
{
vFirstArg = GetArgument(true);
vSecondArg = GetArgument(false);
if(vSecondArg == 0)
{
printf("You can't divide by zero, try again: ");
scanf("%d", &vSecondArg);

printf( "\n %d / %d = %d \n", vFirstArg, vSecondArg, vFirstArg / vSecondArg);
}
else
{
printf( "\n %d / %d = %d \n", vFirstArg, vSecondArg, vFirstArg / vSecondArg);
}


}

if( vOperation == '*')
{
vFirstArg = GetArgument(true);
vSecondArg = GetArgument(false);

printf( "\n %d * %d = %d \n", vFirstArg, vSecondArg, vFirstArg * vSecondArg);

}


else vFinished = true;
}


printf("finito.\n");
return 0;
}
Comment 17 by CMacRun http://masters-of-the-void.com/book4.htm#comment17 http://masters-of-the-void.com/book4.htm#comment17 Uli,

Sorry, false alarm. I realized I was hitting "enter" instead of "return". It runs great now....
Comment 16 by CMacRun http://masters-of-the-void.com/book4.htm#comment16 http://masters-of-the-void.com/book4.htm#comment16 Uli,

First - I've done some surfing on the web for tutorials on C, and yours is definitely a cut above the rest!

I am having problem with my code after I added in the GetArgument stuff. When I compile and run, it stops after I input the answer to the first question about +,-,/, etc.

Here is my code. Thanks for your help!

#include <stdio.h> // Defines printf etc.
#include <stdbool.h>

int GetArgument( bool isLeft )
{
int vNum;

if (isLeft )
printf("Enter 1st number: ");
else
printf("Enter 2nd number: ");
scanf( "%d", &vNum);
fpurge(stdin);

return vNum;

}

int main()
{
int vFirstArg,
vSecondArg;
char vOperation;
bool vFinished;

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

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

printf( "Welcome to my calculator! Would you like to +, -, * or /?\n" );
scanf( "%c", &vOperation );
fpurge( stdin );

if( vOperation == '+' )

{

vFirstArg = GetArgument(true);

vSecondArg = GetArgument(false);

printf( "\n%d + %d = %d\n",
vFirstArg,
vSecondArg,
vFirstArg + vSecondArg );
}
else
{
if ( vOperation == '-')

{
vFirstArg = GetArgument(true);

vSecondArg = GetArgument(false);

printf( "\n%d - %d = %d\n",
vFirstArg,
vSecondArg,
vFirstArg - vSecondArg);

}
else
{
if (vOperation == '*')

{
vFirstArg = GetArgument(true);

vSecondArg = GetArgument(false);

printf( "\n%d * %d = %d\n\n",
vFirstArg,
vSecondArg,
vFirstArg * vSecondArg);
}
else
{
if (vOperation == '/')

{
vFirstArg = GetArgument(true);

vSecondArg = GetArgument(false);

if (vSecondArg == 0)
{
printf("\nHello! You can't divide by zero. Are you trying to crash my program? \nPick a new number!");
scanf("%d", &vSecondArg);
fpurge(stdin);

printf("\n%d / %d = %d\n\n",
vFirstArg,
vSecondArg,
vFirstArg / vSecondArg);
}
else
printf("\n%d / %d = %d\n\n",
vFirstArg,
vSecondArg,
vFirstArg / vSecondArg);
}
else
vFinished = true;
}
}
}
}

printf( "Finished.\n" );

return 0;
}
Comment 15 by Benoît http://masters-of-the-void.com/book4.htm#comment15 http://masters-of-the-void.com/book4.htm#comment15 Garotas*, because C's design doesn't allow you to call a function unless you've already declared it earlier in the file. To solve this problem, you can state the return type, the name, and the arguments (if any) of GetArgument() at the top, then define it (implement it with actual code) after the main function.

MathNinja, if the variable is defined as an unsigned int, which is 4-byte long, it can hold a number up to +2^32-1. A signed int, capable of representing negative integers, is in the range of -2^16 to +2^16-1.
Comment 14 by MathNinja http://masters-of-the-void.com/book4.htm#comment14 http://masters-of-the-void.com/book4.htm#comment14 What is the range of integers that we can use for this crude calculator?
Comment 13 by steven http://masters-of-the-void.com/book4.htm#comment13 http://masters-of-the-void.com/book4.htm#comment13 steven writes:
PS, like the Captcha phrase. Usually, I hate captchas, but this was good


anyway, I am having trouble with division producing amazing long strings.

the code is :
else if (vOperation=='/')
{

vFirstArg=GetArgument(true);
vSecondArg=GetArgument(false);
if (vSecondArg==0) {

printf("This would cause a division by zero error. Also, Proffessor Friedman's arguments are never null \n");
vSecondArg=GetArgument(false);
}
printf("\n%f / %f = %f\n",
vFirstArg,
vSecondArg,
vFirstArg/vSecondArg);

}

else {

Anyway, the question is, is C so strongly typed that I can't massage D into F at run time?
Comment 12 by Garotas* http://masters-of-the-void.com/book4.htm#comment12 http://masters-of-the-void.com/book4.htm#comment12 One question about the function getArgument(). Why can't I put it after main()?
Comment 11 by Charles Marshall http://masters-of-the-void.com/book4.htm#comment11 http://masters-of-the-void.com/book4.htm#comment11 I thought I was trying to be too clever! GetArgument() is a function... I knew that. Onwards into the Void!
Thanks Uli!
Comment 10 by Uli Kusterer http://masters-of-the-void.com/book4.htm#comment10 http://masters-of-the-void.com/book4.htm#comment10 Uli Kusterer writes:
Charles, what do you expect to happen? *every* occurrence of a function that you write in an expression causes that function to be run once. Your line contains four calls to GetArgument(), so the user will be asked four times. I guess you just optimized to far :-)
Comment 9 by Charles Marshall http://masters-of-the-void.com/book4.htm#comment9 http://masters-of-the-void.com/book4.htm#comment9 I thought this seemed like a logical way to economize even more:

if(myOperator=='+')

printf("%d + %d = %d\n", GetArgument(true), GetArgument(false), GetArgument(true)+GetArgument(false));


And although it eventually works, it's obviously not correct because it requires typing the arguments twice in the console:

Please select a function (+,-,*,/ or q to quit):+
Please input your first number:3
Please input your second number:4
Please input your second number:4
Please input your first number:3
3 + 4 = 7

Can you tell me what's happening here? or should I just stop messing around and move on to the next lesson? ;)
Comment 8 by Uli Kusterer http://masters-of-the-void.com/book4.htm#comment8 http://masters-of-the-void.com/book4.htm#comment8 Uli Kusterer writes:
Yup, that sounds like you nailed it :-)
Comment 7 by Charles Marshall http://masters-of-the-void.com/book4.htm#comment7 http://masters-of-the-void.com/book4.htm#comment7 Thanks, Uli! Okay. I think I was confusing "compiling" and "running". So let me see if I got this straight: the compiler needs to see everything in order from top to bottom or else it wouldn't know that GetArgument() existed. And when the program runs, it does so directly from main(). The various "vFirstArg=GetArgument(true);" lines in main(), in effect, 'initialize' the boolean "isLeft" in the GetArgument() function (setting the value to true or false as the case may be). The end result is the return value stored in vNum which 'replaces' the right side of the "vFirstArg=GetArgument(true);".

Is that right?

Also, would it be safe to describe the entire GetArgument() function as a sort of "macro"?
(maybe I shouldn't go there...)

One final thing: with an "if" statement, it seems from this example that a boolean condition doesn't have to be written out like an equation (condition=true) but the condition can simply be a boolean variable defined (maybe elsewhere in the code) as "true" for the "if" command to take place. Do I have that right?
Comment 6 by Uli Kusterer http://masters-of-the-void.com/book4.htm#comment6 http://masters-of-the-void.com/book4.htm#comment6 Uli Kusterer writes:
Charles,

it may help to look at the movie again. You see that the parameter, isLeft, is initialized with the "true", that flies over from where we call it. This happens because the "int isLeft" was written between the brackets, not between the curly brackets where we put "normal" local variables. Regular local variables only exist inside the function and cease to exist once we have returned to the calling function (in this case, main()). Parameters are special, and hence go between the brackets to tell the compiler that is where we want our stuff from outside to come in. Since the stuff from outside gets put in them, there's no need to initialize them any further.
Comment 5 by Uli Kusterer http://masters-of-the-void.com/book4.htm#comment5 http://masters-of-the-void.com/book4.htm#comment5 Uli Kusterer writes:
Charles, these are two separate things: The program needs to make sense to the compiler when read from top to bottom in the sense that you can't use anything that hasn't been mentioned before. The compiler has to know what GetArgument() is before you can use it. However, all that is needed when the compiler turns our C text into actual machine code. Once that is done, the compiler knows where the main() function is, etc., so it doesn't need to do everything in order, it can start at main() directly.

The part about *initializing* a variable is necessary when you *run* the program. If you do not provide some initial value, it will contain garbage. Since a parameter (like isLeft in the case of GetArgument()) is a sort of "mail box" into which values from outside come into the function, you can't give it an initial value inside the function (after all, then that would replace whatever was put in it from the outside). Instead, you do that in main() or wherever else you call GetArgument, by writing the value you want in isLeft between the brackets after the function name.

More questions?
Comment 4 by Charles Marshall http://masters-of-the-void.com/book4.htm#comment4 http://masters-of-the-void.com/book4.htm#comment4 I'm confused. I was under the impression that the compiler (or computer, not sure which term to use here) reads the code in our file from top to bottom. And a lesson or two ago you said a boolean variable needed to be initialized. I don't see where this is happening, unless the computer isn't reading "GetArgument" first. Is the parameter variable getting initialized from the "vFirstArg=GetArgument(true);" line?

For that matter, could the entire "GetArgument" block be somewhere else, like at the bottom of the file?
Comment 3 by David Hunter http://masters-of-the-void.com/book4.htm#comment3 http://masters-of-the-void.com/book4.htm#comment3 David Hunter writes:
I did the same thing at first.
you have:

if( vOperation == '+' )
{
vFirstArg = GetArgument(true);

vFirstArg = GetArgument(false);

in each of your operations, you want to have:

if( vOperation == '+' )
{
vFirstArg = GetArgument(true);

vSecondArg = GetArgument(false);

otherwise you are setting vFirstArg and then resetting it and not defining vSecondArg.

See what I mean, I did the same thing some how.
Comment 2 by Uli Kusterer http://masters-of-the-void.com/book4.htm#comment2 http://masters-of-the-void.com/book4.htm#comment2 Uli Kusterer writes:
Snakeman, you're doing vFirstArg = GetArgument(true) and then vFirstArg = GetArgument(false). So, you put the first argument in vFirstArg, then overwrite it with the second argument, then calculate using vFirstArg (containing the second argument) and vSecondArg (which has never been assigned a value, and thus just contains a garbage number.
Comment 1 by Snakeman555 http://masters-of-the-void.com/book4.htm#comment1 http://masters-of-the-void.com/book4.htm#comment1 I am having some problems
first here is my code:
#include <stdio.h>
#include <stdbool.h>
int GetArgument( bool isLeft )
{
int vNum;

if( isLeft )
printf( "Enter first number: ");
else
printf( "Enter second number: ");
scanf( "%d" , &vNum );
fpurge( stdin );

return vNum;
}
int main()
{
int vFirstArg,
vSecondArg;
char vOperation;
bool vFinished;

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

//Now loop until our flag is initialized!
while( vFinished != true )
{
printf( "What operation do you want to do?(+,-,*,/)\n" );
scanf( "%c" , &vOperation );
fpurge( stdin );

if( vOperation == '+' )
{
vFirstArg = GetArgument(true);

vFirstArg = GetArgument(false);

printf( "\n%d + %d = %d\n" ,
vFirstArg,
vSecondArg,
vFirstArg + vSecondArg );
}
else
{
if( vOperation == '-' )
{
vFirstArg = GetArgument(true);

vFirstArg = GetArgument(false);

printf( "\n%d - %d = %d\n" ,
vFirstArg,
vSecondArg,
vFirstArg - vSecondArg );
}
else
{
if( vOperation == '*' )
{
vFirstArg = GetArgument(true);

vFirstArg = GetArgument(false);

printf( "\n%d x %d = %d\n" ,
vFirstArg,
vSecondArg,
vFirstArg * vSecondArg );
}
else
{
if(vOperation == '/' )
{
vFirstArg = GetArgument(true);

vFirstArg = GetArgument(false);
if(vSecondArg == 0)
{
printf("You can't divide by zero stupid!\n");
}
else printf( "\n%d / %d = %d\n" ,
vFirstArg,
vSecondArg,
vFirstArg / vSecondArg );
}

else vFinished = true;
}
}
}
}
printf( "Finished.\n" );

return 0;
}

and this is what it is doing

What operation do you want to do?
-
Enter first number: 7
Enter second number: 5

5 - -1881139893 = 1881139898



What operation do you want to do?
+
Enter first number: 9
Enter second number: 9

9 + -1881139893 = -1881139884
What operation do you want to do?