# Switching Things Up22

Posted by Loren Shure,

If you have ever used a switch statement in MATLAB and also used it in C, you might have noticed that the two constructs have different semantics.

### switch in C

In C, you often terminate case statements in switch constructs with a break statement to prevent execution of the code in the case that follows. Omitting the break statement causes the code in the following case to execute. The behavior of switch statements in C is sometimes described as fall through.

### switch in MATLAB

There are several major differences between switch statements in MATLAB and C.

• MATLAB does not have fall through behavior in its switch statements and therefore no break statement is typically required for individual case statementss.
• MATLAB case statements have another feature that C and many other languages do not have. The expression following case need not be scalar-valued, but can combine several expressions by placing the acceptable expressions in a cell array.
• If you want to specify behavior for switch expressions that don't match any of the case expressions, use the otherwise branch. In C, use default instead.
• Expressions for case statements can include strings and numeric expressions, not just integer values. Though you have to be careful using non-integral numbers because of round-off, this flexibility can make the intent of your code more obvious instead of seeing a list of numbers.
• ### More on switch in MATLAB

When we originally were designing switch for MATLAB, we examined much of our own C source code, and we found a huge majority of the case statements terminated in break, hence the no fall-through behavior of MATLAB. This makes the switch statement in MATLAB equivalent to an if-elseif construct. To achieve fall-through behavior in MATLAB, you can specify all the relevant expressions in one case and then conditionally compute values within that section of code.

### Do You Use switch Statements?

I am curious to hear about your experiences using switch statements in MATLAB. Post your thoughts here.

Get the MATLAB code

Published with MATLAB® 7.8

Will replied on : 1 of 22

I use them a lot when I’m dealing with argument, value pairs that are in varargin cell-arrays.

matt fig replied on : 2 of 22

I love the Matlab switch construct! When I was first learning Matlab about 5 years ago, I found myself with many of these:

if (…)
elseif (…)
elseif (…)
elseif (…)
end

The switch looks so much nicer in the code. This is especially true when cell arrays are used to replace multiple conditional evaluations.

Yakov replied on : 3 of 22

Related to differences between C and Matlab is the use of for loop. We found the following useful in some of our code:

a=[1 2 3;4 5 6;7 8 9];
for I=a;I,end

It actually cycles through the columns of matrix and is an easy way to implement column-wise operations. One in a long list of undocumented behaviors.

Jos replied on : 4 of 22

Sometimes, I miss the fall-through C-like behavior of switch, for instance, when setting default values of input parameters to a function:

 
function F (a,b,c,d)
% C-style switch
switch nargin
case 0
a = 1
case 1
b = 2
case 2
c = 3
case 3
d = 4
end
 

looks nicer than

 
function F (a,b,c,d)
% matlab-style
if nargin < 4
d = 1
if nargin < 3
c = 1
if nargin < 2
b = 1
if nargin < 1
a = 1
end
end
end
end
 

Just a thought

Jos

Loren replied on : 5 of 22

Jos-

You might consider inputParser for putting in default values.

–Loren

Eric replied on : 6 of 22

We’ve been replacing a lot of big ugly switch statements with containers.Map since that has been added to MATLAB. Typically they are used for translating between item ‘codes’ or ‘tags’ and the corresponding long-form description or other information.

Loren replied on : 7 of 22

Eric-

Out of curiosity, why change from switch to containers.Map?

–Loren

Dan Mac replied on : 8 of 22

Yakov
Thanks for that little tidbit about cycle through the columns of matrix in a for loop. I had not known about that feature. Probably would have used it often if it had.

Dan

Loren replied on : 9 of 22

Yakov and Dan-

I blogged about the for-loop behavior (and more) here.

–Loren

Eric replied on : 10 of 22

