1. ## Switch-case working

Hello gentle folks,
I almost tried to look for the answer in my books and in some other treads here but there's nothing about my little mind trick...
I need to create a simple calculator with switch construct.
No problems for that

Code:
```#include <stdio.h>
#include <stdlib.h>

int main()
{
int op;
int a, b, c;
int err;

printf("Simple calculator\n");

printf("Insert 1 to sum\n");
printf("Insert 2 to subtracte\n");
printf("Insert 3 to moltiplicate\n");
printf("Insert 4 to divide\n");

scanf("%d", &op);
printf("First operand : \n");
scanf("%d", &a);
printf("Second operand: \n");
scanf("%d", &b);

/*Initializing error condition*/
err = 0;
/*Execute requested operation*/
switch( op )
{
case 1:
c = a + b;
break;
case 2:
c = a - b;
break;
case 3:
c = a * b;
break;
case 4:
if( b == 0 )
{
printf("Can't  be divided for 0!\n");
err = 1;
}
else
{
c = a / b;
}
break;
default:
printf("Error\n");
err = 1;
}

if( err == 0 )
printf("Result value: %d\n", c);
exit(0);
}```
This works perfectly,
My question is: when i go to terminal and execute this, if I type 1,2,3,4 i get no error and i select sum,multiplication ecc... ; but if I type 0, 5, 6, 7, -7634762 or 589627962166 it's the same because the program follows the "flow" and asks me operands,saying me "insert first and second operand.Can I stop that to the point before it asks me "insert operands"?

2. Sure, you just need your switch before you ask for the operand values.
Code:
```    switch( op )
{
case 1:
getOperands(&a,&b);
c = a + b;
break;```

3. Thank you,
Should I use "getOperands(&a,&b);" even in default case?
I think...Is this a special function like "fgetpos" or something else?
And by the way..why do I find, with recurrence, additional functions not explained anywhere?
I may understand the rare usage or similar causes, but it's important anyways...like the usage of macros, I think...

4. > Should I use "getOperands(&a,&b);" even in default case?
That would seem unnecessary to me.

> I think...Is this a special function like "fgetpos" or something else?
No, it's something you would have to write for yourself.
It's just your two printf/scanf calls wrapped in a nice little function you can re-use.

5. I tried as you said and even in different ways...I can't compile the code because compiler says it is undefined,and that's how it is...
I think books should explain this mechanisms...They just put students at the bottom of the barrel leaving holes in some arguments
Right now i can't define this, later I won't be able to define something else or some new sort of thing will appear...

6. You need to study more.
Code:
```void getOperands(int *a, int *b) {
printf("First operand : \n");
scanf("%d", a);
printf("Second operand: \n");
scanf("%d", b);
}```
Post your actual code and actual error messages when you're stuck.

"I tried .... and got an error of some sort" doesn't allow us to help you.

7. I'm sorry for not being precise before.
On the way I didn't even know that i could use a void function with pointers inside the main() one.
I mean,there are so many cases that books should illustrate more...
I changed code to this
Code:
```#include <stdio.h>
#include <stdlib.h>

int main()
{
int op;
float a, b, c;
int err;

printf("Semplice Calcolatrice\n");

printf("Inserisci 1 per la somma\n");
printf("Inserisci 2 per la sottrazione\n");
printf("Inserisci 3 per la moltiplicazione\n");
printf("Inserisci 4 per la divisione\n");

printf("La tua scelta: \n");
scanf("%d", &op);

void getOperands(float *a, float *b)
{
printf("Immetti il primo operando: \n");
scanf("%f", a);
printf("Inserisci il secondo operando: \n");
scanf("%f", b);
}
/*La condizione di errore viene inizializzata*/
err = 0;
/*Esegui l'operazione richiesta*/
switch( op )
{
case 1:
getOperands( &a, &b);
c = a + b;
break;
case 2:
getOperands( &a, &b);
c = a - b;
break;
case 3:
getOperands( &a, &b);
c = a * b;
break;
case 4:
getOperands( &a, &b);
if( b == 0 )
{
printf("Impossibile dividere per zero!\n");
err = 1;
}
else
{
getOperands(&a,&b);
c = a / b;
}
break;
default:
printf("Operazione errata\n");
err = 1;
}

if( err == 0 )
printf("Il risultato vale: %f\n", c);
exit(0);
}```
Before changing to floats i tried with integers and program works perfectly,so thank you.
But I guessed what would happen if i tried with floats.
I tried but i think I'm mistaking something I don't know about.
Why the program ends?

