Follow our public account for timely embedded content! 👇
Table of Contents
- 1. Introduction
- 2. Basic Syntax and Semantics
- 3. Detailed Explanation
4. Conclusion
1. Introduction
The switch statement is a fundamental concept that every C/C++ programmer must learn. It appears simple: an expression, a series of case labels, and an optional default. However, behind this seemingly straightforward syntax lies many details that can trip up even seasoned programmers. Many have used it for years yet still have a superficial understanding of its core mechanisms.
2. Basic Syntax and Semantics
The switch statement is a multi-way branch selection structure that selects one of several code blocks to execute based on the value of an integer expression.
1. Basic Structure
switch (expression) { case constant1: // Statement sequence 1 break; case constant2: // Statement sequence 2 break; // ... More case labels default: // Default statement sequence break; // Usually also add break, though not required, for consistency}
2. Semantic Details
[1] The switch expression must be of an integer or enumeration type, specifically including:
All signed integer types: int, char, short, long, long long. The character type (char) is essentially an integer.
All unsigned integer types: unsigned int, unsigned char, unsigned short, unsigned long, unsigned long long.
Boolean type: bool.
Enumeration type: enum.
Valid switch expressions
int num = 2;char ch = 'A'; enum Color {RED, GREEN, BLUE} color = RED;bool flag = true;switch(num) { /* ... */ } // ✓ Integer switch(ch) { /* ... */ } // ✓ Character type (essentially an integer)switch(color) { /* ... */ } // ✓ Enumeration typeswitch(flag) { /* ... */ } // ✓ Boolean type (though not commonly used[citation:1])
Invalid expression types, the following types cannot be used directly as switch expressions:
All floating-point types: float, double.
String literals: char*, const char*.
float f = 1.5;double d = 3.14;char* str = "hello";switch(f) { /* ... */ } // ✗ Floating-point switch(d) { /* ... */ } // ✗ Floating-point switch(str) { /* ... */ } // ✗ Pointer type (unless it's an integer value of an integer pointer)
[2] Case labels must be compile-time constant expressions, and their values must be unique and cannot be duplicated.
[3] The break statement is used to exit the switch statement; if omitted, execution will continue to the next case (fall-through phenomenon).
[4] The default label is optional and executes when none of the cases match; it can be placed anywhere but is usually placed at the end.
3. Execution Flow
[1] Calculate the value of the switch expression
[2] Compare with each case constant
[3] Find the matching case and execute the corresponding code
[4] If there is no match and a default exists, execute the default code
[5] Exit upon encountering a break or the end of the switch
3. Detailed Explanation
1. The Performance Mystery of Switch vs. If-Else
If-else is a linear sequential judgment with an average time complexity of O(n). The more branches there are, the more comparisons in the worst case. The switch statement is designed for multi-way branching, and the compiler will optimize based on the number and density of cases:
Jump table: When case values are continuous or dense, the compiler creates a jump table for O(1) constant time direct jumps, significantly outperforming if-else.
Binary search: When there are many but non-continuous case values, the compiler uses binary search (O(log n)), which is still much more efficient than linear search.
Converted to if-else: When there are very few branches, both perform similarly.
In scenarios with many branches (e.g., more than 5) and discrete integer values, switch, due to the compiler’s powerful optimization, usually performs significantly better than if-else, and the code is clearer. For fewer branches or complex conditions, use if-else.
2. Variable Definition Under Case Labels
The following code requires defining a temporary variable under one case
#include <stdio.h>#include <stdlib.h>int main() { int condition = 2; switch (condition) { case 1: // Do something break; case 2: int my_var = 10; // Error! Or warning! printf("my_var = %d\n", my_var); break; default: break; } return 0;}
Will this code compile? C++ is stricter and will result in a compilation error because C++ emphasizes object construction and destruction, not allowing skipping initialization. C may only issue a warning, but the behavior is undefined; C is relatively lenient, but the actual behavior is unpredictable.
The root of the problem lies in the fact that the entire switch statement block is a single scope. The case labels are merely jump targets within this scope, not delimiters of the scope.
case 2: int my_var = 10; // Variable declaration + initialization
Although my_var seems to be “inside” case 2 from the code layout, it is actually seen by the compiler as being at some position within the entire switch statement block.
Why is this dangerous? From the compiler’s perspective, the variable my_var is declared within the scope of the switch block, but during program execution, it may bypass its initialization statement. If the program later uses this variable in another way, it will be uninitialized!
For example, illustrating this danger:
switch (condition) { case 1: int my_var = 42; printf("Initialized: %d\n", my_var); case 2: printf("Danger: %d\n", my_var); break;}
If condition is 2, it will jump directly to case 2, and my_var will be uninitialized.
Correct solutionsMethod 1: Create a local scope with braces
case 2: { int my_var = 10; // Now this variable is only valid within the braces printf("my_var = %d\n", my_var); break;}
Method 2: Declare the variable before the switch
int my_var;switch (condition) { case 2: my_var = 10; // Assignment, not initialization printf("my_var = %d\n", my_var); break;}
4. Conclusion
Due to my limited level, if there are any errors or logical inconsistencies, I hope readers will not hesitate to correct me. If this can provide you with some help, I would be most honored.
Welcome to apply to join the embedded technology exchange group by adding the author’s WeChat below.