There are some functions in MATLAB that we designed to be similar to their counterparts in other languages. There are also some functions that we deliberately designed differently. A case in point is the syntax and behavior for the switch statement.
Contents
No Fall Through in MATLAB
The individual case statements in MATLAB do not fall through to the next case, the default behavior in C. We found that in C, one common source of bugs was not properly stopping the default fall through behavior but termination with a break statement. So we eliminated the need to terminate each case in MATLAB.
Why Does C Allow Fall Through?
At least one major reason C allows fall through behavior is so that multiple cases can share code. This is generally very good for code hygiene. Otherwise, you risk code bloat and propogation of errors via copy-paste, among other pitfalls.
How Does MATLAB Handle Code Sharing Between Cases?
MATLAB avoids the code bloat and error propagation downsides of no fall through behavior by allowing you to group cases together, in a cell array. In fact, if you want to share code, you must group like cases together since you cannot fall through to another case under any circumstances. If your expression matches more than one case, the first one encountered in the switch is the one that will execute.
If you have some cases that share most of the code in common but still differ a bit, you have several options. You can place them in the same case and then embed another switch statement or use conditional logic, via if statements. Or write code perhaps using appropriate logical indexing.
What About Default?
Finally, we felt that the last choice in a switch statement, being called default, was a bit misleading. It is used if no other case matches, but that is rarely the behavior the programmer is expecting. Instead, we chose otherwise because we felt it better reflected that none of the previous cases matched at all.
Example Code
Here's a simple example that shows the features of switch.
type blogswitch
function blogswitch(myinput)
% Sample switch statement for blog
switch myinput
case {1, true, 'yes','true'}
disp('Input is true')
case {0, 'false', 'no', false}
disp('Input is false')
case {ones, zeros}
disp('Ya can''t get here from there. You need to make up your mind!')
otherwise
disp('No dice')
end
One thing you may notice is that you can't reach the third case. The case listed with {ones, zeros} will always be satisfied by one of the first two cases and won't ever execute.
Let's try the code.
blogswitch trueInput is true
blogswitch maybeNo dice
What Cases Do You Run Into?
I wonder what situations you find yourselves in. Do you use switch statements with cases for multiple conditions? Did you even know you could do that? Let me know your switch-case experiences here.
Get
the MATLAB code
Published with MATLAB® 7.9



