I came across this puzzle here. I can't figure out why NONE is not printed. Any ideas?
#include<stdio.h>
int main()
{
int a=10;
switch(a)
{
case '1':
printf("ONE\n");
break;
case '2':
printf("TWO\n");
break;
defa1ut:
printf("NONE\n");
}
return 0;
}
defa1ut: is a syntactically valid label, e.g. for a goto but not the default of the switch statement.
If you compile with gcc with enough warnings it will point this out:
ajw#rapunzel:/tmp > gcc -Wall -Wextra test.c
test.c: In function ‘main’: test.c:13:15: warning: label ‘defa1ut’
defined but not used
It's a good argument for building with warnings cranked up high and aiming for 0 warnings in every build.
If defa1ut is a typo for default and the string "NONE" is printed:
This is because '1' and 1 is different.
'1' means the ASCII value of the character '1' whose value in decimal is 49. and 1 is an integer.
The first case will be true if the value of a is 49 or '1' , but as a=10 so it is neither equal to '1' nor equals to '2' and thus default is executed (if it existed, and defa1ut is not a typo).
If defa1ut is not a typo for default and simply nothing is printed:
In this case you have no default instead which look like it is defa1ut which will act as a normal label, so simply nothing will be printed.
default is spelled wrong. and so that case is never reached.
http://codepad.org/gQPA6p4s
#include<stdio.h>
int main()
{
int a=10;
switch(a)
{
case '1':
printf("ONE\n");
break;
case '2':
printf("TWO\n");
break;
defalut:
printf("NONE\n");
mickey_mouse:
printf("No Mickey\n");
default :
printf("CORRECT DEFAULT\n");
}
return 0;
}
Since defa1ut is not keyword, it should be addressed with a case statement.
Why do you think it should be printed?
defa1ut is different from default
Related
Yesterday I saw the below code. As you can see it hasn't got any break I predicted that it would print "354" because I thought the default part would be finally evaluated (after checking all the cases.)
But that isn't practically correct as it printed "345". Can somebody explain the reason?
int main ()
{
int a = 2;
switch (2*a-1)
{
case 1: printf ("1");
case 2: printf("2");
case 3: printf("3");
default: printf("4");
case 5: printf("5");
}
}
Since 2*a-1 is 3, the code jumped to the case 3 label and kept running from there. The other labels were ignored because no code ever jumped to them. The default label is only jumped to if the value in the switch doesn't match any of the case labels.
I have an exercise asks me to correct the syntactic error, I tried to correct but every time I want to compile it shows me an error in the for loop.
(the exercise allows for counting and displays the number of vowel letters in a sentence entered by the user, the user indicates the end of the entry by typing '*')
#include <stdio.h>
main(){
char c;
char TV[5];
int k;
for (k = 0; k < 5; k++)
{
TV[k]=0;
}
printf("Entrer un texte. Tapez le caractére * pour sortire. \n");
c = getchar();
while(c!='*')
{
switch (c) {
case 'A': TV[0]++;
case 'a': TV[0]++;
case 'E': TV[1]++;
case 'e': TV[1]++;
case 'I': TV[2]++;
case 'i': TV[2]++;
case 'O': TV[3]++;
case 'o': TV[3]++;
case 'U': TV[4]++;
case 'u': TV[4]++;
default: c = getchar();
}
}
printf("a \t e \t i \t o \t u \n");
for(k=0;k<5;k++)
{
printf("%d \t",TV[k]);
}
}
error message:
mariem#MIGI:~/Bureau/syt_exp$ gcc Tp6-lesChaines-Exercice1.c
Tp6-Channels-Exercise1.c:2:1: warning: return type defaults to ‘int’ [-Wreturn-type]
main(){
^~~~
mariem#MIGI:~/Bureau/syt_exp$ ./Tp6-lesChaines-Exercice1.c
./Tp6-Channels-Exercise1.c: line 6: syntax error near the unexpected symbol "("
./Tp6-Channels-Exercise1.c: line 6: `for (k = 0; k <5; k ++) '
I think it's better now.
I don't see a syntax error. And I can't copy the code to check with my compiler. However:
main should be declared as
int main(int argc, char **argv)
Your loop: while (c=='*')?? You mean while (c!='*').
And: a case should be terminated with a break;, otherwise execution just continues.
Why you don't have declarated type of main()?
int main()
You are trying to execute the C source file directly in the shell, as if it was a shell script. C needs to be compiled, and then you execute the file created by the compiler.
The default name for this that GCC produces is a.out, so execute it with ./a.out
A couple things...
1- to fix the warning - main(){ should be int main(){ OR even void main(){ works, but return type int is the most standard here. input parameters are optional - i.e. argv/argc.
2- after compilation (which you are doing correctly), without specifying an executable name, the default .exe produced by the compiler is either a.out or a.exe. to run, type ./a.exe on the command line.
Note - by doing those 2 things, I have confirmed that the program runs.
#include<stdio.h>
int main()
{
switch(2)
{
case 1:
if(1)
{
case 2:
printf("hello\n");
};
}
return 0;
}
OUTPUT = hello
as I'm passing 2 in switch
case 1 is not true then also it enters it and executes code inside case 2.
How come it enters case 1?
Thanks.
After switch(2), it will jump immediately to the case 2 label. The fact that it is within an if block contained within case 1 is irrelevant. case 2: effectively functions no differently from a goto label, so it will jump to it wherever it is. It is not true that case 1 is somehow being entered.
To clarify, properly indented it looks thus:
#include<stdio.h>
int main() {
switch(2) {
case 1:
if(1) {
case 2:
printf("hello\n");
}
;
}
return 0;
}
how come it enters case 1 ?
It doesn't enter the case 1. In fact if(1) has no use here. The above code is equivalent to
#include<stdio.h>
int main()
{
switch(2)
{
case 1:
case 2: printf("hello\n");
}
return 0;
}
To see the irrelevant use of if you can replace if(1) with if(0) and you will find that result will be the same.
I want the code below to print ok when user enters 1 or 3, or to print why otherwise.
Why, when user enters 3, the program prints why?
#include <stdio.h>
#include <conio.h>
int main(void){
int i;
clrscr();
scanf("%d", &i);
switch(i){
case (1||3):
printf("ok\n");
break;
default:
printf("why\n");
}
getch();
return 0;
}
case(1||3):
Will not work. If you want to say "1 or 3", write:
case 1 :
case 3 :
printf("ok");
break;
If you don't have break between cases, they flow from one into the next. Try it in the debugger.
Expression
1||3
has constant value 1. Operator || is the logical OR operator that according to the C Standard
3 The || operator shall yield 1 if either of its operands compare
unequal to 0; otherwise, it yields 0. The result has type int.
So if you enter 1 then code under the case label will be executed. Otherwise the code under the default label is executed.
In fact your switch statement looks like
switch(i)
{
case 1:
printf("ok");
break;
default:
printf("why");
}
Expression 1 || 3 will be calculated at compilation time and the compiler will generate code that will correspond to the label
case 1:
All case label expressions are evaluated at compilation time and instead of the expressions the compiler uses their results.
To achive the result you want you should either add one more case label or substitute the switch statement for a if-else statement. For example
switch(i)
{
case 1:
case 3:
printf("ok");
break;
default:
printf("why");
}
or
if( i == 1 || i == 3 )
{
printf("ok");
}
else
{
printf("why");
}
You want to learn the following paradigm for flow control:
switch(i)
{
case (1):
case (3):
printf("ok");
break;
default:
printf("why");
}
Where either 1 or 3 will fall through until the break.
1||3 => true... which is typically 0x1
Yet another solution:
printf( (i==1||i==3)?"ok":"why" );
I was trying this :
#include<stdio.h>
int main() {
int i = 2;
switch(i) {
default:{
printf("Hi\n");}
case 1:
printf("Hi1\n");
case 2:
printf("Hi2\n");
}
}
output is "Hi2" as expected, however if i = 3,
#include<stdio.h>
int main() {
int i = 3;
switch(i) {
default:{
printf("Hi\n");}
case 1:
printf("Hi1\n");
case 2:
printf("Hi2\n");
}
}
Output is
"Hi"
"Hi1"
"Hi2"
How does program enter other cases which do not match? I know putting break in default would solve this.
Why this behavior? Is there anything mentioned in C specification for this?
In C (and many other languages) the cases are simply labels that get 'jumped' to. Once execution starts in a selected case, it flows just like normal. If you want execution to 'stop' at the end of a case 'block' you have to use the break statement (or some other flow control statement):
switch(i) {
default:{
printf("Hi\n");}
break;
case 1:
printf("Hi1\n");
break;
case 2:
printf("Hi2\n");
break;
}
}
For whatever it's worth, in my opinion this is was an unfortunate decision made by the language designers since falling through to the next case after execution one or more statements in a case are executed is very, very rarely desired. However, that's the way the language works.
C# addresses this by making it so falling out of a case is illegal - some sort of explicit flow control (a break or a goto) is required at the end of a sequence of of statements in a case (unless it's the last case in the switch).
This is because the code steps through each instruction unless explicitly stated not to.
In a switch() { }, you must be explicit.
Think about the instructions backed by this C. It would be a jump table. Without break, there would be no jump beneath each branch to go after the switch case.
Complementing #alex, try this.
#include<stdio.h>
int main() {
int i = 2;
switch(i) {
default:{
printf("Hi\n");}
case 2:
printf("Hi2\n");
case 1:
printf("Hi1\n");
}
}