Is there different between if & else and switch & case?

Status
Not open for further replies.

foxbrain

Full Member level 2
hi:
i'm programming a simple program on atmega 16L:
PORTB is connected to 7 segment and PORTA to bottoms......
the code is :
#include <util/delay.h>
#include <avr/io.h>

int main()
{
DDRC=0xFF;
DDRA=0x00;
DDRB=0xFF;

PORTB=0xFF;
PORTA=0xFF;

uint8_t num;
for(;
{
CLEARBIT(PORTC,2);
PORTB=0XFF;
num=0xFF;
num &=PINA;

switch (num)
{

case 0b11011111:
PORTB &=~0b10111100;
asm("NOP");
_delay_ms(100);
case 0b11101111:
PORTB &=~0b10110110;
asm("NOP");
_delay_ms(100);
case 0b11110111:
PORTB &=~0b11010010;
asm("NOP");
_delay_ms(100);
case 0b11111011:
PORTB &=~(0b11100110);
asm("NOP");
_delay_ms(100);
case 0b11111101:
PORTB &=~0b11101110;
asm("NOP");
_delay_ms(100);
case 0b11111110:
PORTB &=~0b00110010;
asm("NOP");
_delay_ms(100);
case 0b00111111:
PORTB &=~0b11111110;
asm("NOP");
_delay_ms(100);
case 0b01011111:
PORTB &=~0b11110110;
asm("NOP");
_delay_ms(100);
case 0b11111111:
PORTB &=0b11111111;
asm("NOP");
_delay_ms(100);
}

if (num==0b01111111)
{PORTB &=~(0b01111110);
SETBIT(PORTC,2);
asm("NOP");
_delay_ms(100);}
else if(num==0b10111111)
{PORTB &=~0b00010010;
asm("NOP");
_delay_ms(100);}
else {PORTB &=0b11111111;
asm("NOP");
_delay_ms(100);}

}
return 0;
}

when a make the case of num == 0b01111111 or 0b10111111 or 0b11111111 (in if & else command) everything seems going good.
but when i make the any other case (in switch & case command) i'm not sure what it makes on the output of the 7 segment because it's to short but when i want to press any other bottom the atmega seems it stopped working or finished working (it doesn't respond for anything).....
so what's wrong with that??????
is there different between if & else and switch & case ???

alexan_e

The switch/case statement is used to execute a statement selected by the value of an expression.
The default case is optional, it allows statements to be executed where there are no matching constants.

Code C - [expand]1
2
3
4
5
6
7
8
9
10
11
12
13
14
switch (expression)
{
case const1:
statement1;
statement2;
break;
case const2:
statement3;
statement4;
break;
default:
statement5;
statement6;
}

the expression is evaluated and its value is compared against the constants.
Execution begins at the statement following the constant that matches the value of the expression.
ALL THE STATEMENTS FOLLOWING THE MATCHING CONSTANT WILL BE EXECUTED TO THE END OF THE CONSTRUCT, since this is normally not desirable, a break statement can be used at the end of each block to stop the “fall-through” and exit the switch construct.

Alex

andre_teprom

Super Moderator
Staff member
The switch/case statements compiled to assembly, may use pointer instructions ( lookup access ) while if/else statements must evaluate every expressions.

+++

alexan_e

He is asking because his code is not working when he uses switch/case, the cause of the problem is that he is not using break to exit the block so all the lines after the matching case are executed.

Alex

foxbrain

Full Member level 2
it didn't work but i think that if the code is OK so the wrong must be in te circuit ....i would like you to see the circuit that i attached it....
it should work like this : when i put 0v on portA,7 it should light the led + shows 0 on 7 segment.
when i put 0v on portA,6 it should turn off the led and shows 1 on the 7segment ......and so on.
note: portA i use a wire to connect it pins to 0v (ground)
and the 7segment is common anode.
i know that i may need to add some resistances before each 7segment pin but i think it's OK specially i'm using small voltage about 2.7v-3v (because I'm using atmega16L) but the same think is happening to the led....
thanks

Attachments

• 257.7 KB Views: 6

alexan_e

Your switch/case statement was missing the break but it was also different compared to your if/else

Code C - [expand]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (num==0b01111111)
{   PORTB &=~(0b01111110);
SETBIT(PORTC,2);
asm("NOP");
_delay_ms(100);
}
else if(num==0b10111111)
{   PORTB &=~0b00010010;
asm("NOP");
_delay_ms(100);
}
else {
PORTB &=0b11111111;
asm("NOP");
_delay_ms(100);
}

so the switch/case to do the same thing should be

Code C - [expand]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
switch (num)
{
case 0b01111111:            // check for this
PORTB &=~(0b01111110);
asm("NOP");
_delay_ms(100);
break;
case 0b10111111:            // check for this
PORTB &=~0b00010010;
asm("NOP");
_delay_ms(100);
break;
default:            // or apply this if not any of the above case
PORTB &=0b11111111;
asm("NOP");
_delay_ms(100);
}

Alex

Last edited:

andre_teprom

Super Moderator
Staff member
foxbrain,

The point that alexan_e warned you, is a common programming error.
Really, the break statementis is missing, and without it all others following case items will be executed.

+++

alexan_e

Actually I forgot to add the break in my code above oops and I had also used switch statement twice, now the code is correct

Alex

foxbrain

Full Member level 2
i made what you have told me to do (just to add "break;" in every case) , but nothing have worked.
i put in the code on the switch case function but nothing appears on the 7segment in any bottom is pressed

andre_teprom

Super Moderator
Staff member
...The point that alexan_e warned you, is a common programming error...
It just fortify the statement...

...I forgot to add the break in my code above...
:grin:

alexan_e

i made what you have told me to do (just to add "break;" in every case) , but nothing have worked.
I put in the code on the switch case function but nothing appears on the 7segment in any bottom is pressed
I didn't check the functionality of your code but you said that the if/else was working fine,
when a make the case of num == 0b01111111 or 0b10111111 or 0b11111111 (in if & else command) everything seems going good.
In that case the switch/case of post #6 (the edited version with break) does exactly the same thing as the if/else (the if/else is a copy of your original code).
They either work (both) or they are both wrong.

Alex

foxbrain

Full Member level 2
I think i got it ....it's like this:
switch case as you told me it is like if (statement ) { } then if (the same statement) {} and so on.
when we use break in either (if) or (switch) it goes out of the for(; the infinite loop.

alexan_e

It can't be used in a if/else statement.

break is used to exit a for, while, do/while, or switch/case statement, if the statements are nested one inside the other, the break will exit only from the immediate block of statements.

continue allow the program to start the next iteration of a while, do/while, for loop. It stops the execution of the loop at that point and it starts the loop again from the top .

Alex

foxbrain

foxbrain

points: 2

foxbrain

Full Member level 2
it worked with some changes on the code.
and i used break; (that's right).....
thanks

kapilddit

Junior Member level 1
It is common mistake to forgot to write the break in switch statement....
if you forgot to write break statement then It will continue to go on executing the next statement of of other case also...
So it will cause the problem....

kapilddit

foxbrain

Full Member level 2
i thought i doesn't need break as in if else.....

Status
Not open for further replies.