The basic syntax of the switch statement is as follows:
switch (expression)
{
case constant_expression1:
code1;
break;
case constant_expression2:
code2;
break;
……
default:
codeN;
}
①The switch statement in C++ is used to select different code branches based on the value of the expression.
②The expression inside switch (expression) can only be of integer, character, or enumeration type. The type of the constant expression following case must match it. Types like float cannot be used as expressions in switch, otherwise, a compilation error will occur.
③When the value of the expression is equal to a constant expression following a case, the statements following that case are executed. If none of the constant expressions in the cases match the value of the expression, the statements following default are executed.
④The case statement acts as a label. Labels cannot be duplicated, so the values of each case constant expression must be unique; otherwise, a compilation error will occur.
⑤Behavior of “fall-through” without break: case and default are just “labels” and do not automatically change the control flow. If there is no break after a case, the program will start executing from the matching case and continue executing all subsequent case/default statements (commonly referred to as “fall-through”).
Example (fall-through without break):
char grade = ‘A’;
switch(grade)
{
case ‘A’: cout << “85~100\n”;
case ‘B’: cout << “70~84\n”;
case ‘C’: cout << “60~69\n”;
case ‘D’: cout << “<60\n”;
default: cout << “error\n”;
}
// Output: 85~100 70~84 60~69 <60 error (because there is no break, it starts executing all subsequent statements from case ‘A’)
⑥case is usually used with break, which serves to immediately terminate the switch statement after executing the logic of the current case, avoiding “fall-through”.
Correct example (using break to implement multiple branches):
char grade = ‘B’;
switch(grade)
{
case ‘A’: cout << “85~100\n”; break;
case ‘B’: cout << “70~84\n”; break; // After executing this statement, it jumps out of switch due to break
case ‘C’: cout << “60~69\n”; break;
case ‘D’: cout << “<60\n”; break;
default: cout << “error\n”;
}
// Output: 70~84 (only executes the logic of case ‘B’ and then terminates switch)
⑦The order of the various case statements (including default) can be adjusted arbitrarily. As long as each case branch has a break, the order of the case does not affect the execution result.
Example (adjusting the order of case, result unchanged):
Original code (in the order of A, B, C, D, default):
char grade = ‘B’;
switch(grade)
{
case ‘A’: cout << “85~100\n”; break;
case ‘B’: cout << “70~84\n”; break;
case ‘C’: cout << “60~69\n”; break;
case ‘D’: cout << “<60\n”; break;
default: cout << “error\n”;
}
// Output: 70~84
After adjusting the order (C, default, D, A, B order):
char grade = ‘B’;
switch(grade)
{
case ‘C’: cout << “60~69\n”; break;
default: cout << “error\n”; break;
case ‘D’: cout << “<60\n”; break;
case ‘A’: cout << “85~100\n”; break;
case ‘B’: cout << “70~84\n”; break; // Still matches this case, output 70~84
}
// Output: 70~84 (result is consistent with the original code)
⑧Multiple case statements can share a group of execution statements (utilizing the “fall-through” feature, omitting the execution logic of intermediate case statements, and directly executing the statements of the last case).
Example (A, B, C share the logic of “output >60”):
char grade;
grade = ‘A’; // can also be ‘B’ or ‘C’
switch(grade)
{
case ‘A’:
case ‘B’:
case ‘C’: cout << “>60\n”; break; // When grade is ‘A’/’B’/’C’, this output is executed
case ‘D’: cout << “<60\n”; break;
default: cout << “error\n”;
}
// If grade is ‘A’, output: >60
⑨The default statement is optional. If default is not written, and the value of the switch expression does not match any of the case constants, the program will skip the switch statement and continue executing the subsequent code.
Example (no default, and no matching case):
int num = 5;
switch(num)
{
case 1: cout << “one\n”; break;
case 2: cout << “two\n”; break;
}
// num is 5, no matching case, and no default, so there is no output inside switch, directly executing subsequent code
cout << “switch execution completed\n”;
// Output: switch execution completed
⑩Simplified form: switch does not necessarily require a “compound statement block” (i.e., {} wrapping multiple statements); a single statement can directly follow a case.
Example (switch equivalent to if in a simplified scenario):
int i = 1;
switch(i) case 1: cout << “ok\n”; // When i=1, output ok
if (i == 1) cout << “ok\n”; // Equivalent to the previous statement, also outputs ok
<11>Nested switch: switch can be nested, and the inner case/default only relates to the innermost switch that contains it.
Example (nested structure illustration):
int a = 1, b = 2;
switch(a)
{
case 1:
switch(b) // inner switch
{
case 2: cout << “a=1, b=2\n”; break;
default: cout << “a=1, b is not 2\n”;
}
break;
default: cout << “a is not 1\n”;
}
// Output: a=1, b=2
<12>The limitations of switch and the complement of if:
switch can only test “equality” for integer, character, and enumeration types (for example, checking if a variable equals a fixed value).
If the test is for range conditions (like scores in [85,100], [70,85), etc.), or testing floating-point variables, if statements are needed (because if supports relational expressions, allowing for flexible descriptions of “greater than, less than, range,” etc.).
Example (using if to determine score range):
int grade = 80;
if (grade >= 85 && grade <= 100) cout << “A\n”;
else if (grade >= 70 && grade < 85) cout << “B\n”; // 80 matches this branch, outputs B
else if (grade >= 60 && grade < 70) cout << “C\n”;
else if (grade >= 0 && grade < 60) cout << “D\n”;
else cout << “error\n”;
The final else is equivalent to default in switch.
If you force switch to implement the above logic, you would need to write a case for each score (or many range boundary points), making the code very verbose, so for range and floating-point tests, if is more suitable.
<13>The advantages of switch (conciseness):
If testing for several discrete different values of an integer variable (like determining the day of the week, menu option numbers, etc.), using switch is more concise.
Example (using switch to determine the day of the week, assuming day corresponds to 1 – 7 for Monday to Sunday):
int day = 3;
switch(day)
{
case 1: cout << “Monday\n”; break;
case 2: cout << “Tuesday\n”; break;
case 3: cout << “Wednesday\n”; break; // day=3, outputs Wednesday
//… other cases
default: cout << “Invalid day\n”;
}
<14>The execution body of if…else statements is equivalent to a group of statements in switch that contain break.
<15>How to choose between if and switch?
When you need to judge range conditions (like intervals, size relationships), or test floating-point variables, use if statements.
When you need to judge discrete fixed values of integer/character variables, using switch statements is more concise.
Transfer Statements
1. break statement
Function: In a switch statement, it exits the switch statement; in a loop statement, it exits from the nearest enclosing loop body.
Example explanation: In the case of nested loops, break only exits the inner loop, and then executes the statements after break in the outer loop.
2. continue statement
Function: In a loop statement, it ends the current loop, skips the statements in the loop body that have not been executed, and proceeds to the next loop condition.
Example explanation: For example, to output numbers from 100 to 200 that are not divisible by 3, when n is divisible by 3, continue skips the output statement and continues to the next loop; the same functionality can also be achieved using an inverse conditional if statement block, thus omitting continue.
Using continue:
for(int n=100; n<=200; n++)
{
if(n%3 == 0)
continue; // If divisible by 3, skip the output statement for this loop
cout << n << endl;
}
Using inverse conditional if statement:
for(int n=100; n<=200; n++)
{
if(n%3 != 0) // Inverse condition, checking “not divisible by 3”
{
cout << n << endl;
}
}
Difference from break: continue only ends the current loop, while break terminates the entire loop.
3. goto statement
Function: Transfers control to the statement label.
Example explanation: Can be used to implement loops (like calculating the sum from 1 to 100), and can also directly jump out of deep nested loops.
Usage suggestion: Modern programming design advocates limiting its use, as misuse can lead to chaotic program flow and poor readability; it can be useful when deep jumps in multiple loops are needed and using break would be cumbersome.