If "car" or "ferrari" as an input, it should print "car or ferrari". How can I achieve it?
<?php
$car ='333';
switch($car)
{
case car OR ferrari:
print("car or ferrari");
break;
case cat:
print("cat");
break;
default:
print("default");
break;
}
?>
Use two case clauses:
case 'car':
case 'ferrari':
print("car or ferrari");
break;
The explanation:
It is important to understand how the switch statement is executed in order to avoid mistakes. The switch statement executes line by line (actually, statement by statement). In the beginning, no code is executed. Only when a case statement is found with a value that matches the value of the switch expression does PHP begin to execute the statements. PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement. If you don't write a break statement at the end of a case's statement list, PHP will go on executing the statements of the following case.
You can simply "fall through" the cases you want to handle equally:
<?php
$auto ='333';
switch($auto)
{
case car:
case ferrari:
print("car or ferrari");
break;
case kissa:
print("cat");
break;
default:
print("default");
break;
}
switch($car)
{
case car:
case ferrari:
print("car or ferrari");
break;
case cat:
print("cat");
break;
default:
print("default");
break;
}
Cases "fall through" until the first break statement. This also means that you don't need a break in the default case.
switch($car) {
case 'car':
case 'ferrari':
print("car or ferrari");
break;
case 'cat':
print("cat");
break;
default:
print("default");
break;
}
This is taking advantage of the 'fall-through' property of the switch() statement. Basically, a section doesn't stop at a case, it stops at a break (or other operation that exits the function).
I've taken the liberty of applying the indentation I prefer for switches, which makes them only use up one indent level, which I consider appropriate because, logically, the switch and its cases are all elements of the same construct. So using two indent levels within the switch conveys no useful information.
I dont' know if PHP supports this but in C, you could do something like this:
case car:
case ferrari:
print("car or ferrari");
break;
The idea is that code for handling the car case will keep running until it hits a break statement. As for style, it should be avoided.
Related
I am learning PHP. I have downloaded an open source project from a website and looking the workflow of each modules in that project. I noticed a switch case which is unfamiliar to me.
switch ($value) {
case 'student':
case StudentClass::getInstance()->getId();
return new StudentClass();
break;
case 'teacher':
case TeacherClass::getInstance()->getId();
return new TeacherClass();
break;
default:
break;
}
The above patch is what I looked.
When I give input:
$value = 'student';
It returns StudentClass instance.
If I give
$value = 'teacher';
then it returns TeacherClass instance.
If anyone explain the flow, it will be helpful to me to understanding PHP much better
Your string cases don't have break or return statements, so they "fall through" to the next case. Also, your breaks don't serve any purpose here.
I've added comments to your code to explain what's happening.
switch ($value) {
case 'student': // keeps going with next line
case StudentClass::getInstance()->getId();
return new StudentClass(); // handles both cases above
break; // unnecessary because of the return above
case 'teacher': // keeps going with next line
case TeacherClass::getInstance()->getId();
return new TeacherClass(); // handles both cases above
break; // unnecessary because of the return above
default:
break; // pointless, but handles anything not already handled
}
Also, PHP explicitly allows use of a semicolon (;) after a case, but it is not generally considered good style. From the docs:
It's possible to use a semicolon instead of a colon after a case...
Switch statement is used to perform different actions based on different conditions.
First we have a single expression n (most often a variable), that is evaluated once. The value of the expression is then compared with the values for each case in the structure. If there is a match, the block of code associated with that case is executed. Use break to prevent the code from running into the next case automatically. The default statement is used if no match is found.
switch (n) {
case label1:
code to be executed if n=label1;
break; // if n=label1,break ends execution and exit from switch
case label2:
code to be executed if n=label2;
break; // if n=label2,break ends execution and exit from switch
case label3:
code to be executed if n=label3;
break; // if n=label3,break ends execution and exit from switch
...
default:
code to be executed if n is different from all labels;
}
What is the different between
switch (variable) {
case 'value':
# code...
break;
case 'value':
# code...
break;
}
and this one
switch (variable) {
case 'value':
# code...
continue;
case 'value':
# code...
continue;
}
It's really different result or just same?
This is a special case for PHP because, as stated by the official documentation:
Note: In PHP the switch statement is considered a looping structure
for the purposes of continue. continue behaves like break (when no
arguments are passed). If a switch is inside a loop, continue 2 will
continue with the next iteration of the outer loop.
So in essence it means there is no actual difference between your two examples. However for clarity I think it would be best to use break as that is the standard in other languages. Note also that you could use continue 2 (or 3, 4...) to advance to the next iteration of a loop if the switch is inside a loop (or more).
In PHP the above two codes work in same way. Here the break and continue statement prevent control going to next case. That is the continue acts just like break here. Also switch is intended to be executed only once. It's not a loop. Hence continue is not relevant here.
Note:If there is loop enclosing this switch statement then the result will be different.
Here is a simple example code with both the switch cases mentioned above
<?php
$variable = 20;
echo "Normal<br/>";
switch ($variable) {
case '20':
echo "twenty";
break;
case '21':
echo "twenty one";
break;
}
echo "<br/><br/>With Continue<br/>";
switch ($variable) {
case '20':
echo "twenty";
continue;
case '21':
echo "twenty one";
continue;
}
?>
When I execute above code I got following output
Normal
twenty
With Continue
twenty
How?
Working of break statement
Break statement causes code execution to come out of the block and execute next statements because of which switch statement will execute only one case statement and exit out of switch block without executing other case blocks.
Working of Continue statement
Continue statement in case of loops will cause loop to stop execution of current iteration of loop and go for next iteration of the loop(if any exists) but in case of switch statement it is considered as a loop statement but no next iterations causing exit switch statement.
We can have a switch statement without break statements too like this
<?php
$variable = 20;
echo "Normal";
switch ($variable) {
case '19':
echo "<br/>Nineteen";
case '20':
echo "<br/>twenty";
case '21':
echo "<br/>twenty one";
case '23':
echo "<br/>twenty three";
}
?>
The output of above code will be
Normal
twenty
twenty one
twenty three
i.e. executing all the case statements after the case where first match is found.
I've got and switch statements like this:
switch(x){
case a:
executeSth();
executeA();
break;
case b:
executeSth();
executeB();
break;
...
}
so executeSth(); should allways be executed except in default case but after it some case specific code is called (executeA(); or executeB() and so on). (So simply putting it in front of the switch doesn't work).
Is there an efficient way to reduce the number of "executeSth();" without sacrificing performance?
I could only imagine split it into two switches (one that executes the executeSth() in and one that executes the specific code) but that would sacrifice performance. Maybe you got better ideas?
I'm basicly interessed in code for c/c++ or php. My goal is to minimize code size and in case of c/c++ the size of the resulting executable.
Edit: Yes, the order of the functions matters.
Edit2: I don't have the choice between php or c++, I need it both to be as good as possible.
A nested switch is an option...
This uses two switches, but the second is not triggered in the default case so has a slightly better performance profile than just two in-line switches.
switch($x) {
case a: case b: case c:
executeSth();
switch($x) {
case a:
executeA();
break;
case b:
executeB();
break;
case c:
executeC();
break;
}
break;
default:
...
}
Alternatively, a variable function may do the job...
This is a PHP option which may work, though a lot of people don't like variable functions. This is probably the best option if you want to totally remove nesting & repetition.
switch($x) {
case a:
$function = "executeA";
break;
case b:
$function = "executeB";
break;
case c:
$function = "executeC";
break;
default:
...
}
if(isset($function)) {
executeSth();
$function();
}
I've also made a little live test bed here, if anyone wants to test their PHP solutions work before posting them (case 10 should executeSth() and executeA(), case 20 should executeSth() and executeB(), default should executeDefault()).
In C++, you can use a function pointer to achieve the same as the above
I had a total brain fart when I wrote this, thankfully idipous reminded me that we can do this with a simple function pointer.
// Declare function pointer
int (*functionCall)() = NULL;
// In switch statement, assign something to it
functionCall = &execute;
// After the switch statement, call it
int result = (*functionCall)();
Note: I'm out so haven't checked the syntax on these. The syntax I've used is C syntax and may require some small changes to work in C++.
What you could do (although it might not be the most readable solution) and that if you are using PHP 5.3 and above you could create a method like below:
function mymethod($funcToCall){
executeSth();
$funcToCall();
}
and have the swtich like below:
switch(x){
case a:
mymethod('executeA');
break;
case b:
mymethod('executeB');
break;
...
}
Unless there is really a huge amount of this sort of thing, I'd leave it as is.
One solution is of course to move the call of executeSth into the executeA defintion and executeB definitions - this is of course only meaningful if there are multiple places with similar code - if there aren't more than one place, you have moved two lines of code from one place to another place.
Another solution may be to pass the function executeA or executeB into executeSth as an argument. But it will just make things more complicated to read.
In general, I'd say "smaller code" is not necessarily "better code". The key is to make the code as clear as possible (whilst still achieving reasonable performance and code-size, of course).
In C++, I would additionally expect that if executeSth is small, that it gets inlined into the case-code. So there is no overhead difference between having one or two function calls.
Why don't you set a flag in your default case, and then, after the switch statement, execute the common function if the flag is not set (meaning that it's not the default case)? That sounds like a reasonable solution.
$flag = false;
switch(x){
case a:
executeA();
break;
case b:
executeB();
break;
default:
... // other stuff
$flag = true;
break;
}
if ( !$flag )
executeSth();
EDIT
I misinterpreted the question.
For the reverse order you can put the possible cases in a variable and then use something like in_array in PHP or strstr in C++ (not sure if there's a better native function):
if ( !in_array(x, cases) {
executeSth();
}
switch(x){
case a:
executeA();
break;
case b:
executeB();
break;
...
}
In code size speaking: it doesn't matter. Readability > codesize.
Perhaps you can write something like that for your executeSth():
if(!notDefault){
executeSth();
}
(C++) Let the preprocessor duplicate the code for you? (Dᴏɴ’ᴛ Uꜱᴇ Tʜɪꜱ ɪɴ Mᴀɪɴᴛᴀɪɴᴇᴅ Cᴏᴅᴇʙᴀꜱᴇ. It may hurt readability. I think the two-switch solution is fine.)
#define CASE(n) case n: printf("non-default\n"); _unused_label_##n
switch (x) {
CASE(1):
printf("case 1\n");
break;
CASE(2):
printf("case 2\n");
break;
default:
printf("case else\n");
break;
}
#undef CASE
I have a flag that when passed to a switch statement needs different logic applied to it, three of the cases apply the same logic apart from one of those cases (out of the three) has an extra step.
Is this syntactically correct?
switch($foo)
{
case 1:
//do something
break;
case 2:
//do step 1
case 3:
case 4:
//do step 2
break;
}
Yes, your code is syntactically correct and will do what you've said in the comments.
Is this good practise ... ie, grouping the default case with another?
switch ($cond){
case 1:
...;
break;
case 2:
...;
break;
case 3:
default:
...;
break;
}
It makes perfect sense to do it that way.
Also, #Ian is correct, but in a limited scope. If you wanted additional functionality applied to case 3 you would leave it the way it is. As long as you don't break, it will go on to the next case.
It kind of makes case 3 redundant though, so I'd remove it and just leave it as default