I think the MATLAB approach is superior to C in this situation — fall-through makes it hard to reason about the code, and encourages users to write convoluted SWITCH statements to shave a few cycles.
Regarding interesting uses of SWITCH: At one point, I needed to do a switch based on two string variables (the current location of a GUI element, and the new location). Doing it with nested SWITCHes or nested IF-THENs proved very complicated. The cleanest solution was to SWITCH on the concatenated value of the two strings:
Loren, Hi.
The significance of the {ones,zeros} was lost on me. Apart from not having a way to get there. Is this not just {1,0}? Is there some benefit in case ones?
For your question: Yes, use case all the time for options, but don’t use multiple option much, as my options are usually distinct. Used to use switch with numeric flags. Then saw a comment recommending use of string constants, so I do that a lot now.
Never had an issue with the switch syntax, thanks.
The CASE command in MATLAB is one of the winning features (some of the features turned out better than others!). Being able to test for strings and numeric values in the same case statement is fabulous. I don’t miss the fall-through behavior. In fact, I hardly ever use it in C except for having various values execute the same code. Anything else I’d rather solve with if/else constructs, because fall-through is very hard to read.
I did not know it was legal to have more than one case matching the switch value. I guess this might be useful if the values in case are variables rather than constants.
Neil-
The {ones, zeros} is just another way to say {1,0}. I was just showing that the expressions don’t need to be constants and can be ones that get evaluated. No special benefit unless for some reason you want to paramaterize the inputs and use something like ones(n) where there are different values of n in different cases.
–Loren
Loren,
I really like the ability of having multiple cases in a single CASE statement. I’ve done something very similar to your example code for processing input arguments. But I did have to add one extra step before the SWITCH block to account for various cases (no pun intended):
if ischar(myinput)
myinput = lower(myinput);
end
This way, the user can specify “Yes” or “FALSE” as myinput.
Hi Loren,
I do not fully understand your reply to Neil (#4), since the switch expression must be a scalar or a string. For instance, this errors (for all n other than 1)
n = 3 ; A = ones(n) ; switch A, case {ones(n)}, disp('ok') ; end % ??? SWITCH expression must be a scalar or string constant.Jos
Jos-
My bad, you are correct. Scalars or strings. But you can still use expressions that evaluate to scalars, which is what I had been thinking about.
I use an alternate method to use the same ‘case’ for multiple situations: ‘switch true’ (works in most languages).
In my case, I ask the user to specify an action, then check whether it was ‘append’,'prepend’ or ‘replace’, or the first few letters of one of these options:
switch true % execute the first case for which the statement evaluates to true case strncmp(action,'replace',length(action)) % code to perform replace action case strncmp(action,'replace',length(action)) % code to perform replace action case strncmp(action,'replace',length(action)) % code to perform replace action otherwise % error: unknown action end(It works because a switch statements simply compares the expression following ‘switch’ to the expression following the first ‘case’, then the second, etc, until it finds a match.)
I imagine I could have used ‘case {‘a’,'ap’,'app’,'appe’-etc’, but I like the way this looks better.
Loren, is there a better way to do this, using cases with multiple conditions? The ‘switch true’ is awkward syntax, but typing out all the options doesn’t appeal to me either.
@LyVe
I think you are looking for the function STRMATCH
Jos
LyVe-
I don’t see a way to do what you want without spelling out all the cases unless you switch on the first character only and assume that word is correct. Only works if the words start with different letters obviously.
–Loren
LyVe,
Take a look at VALIDATESTRING (available R2007b and later)
http://www.mathworks.com/access/helpdesk/help/techdoc/ref/validatestring.html
choices = {'appendAfter', 'appendBefore', 'replace'};
% This returns 'replace'
v = validatestring('re', choices)
% This returns 'appendAfter'
v = validatestring('appenda', choices)
% This throws an exception
v = validatestring('append', choices)
Once you do this, then you can have a SWITCH block that performs the appropriate actions.
@Jos:
Indeed, strmatch would work. The code would become something like this then, I guess:
possible_actions={'replace','append','prepend'}; action_id=strmatch(action,possible_actions); if isempty action_id action_id = 0; end switch action_id case 1 % 'replace' % code to perform replace action case 2 % 'append' % code to perform replace action case 3 % 'prepend' % code to perform replace action otherwise % error: unknown action end switch true % execute the first case for which the statement evaluates to true case strncmp(action,'replace',length(action)) % code to perform replace action case strncmp(action,'replace',length(action)) % code to perform replace action case strncmp(action,'replace',length(action)) % code to perform replace action otherwise % error: unknown action endAs you can see, I had to deal with empty results (I found that switch won’t accept empty input) and I am now switching on the index, which makes the code less transparent – I could add a ‘action=possible_actions{action_id}’ though.
Personally, I dislike strmatch because it’s not obvious from the name what it does exactly, but it appears to be quite suitable here. Based on a quick test, though, the strncmp version appears to be *much* faster. Even if all three strncmps are performed (which will not always be the case), strmatch takes 4 times longer. (For testing, I eliminated the isempty check and the switch, and used 300 randomly pre-generated strings that would be acceptable as input.)
(I hope you don’t think I’m ungrateful, going on in such detail about why I prefer my method – I *do* appreciate the suggestion.)
@Jiro:
validatestring sounds like the perfect choice for this situation; unfortunately, we’re using a pretty old version of Matlab. I might write my own, though.
@Loren:
Thanks for your input – it’s good to know that I didn’t miss a really obvious solution. The ‘must start with different letters’ is sort of a prerequisite for my version as well; the code would run as if nothing happened but the user wouldn’t know in advance which action would be taken.
LyVe,
Why don’t you just use a plain if/elseif/else/end construct? It seems simpler in your case:
if case strncmp(action,'append',length(action)) % code to perform append action elseif case strncmp(action,'prepend',length(action)) % code to perform prepend action elseif case strncmp(action,'replace',length(action)) % code to perform replace action else % error: unknown action end… but obviously without those “case” keywords in there. :)