#i confuse about it
31 messages · Page 1 of 1 (latest)
When your question is answered use !solved to mark the question as resolved.
Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.
In C language, if and switch statements are used to control program flow based on certain conditions.
A switch() is like a chained sequence of if()..else.
You can only compare between the same integer variable and compile-time constant values.
Example:
#define red 0xff0000;
#define green 0x00ff00;
#define blue 0x0000ff;
switch (color)
{
case red:
// code handling red here
break;
case green:
// code handling green here
break;
case blue:
// code handling red here
break;
}
You cannot use switch() to compare two variables
int var1 = calcV1();
int var2 = calcV2();
switch (var1)
{
case var2: // compiler error, var2 not a compile-time constant
...
}
Nor can you use switch() for non-integer comparisons
char input[100];
fgets(input, 100, stdin);
switch (input)
{
case "add": // compiler error, comparing non-integer values
break;
}
When you cannot use switch() then you should just fall back to repeated if()...else.
And even with if()..else you cannot directly compare strings. You should combine if() with strcmp() or variant functions.
"nor can you use switch for non-integer comparisons"
are you sure 🤔
;compile
#include <stdio.h>
int main()
{
char c = 'a';
switch (c)
{
case 'a':
printf("Hello World!");
break;
default:
break;
}
return 0;
}
Hello World!
;compile
#include <stdio.h>
int main()
{
char c = 'b';
switch (c)
{
case 'a':
printf("Hello World!");
break;
default:
break;
}
return 0;
}
No output.
🤷♂️
A character is an integer type.
It ranges from -128 to 127 or from 0 to 255 if unsigned.
sure i guess but telling a beginner you cant use switch with non-integers sounds a lot like saying they cant do it with anything other than an int
im certain the OP doesnt know the meaning of what you just said
but fair enough
p.s. cant switch array of chars but you can still use switch to process it by switching chars inside a loop
;compile
#include <stdio.h>
int main() {
char* s = "switch";
for (int i = 0; s[i] != '\0'; i++) {
switch (s[i]) {
case 's':
printf("s\n");
break;
case 'w':
printf("w\n");
break;
case 'i':
printf("i\n");
break;
case 't':
printf("t\n");
break;
case 'c':
printf("c\n");
break;
case 'h':
printf("h\n");
break;
default:
break;
}
}
return 0;
}
s
w
i
t
c
h
... another thing of note is that switch statements do not exist to make an if-else tree syntactically nicer.
it does not achieve that. In fact it's much worse. A lot of C++ tutorials frame switches this way. "Oh look it's shorter and neater." No, it is not shorter, it is not neater. That isn't why it's there.
the reason switch statements exist is basically because..,... they're a lightweight abstraction from a common construct in machine language called a jump table, which basically let you choose which code to run without even checking the conditions. (huge speedup)
so if you have like ```c
switch(a)
{
case 1:
code block a
case 2:
code block b
case 3:
code block c
}
.... then its probably going to create a table in memory like.... ```
table = [
[address of code block a],
[address of code block b],
[address of code block c]
]
and then what its going to do is basically get the correct address for a at table[a-1]
and jump to it and start executing code from there. So... it can choose the correct code to run without evaluating each case as in an if-else tree.
;asm ```c
#include <stdio.h>
int main(void)
{
int c = getchar();
switch(c)
{
case 'a':
printf("It's a\n");
break;
case 'b':
printf("It's b\n");
break;
case 'c':
printf("It's c\n");
break;
case 'd':
printf("It's d\n");
break;
case 'e':
printf("It's e\n");
break;
case 'f':
printf("It's f\n");
break;
case 'g':
printf("It's g\n");
break;
default:
printf("Uh oh D:\n");
}
return 0;
}
.LC0:
.string "It's a"
.LC1:
.string "It's b"
.LC2:
.string "It's c"
.LC3:
.string "It's d"
.LC4:
.string "It's e"
.LC5:
.string "It's f"
.LC6:
.string "It's g"
.LC7:
.string "Uh oh D:"
main:
push rbp
mov rbp, rsp
sub rsp, 16
call getchar
mov DWORD PTR [rbp-4], eax
mov eax, DWORD PTR [rbp-4]
sub eax, 97
cmp eax, 6
ja .L2
mov eax, eax
mov rax, QWORD PTR .L4[0+rax*8]
jmp rax
.L4:
.quad .L10
.quad .L9
.quad .L8
.quad .L7
.quad .L6
.quad .L5
.quad .L3
.L10:
mov edi, OFFSET FLAT:.LC0
call puts
jmp .L11
.L9:
mov edi, OFFSET FLAT:.LC1
call puts
jmp .L11
.L8:
mov edi, OFFSET FLAT:.LC2
call puts
jmp .L11
.L7:
mov edi, OFFSET FLAT:.LC3
call puts
jmp .L11
.L6:
mov edi, OFFSET FLAT:.LC4
call puts
jmp .L11
.L5:
mov edi, OFFSET FLAT:.LC5
call puts
jmp .L11
.L3:
mov edi, OFFSET FLAT:.LC6
call puts
jmp .L11
.L2:
mov edi, OFFSET FLAT:.LC7
call puts
.L11:
mov eax, 0
leave
ret
.L4:
.quad .L10
.quad .L9
.quad .L8
.quad .L7
.quad .L6
.quad .L5
.quad .L3
this is the "jump table" i was talking about
from sub eax, 97 and mov rax, QWORD PTR .L4[0+rax*8] and jmp rax ..... we can see that its basically converting the entered char into an offset, converting the offset into an actual address using the jump table, and then jumping to the address.