Loren-
The reason I like containers.Map for this is primarily a style thing. To me it looks neater and is easier to mentally parse/maintain when all the keys and values are respectively grouped together. Often I’m copying the keys and values from columns of a CSV or XLS file that someone else has made and it makes it really easy to copy and paste them into the M file and then wrap in {}, compared to manually breaking them out into a switch statement. It also makes it easier to do the help text for the function, because when you are done you can copy the list of keys, paste it into the help text, and then Ctrl-R to comment it.

 keys = { 'a' 'b' 'c' 'd' }; values = { 1 2 3 4 }; map = containers.Map(keys,values); key = 'a'; out = map(key) 
rather than

 key = a; switch key case 'a' out = 1; case 'b' out = 2; case 'c' out = 3; case 'd' out = 4' end 

Regards,
Eric

Joe Kirk replied on : 11 of 22

I use switch statements quite frequently, and for all sorts of things.

For example, in my “vivid” colormap [http://www.mathworks.com/matlabcentral/fileexchange/20848], I needed to interpret a string of color characters (like ‘r’ for red, ‘g’ for green, etc.) as 1×3 arrays of type double. To do this I wrote the following code:

 
clr_mat = zeros(num_clrs,3);
c = 0;
for k = 1:num_clrs
c = c + 1;
switch lower(input(k))
case 'r', clr_mat(c,:) = [1 0 0];  % red
case 'g', clr_mat(c,:) = [0 1 0];  % green
case 'b', clr_mat(c,:) = [0 0 1];  % blue
case 'y', clr_mat(c,:) = [1 1 0];  % yellow
case 'c', clr_mat(c,:) = [0 1 1];  % cyan
case 'm', clr_mat(c,:) = [1 0 1];  % magenta
case 'p', clr_mat(c,:) = [1 0 .5]; % pink
case 'o', clr_mat(c,:) = [1 .5 0]; % orange
case 'l', clr_mat(c,:) = [.5 1 0]; % lime green
case 'a', clr_mat(c,:) = [0 1 .5]; % aquamarine
case 's', clr_mat(c,:) = [0 .5 1]; % sky blue
case 'v', clr_mat(c,:) = [.5 0 1]; % violet
case {'k','w'}, clr_mat(c,:) = [.5 .5 .5]; % grayscale
otherwise, c = c - 1;
end
end
clr_mat = clr_mat(1:c,:);
 
Joe Kirk replied on : 12 of 22

By the way, in my example, colors can be repeated if desired, and by using the counter “c”, I was able to ignore invalid inputs.

Kieran replied on : 13 of 22

I sometimes use switch statements in the following (somewhat kludgy) manner:

switch sprintf('%d %d', logical_test1, logical_test2)
case '0 0'
% Do A
case '0 1'
% Do B
case '1 0'
% Do C
case '1 1'
% Do D
end


This avoid a bunch of nested if statements and is somewhat clearer in my mind than:

if logical_test1
if logical_test2
% Do D
else
% Do C
end
else
if logical_test2
% Do B
else
% Do A
end
end


I’m open to suggestion to improve this.

Loren replied on : 14 of 22

Kieran-

You could switch on the combined tests by converting them to “binary”:

logtest = logtest1*2+logtest1

switch logtest
case 0
case 1
case 2
case 3
end


I don’t know if that’s more readable or less so.

–Loren

Iain replied on : 15 of 22

I have been using Malab for six years and had no idea it had a switch statement. I have always used elseif, which is a more flexible alternative. I think I will probably stick with elseif in a lot of cases.

In the simplest cases, like Eric, I often replace long switch statements with lookup tables. I didn’t know that Matlab finally ships with a decent map data structure. The old-style way of doing Joe Kirk’s example would be to put the colors in a structure:
color_table.r = [1 0 0]; % red color_table.g = [0 1 0]; % green ...and then lookup like this:
clr_mat(c,:) = color_table.(lower(input(k)));One would have to test for field existence or catch exceptions if unknown colors might be requested.

Of course, which approach to use is a stylistic choice and will depend on the precise situation. The book “Code Complete” has a section on “Using decision tables to replace complicated logic” that is worth considering.

Rather than Joe, Iain or Eric’s way of doing look-up tables, I like the clarity of cell arrays and the strcmp function:

color_table = {
'red',   [1 0 0]
'green', [0 1 0]
'blue',  [0 0 1]
};
ii = find(strcmp(color_table(:,1), name ));
clr_mat(c,:) = color_table{ii,2};



.

The problem with containers.Map, in my opinion, is that the key and the value are physically separated. If you want to add one value to the table, you need to edit your function in two places.

The switch statement really shines when you need to execute different bits of code based on an input, it’s not so useful for a simple table lookup.

Joe Kirk replied on : 17 of 22

Chris,

I like your method for some applications.

In the particular case I showed however, I am doing more than a simple table lookup. Instead, I am trying to take an input string of color characters and build an Mx3 matrix of RGB triplets.

For example, if someone provides the input ‘rygb’, I want to build the matrix [1 0 0; 1 1 0; 0 1 0; 0 0 1].

The colors need to be in the correct order, and if someone provides an invalid color character, I want to ignore it.

To achieve this with your method, I need to do the following:

color_table = {
'r',    [1 0 0]     % red
'g',    [0 1 0]     % green
'b',    [0 0 1]     % blue
'y',    [1 1 0]     % yellow
'c',    [0 1 1]     % cyan
'm',    [1 0 1]     % magenta
'p',    [1 0 .5]    % pink
'o',    [1 .5 0]    % orange
'l',    [.5 1 0]    % lime green
'a',    [0 1 .5]    % aquamarine
's',    [0 .5 1]    % sky blue
'v',    [.5 0 1]    % violet
'k',    [.5 .5 .5]  % grayscale
'w',    [.5 .5 .5]  % grayscale
};

num_clrs = length(input(:));
clr_mat = zeros(num_clrs,3);
c = 0;
for k = 1:num_clrs
c = c + 1;
ii = find(strcmp(color_table(:,1),lower(input(k))));
if ~isempty(ii)
clr_mat(c,:) = color_table{ii,2};
else
c = c - 1;
end
end
clr_mat = clr_mat(1:c,:);
if ~isempty(clr_mat)
clrs = clr_mat
end


In my opinion, my SWITCH statement is more compact and readable. I may use your method for other things though… :o)