8. Code:
```    void getOperands(float *a, float *b)
{
printf("Immetti il primo operando: \n");
scanf("%f", a);
printf("Inserisci il secondo operando: \n");
scanf("%f", b);
}```
C doesn't support nested functions.
Move this so it's above main()

> On the way I didn't even know that i could use a void function with pointers inside the main() one.
I think you need better reference material then.

> I mean,there are so many cases that books should illustrate more...
If books explained every single permutation possible, they would be 1000's of pages long and nobody would read them.
You have to understand general concepts, then figure out how to apply that knowledge to specific problems.

Also, delete line 54 - you already got (and validated) the a and b values.

> I tried but i think I'm mistaking something I don't know about.
Well looking at your screen shot, you typed in "7,4".
Your scanf calls as they stand need the values to be separated by white space (spaces, tabs, newlines).

9. >I typed 7,4
I tried with 7.4 (i tried to use dot) and it works.

>Move this so it's above main()
I'd like to understand the reason...Are you saying this is better for compiler?

> I think you need better reference material then. / If books explained every single permutation possible, they would be 1000's of pages long and nobody would read them.

I understand general concepts, but according to what you say Medicine or Law or other arguments should be all general? So why do I buy books if I can't read about specific parts?
My reference material is C book in my motherlanguage made by a university teacher...I even have K&R and when everyone says it's a sacred book...well I don't think so when i can't find (important) specific argument.
Time ago I had a problem with Array lenght..I looked so hard everywhere for that mystical "ARRLEN" and books didn't explain what that was...
I understand what you say...but I think i miss explanations to understand the step between general concepts and specific problems. At least in C language. I think I'll be confident when I understand the "range" of C language, I mean what I can do more and understand from a general concept moving to specific problems

10. > I'd like to understand the reason...Are you saying this is better for compiler?
No, I'm saying that's because what the C standard says you must do.
Some languages allow nested function declarations, C does not.
GCC (for reasons known only to GCC developers) allows nested functions, but you're going to be SoL when using another compiler.

gcc -Wall -std=c99 prog.c
Is a good start to making GCC warn about all sorts of potential issues, and not dragging in all the "enhancements" which would mean your code would not compile on another compiler.

> I've never read getOperands anywhere...
That's because I just made the name up on the spot when I replied to your post!
Specifically, I was trying to give you a meaningful name to describe what the function does.

Would you be more or less happy if I'd written
Code:
```void foo(float *a, float *b)
{
printf("Immetti il primo operando: \n");
scanf("%f", a);
printf("Inserisci il secondo operando: \n");
scanf("%f", b);
}```

> >I typed 7,4
> I tried with 7.4 (i tried to use dot) and it works.
That's all down to the locale.
The standard "C" locale is "English" in nature. You can alter this in your programs, but it involves doing several more things which are not the natural first programming steps.

11. >Some languages allow nested function declarations, C does not.
Ok now I understand..As normally we have to declare functions before main(),but I went in confusion just because when you first suggested me,I thought that I had to declare that function before.
So overall I just created a function for my purpose and I'm gonna recall this void-pointers function on every switch case, right?

Last question...I executed my "updated" program
Code:
```#include <stdio.h>
#include <stdlib.h>
void getOperands(float *a, float *b)
{
printf("Immetti il primo operando: \n");
scanf("%f", a);
printf("Inserisci il secondo operando: \n");
scanf("%f", b);
}
int main()
{
int op;
float a, b, c;
int err;

printf("Semplice Calcolatrice\n");

printf("Inserisci 1 per la somma\n");
printf("Inserisci 2 per la sottrazione\n");
printf("Inserisci 3 per la moltiplicazione\n");
printf("Inserisci 4 per la divisione\n");

printf("La tua scelta: \n");
scanf("%d", &op);

/*La condizione di errore viene inizializzata*/
err = 0;
/*Esegui l'operazione richiesta*/
switch( op )
{
case 1:
getOperands( &a, &b);
c = a + b;
break;
case 2:
getOperands( &a, &b);
c = a - b;
break;
case 3:
getOperands( &a, &b);
c = a * b;
break;
case 4:
getOperands( &a, &b);
if( b == 0 )
{
printf("Impossibile dividere per zero!\n");
err = 1;
}
else
{
c = a / b;
}
break;
default:
printf("Operazione errata\n");
err = 1;
}

if( err == 0 )
printf("Il risultato vale: %f\n", c);
exit(0);
}```
How can be possible that "Insert 1 to sum" comes before of "Insert first operand"?

12. > How can be possible that "Insert 1 to sum" comes before of "Insert first operand"?
Huh?

Because that's the order in which the printf() statements are written in your code.

13. I guess that's because main() has the priority, right?

14. You have to understand that the order of functions in your source file makes absolutely NO difference to what happens when you run the code.

The program always starts at main(), and from that point you can follow how the execution of the program would proceed by reading each line of main(). That's why your first six printf's happen first, in the order you wrote them in. At some point, getOperands() is called, and when that returns, main carries on from where it left off.

Also, the order of functions in your source makes almost no practical difference to the compiler. In fact, putting main last is a somewhat lazy approach while you have the benefit of being able to write a small program in a single source file. Larger projects have 10's, 100's or 1000's of source files, but they all begin somewhere with a single main() function.

For example, these two programs would compile the same.
Code:
```#include <stdio.h>
#include <stdlib.h>
void getOperands(float *a, float *b)
{
printf("Immetti il primo operando: \n");
scanf("%f", a);
printf("Inserisci il secondo operando: \n");
scanf("%f", b);
}
int main()
{
int op;
float a, b, c;
int err;

printf("Semplice Calcolatrice\n");

printf("Inserisci 1 per la somma\n");
printf("Inserisci 2 per la sottrazione\n");
printf("Inserisci 3 per la moltiplicazione\n");
printf("Inserisci 4 per la divisione\n");

printf("La tua scelta: \n");
scanf("%d", &op);

/*La condizione di errore viene inizializzata*/
err = 0;
/*Esegui l'operazione richiesta*/
switch( op )
{
case 1:
getOperands( &a, &b);
c = a + b;
break;
case 2:
getOperands( &a, &b);
c = a - b;
break;
case 3:
getOperands( &a, &b);
c = a * b;
break;
case 4:
getOperands( &a, &b);
if( b == 0 )
{
printf("Impossibile dividere per zero!\n");
err = 1;
}
else
{
c = a / b;
}
break;
default:
printf("Operazione errata\n");
err = 1;
}

if( err == 0 )
printf("Il risultato vale: %f\n", c);
exit(0);
}```
vs.
Code:
```#include <stdio.h>
#include <stdlib.h>

// This is a function prototype.
// It's purpose is to inform the compiler that the function
// getOperands() will exist at some point in the future,
// either later in this file, or perhaps some other file.
// Regardless of where it is, the compiler has enough
// information to allow you to make calls to this function
// within main(), or indeed any other function following in
// this source file.
void getOperands(float *a, float *b);

int main()
{
int op;
float a, b, c;
int err;

printf("Semplice Calcolatrice\n");

printf("Inserisci 1 per la somma\n");
printf("Inserisci 2 per la sottrazione\n");
printf("Inserisci 3 per la moltiplicazione\n");
printf("Inserisci 4 per la divisione\n");

printf("La tua scelta: \n");
scanf("%d", &op);

/*La condizione di errore viene inizializzata*/
err = 0;
/*Esegui l'operazione richiesta*/
switch( op )
{
case 1:
getOperands( &a, &b);
c = a + b;
break;
case 2:
getOperands( &a, &b);
c = a - b;
break;
case 3:
getOperands( &a, &b);
c = a * b;
break;
case 4:
getOperands( &a, &b);
if( b == 0 )
{
printf("Impossibile dividere per zero!\n");
err = 1;
}
else
{
c = a / b;
}
break;
default:
printf("Operazione errata\n");
err = 1;
}

if( err == 0 )
printf("Il risultato vale: %f\n", c);
exit(0);
}

void getOperands(float *a, float *b)
{
printf("Immetti il primo operando: \n");
scanf("%f", a);
printf("Inserisci il secondo operando: \n");
scanf("%f", b);
}```