Jim Weiner replied on : 18 of 22

A not very clearly documented feature of the switch/case construct that I’ve found useful is that it’s much more general than the examples might lead you to believe. All the examples I’ve seen have been of the form:

switch x
case v1

case v2

end

where x is a variable or expression, and each of the vi are numeric or string constants or cells arrays comprised thereof.

But this also works:

switch true
case exp1

case exp2

end

where each of the expi are logical expressions. The first that evaluates as true has its branch executed.

locolab replied on : 19 of 22

Can you use conditional statments in a switch statment for example:

switch num
case num<-2
disp(‘Num less than -2′)
otherwise
disp(‘Error’)
end

Loren replied on : 20 of 22

locolab-

yes, you can use conditional statements for cases in a switch statement.

–Loren

OysterEngineer replied on : 21 of 22

I like the switch syntax since the code is so easy for most people to read.

However, I don’t like how it “artificially” drives the McCabe Clclomatic complexity index high. Thus, when I document a function that I’ve written, & include the output from Code Metrics, I have to write some text to discuss why, for example, the complexity index is 14 rather than my target of less than 10.

In many cases, my co-workers & I look at the function in detail & decide that it is clearer to use the switch-case syntax & accept the higher index rather than dividing the function into sub-functions just to get the index below 10.

I’m under the impression that using if-ifelse syntax will result in the same complexity index as the switch-case syntax. Yet, the switch-case syntax is usually clear.

Maybe I need to invent an Oyster Complexity Index that excludes the effect of the switch-case syntax.

I appreciate Iain’s discussion of decision tables from Code Complete. I browsed thru our copy & see how to implement such a thing in readable code.

Loren replied on : 22 of 22

OysterEngineer-

if-else will result in the same complexity as switch. We often make the same trade-off you do, to keep a switch statement instead of having some very small subfunctions. There is a reason switch drives up the complexity though. The number of possible paths through the code does indeed go up, just as in an if-else situation.

–Loren

These postings are the author's and don't necessarily represent the opinions of MathWorks.