关于Switch的一些东东

博客指出在C#里,switch语句不能穿透,组合case标签编译会报错。若想实现贯穿效果,可采用两种方法:一是用if语句替代;二是使用goto语句,还提到示例语义本不适合贯穿,仅作演示。
首先是组合case标签。

例子如下:
 1None.gifusing System;
 2None.gif
 3None.gifenum Tenders : int
 4ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 5InBlock.gif    Cash = 1,
 6InBlock.gif    Visa,
 7InBlock.gif    MasterCard,
 8InBlock.gif    AmericanExpress
 9ExpandedBlockEnd.gif}
;
10None.gif
11None.gifclass Payment
12ExpandedBlockStart.gifContractedBlock.gifdot.gif{
13InBlock.gif    public Payment(Tenders tender)
14ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
15InBlock.gif        this.Tender = tender;
16ExpandedSubBlockEnd.gif    }

17InBlock.gif    
18InBlock.gif    protected Tenders tender;
19InBlock.gif    public Tenders Tender
20ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
21InBlock.gif        get
22ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
23InBlock.gif            return this.tender;
24ExpandedSubBlockEnd.gif        }

25InBlock.gif        set
26ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
27InBlock.gif            this.tender = value;
28ExpandedSubBlockEnd.gif        }

29ExpandedSubBlockEnd.gif    }

30InBlock.gif    
31InBlock.gif    public void ProcessPayment()
32ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
33InBlock.gif        switch((int)(this.tender))
34ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
35InBlock.gif            case (int)Tenders.Cash:
36InBlock.gif                Console.WriteLine("\nCash - Always good");
37InBlock.gif                break;
38InBlock.gif                
39InBlock.gif            case (int)Tenders.Visa:                
40InBlock.gif            case (int)Tenders.MasterCard:
41InBlock.gif            case (int)Tenders.AmericanExpress:
42InBlock.gif                Console.WriteLine("\nDisplay Credit card Authorization Dialog.");
43InBlock.gif                break;
44InBlock.gif                
45InBlock.gif            default:
46InBlock.gif                Console.WriteLine("\nSorry - Invalid tender");
47InBlock.gif                break;
48ExpandedSubBlockEnd.gif        }

49ExpandedSubBlockEnd.gif    }

50ExpandedBlockEnd.gif}

51None.gif
52None.gifclass Switch
53ExpandedBlockStart.gifContractedBlock.gifdot.gif{
54InBlock.gif    public static void DisPlayMenu()
55ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
56InBlock.gif        Console.WriteLine("Which form of payment is" + "Being Used:");
57InBlock.gif        Console.WriteLine("\t1 = Cash");
58InBlock.gif        Console.WriteLine("\t2 = Visa");
59InBlock.gif        Console.WriteLine("\t3 = Master Card");
60InBlock.gif        Console.WriteLine("\t4 = American Express");
61InBlock.gif        Console.WriteLine("===>");
62ExpandedSubBlockEnd.gif    }

63InBlock.gif    
64InBlock.gif    public static int GetTender()
65ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
66InBlock.gif        int tenderChoice = -1;
67InBlock.gif        DisPlayMenu();
68InBlock.gif        
69InBlock.gif        bool validTender = false;
70InBlock.gif        while(!validTender)
71ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
72InBlock.gif            string str = Console.ReadLine();
73InBlock.gif            tenderChoice = Convert.ToInt32(str);
74InBlock.gif            
75InBlock.gif            if(tenderChoice >= 0 && tenderChoice <=4)
76InBlock.gif                validTender = true;
77InBlock.gif            else
78InBlock.gif                Console.WriteLine("Ivalid choice - try again");
79ExpandedSubBlockEnd.gif        }

80InBlock.gif        
81InBlock.gif        return tenderChoice;
82ExpandedSubBlockEnd.gif    }

83InBlock.gif    
84InBlock.gif    public static void Main()
85ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
86InBlock.gif        Tenders tenderChoice = (Tenders)GetTender();
87InBlock.gif        Payment payment = new Payment(tenderChoice);
88InBlock.gif        payment.ProcessPayment();
89InBlock.gif        
90InBlock.gif        Console.ReadLine();
91ExpandedSubBlockEnd.gif    }

92ExpandedBlockEnd.gif}

  虽然可以组合case标签,但是不能穿透switch语句。
 比如39-43行改成:

None.gif            case (int)Tenders.Cash:
None.gif                Console.WriteLine(
"\nCash - Always good");
None.gif                
None.gif            
case (int)Tenders.Visa:
None.gif                Console.WriteLine(
"Visa - Accepted");
None.gif                
None.gif            
case (int)Tenders.MasterCard:
None.gif                Console.WriteLine(
"\nMasterCard - Accepted");
None.gif          
None.gif                
None.gif            
case (int)Tenders.AmericanExpress:
None.gif                Console.WriteLine(
"\nAmerican Express - Accepted");
None.gif                
break;
None.gif

 

 编译时就会报错。
但是我确实想让它实现贯穿的效果呢?当然还是有其他弯路可以走的:
 第一种方法就是使用if语句替代:

None.gif        if(Tenders.Cash = Tenders.Visa)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif{
InBlock.gif                Console.WriteLine(
"\nCash - Always good");
ExpandedBlockEnd.gif        }

None.gif        Console.WriteLine(
"Visa - Accepted");
None.gif      Console.WriteLine(
"\nMasterCard - Accepted");                
None.gif        Console.WriteLine(
"\nAmerican Express - Accepted");


(当然,这个例子的语义本来就不适合贯穿,仅作演示)

 第二种方法是使用我们一直避讳使用的goto语句:

None.gif            case (int)Tenders.Cash:
None.gif                Console.WriteLine(
"\nCash - Always good");
None.gif                
goto case (int)Tenders.Visa;
None.gif                
None.gif            
case (int)Tenders.Visa:
None.gif                Console.WriteLine(
"Visa - Accepted");
None.gif                
goto case (int)Tenders.MasterCard;
None.gif                
None.gif            
case (int)Tenders.MasterCard:
None.gif                Console.WriteLine(
"\nMasterCard - Accepted");
None.gif                
goto case (int)Tenders.AmericanExpress;
None.gif                
None.gif            
case (int)Tenders.AmericanExpress:
None.gif                Console.WriteLine(
"\nAmerican Express - Accepted");
None.gif                
break;

参考资料:《C#技术揭秘》
<think>首先,用户的问题是:“我想在C++的switch语句中使用if语句的具体方法或问题 请问C++ switch语句中如何正确使用if语句”。这涉及到在C++的switch语句中嵌套if语句。 从系统级指令: - 所有行内数学表达式必须使用$...$格式,但这里没有数学内容,所以可能不需要。 - 独立公式必须使用$$...$$格式并单独成段,但同样,没有数学公式。 - LaTeX语法正确:确保任何数学表达正确。 - 使用中文回答。 - 生成相关问题:在回答结束后,添加相关问题。 - 回答中引用的段落末尾自然地添加引用标识,如[^1]。 用户可见层: - 回答结构清晰,逐步解决问题。 - 保证回答真实可靠。 参考站内引用: - [^1]: 关于C++中if/switch语句的变量声明方式。 - [^2]: 示例代码展示switch语句中嵌套if-else语句。 - [^3]: switch语句的基本结构。 - [^4]: 注意花括号的使用以避免错误。 - [^5]: switch语句的表达式和case值。 用户的问题是关于在switch语句中正确使用if语句。从引用[^2]中,有一个具体的代码示例展示了如何在switch的case中嵌套if-else语句。引用[^4]强调了使用花括号以避免歧义的重要性。 结构化回答: 1. **介绍**:简要解释在switch语句中使用if语句的可能性和原因。 2. **方法**:详细描述如何正确嵌套if语句在switch语句中,包括语法和注意事项。 3. **示例**:提供一个或多个代码示例来演示。 4. **常见问题**:讨论可能遇到的错误和如何避免。 5. **总结**:重申关键点。 6. **相关问题**:生成相关问题。 使用中文回答。 生成相关问题:在最后添加,如系统指令所示。 确保回答真实可靠:基于C++标准。 大纲: 1. **引言**:在C++中,switch语句用于基于整数表达式的值选择执行路径。有时需要在某个case中使用if语句来添加额外的条件检查。 2. **正确方法**: - 在switch语句的case标签后,可以像在普通代码块中一样使用if语句。 - 使用花括号来界定case的代码块,以避免作用域问题。 - 注意break语句的位置,确保控制流正确。 3. **示例代码**:基于引用[^2]的示例,简化或扩展。 4. **注意事项**: - 避免悬空else问题(如引用[^4]提到的)。 - 变量作用域:在case中声明的变量需要小心作用域。 5. **总结**:强调使用花括号和正确缩进。 6. **相关问题**:生成2-3个相关问题。 相关问题: 1. 在C++中,switch语句中可以使用非整数类型吗? 2. 如何避免在嵌套if语句中常见的错误? 3. switch语句和if-else链的性能比较? 现在,构建回答。</think>### C++ switch语句中正确使用if语句的方法 在C++中,switch语句是一种基于整数表达式的值选择执行路径的控制结构。有时需要在特定case中添加额外的条件检查,这时嵌套if语句是常见做法。正确使用if语句可以增强代码的灵活性,但需注意语法细节以避免错误。以下从基本语法、正确方法、示例和注意事项逐步说明。 #### 1. **基本语法和正确方法** - **switch语句结构**:switch语句以整数表达式开始,每个case标签对应一个可能的值。default标签处理未匹配的情况。 ```cpp switch (整型表达式) { case 值1: // 代码块 break; case 值2: // 代码块 break; default: // 默认代码块 } ``` - **嵌套if语句的正确方式**: - **在case中使用if语句**:直接在case标签后添加if语句,就像在普通代码块中一样。 - **使用花括号界定作用域**:每个case的代码块必须用花括号`{}`包裹,以避免作用域问题(如变量冲突或悬空else)。 - **注意break语句**:break用于退出switch块;如果嵌套if语句后需要继续执行其他case,应省略break,但这通常不推荐。 - **变量声明**:在case中声明的变量作用域仅限于该花括号块内,避免全局污染。 #### 2. **代码示例** 以下示例基于引用[^2]和[^4]优化,展示在switch语句中正确嵌套if语句: ```cpp #include <iostream> int main() { int switchValue = 2; // switch的整数表达式 int ifValue = 5; // if语句的条件变量 switch (switchValue) { case 1: { // case 1的代码块(必须用花括号) std::cout << "Switch case 1" << std::endl; // 嵌套if-else语句 if (ifValue > 0) { std::cout << "If: ifValue is positive" << std::endl; } else { std::cout << "If: ifValue is not positive" << std::endl; } break; // 退出switch } case 2: { // case 2的代码块 std::cout << "Switch case 2" << std::endl; // 嵌套if-else语句 if (ifValue == 5) { std::cout << "If: ifValue equals 5" << std::endl; } else { std::cout << "If: ifValue does not equal 5" << std::endl; } // 可进一步嵌套另一个if语句 if (ifValue < 10) { std::cout << "Nested If: ifValue is less than 10" << std::endl; } break; // 退出switch } default: { std::cout << "Switch default" << std::endl; break; } } return 0; } ``` **运行结果**(当`switchValue=2`时): ``` Switch case 2 If: ifValue equals 5 Nested If: ifValue is less than 10 ``` **解释**: - 在case 1和case 2中,if语句被嵌套用于额外的条件检查。 - 每个case用花括号`{}`包裹,确保if语句的作用域清晰。 - break语句防止“fall-through”到下一个case。 #### 3. **常见错误和注意事项** - **缺少花括号导致悬空else**:如果省略花括号,else可能与错误的if配对。例如: ```cpp case 1: if (条件) // 语句1 else // 可能匹配到外部if,导致逻辑错误 // 语句2 ``` 引用[^4]强调,这会引起歧义,因为C++编译器不依赖缩进。**解决方案**:始终使用花括号定义case块。 - **变量作用域问题**:在case中声明变量时,必须用花括号限定作用域,否则变量可能在其他case中可见: ```cpp case 1: { int x = 10; // 正确:作用域限于此花括号 // ... } case 2: int y = 20; // 错误:未用花括号,可能导致编译错误 ``` - **性能考虑**:switch语句通常比长if-else链高效,因为编译器可能使用跳转表优化。但嵌套if语句会增加分支预测失败风险,建议在复杂条件时重构代码。 - **表达式类型限制**:switch的表达式必须是整数类型(如int、char),不能是字符串或浮点数。引用[^5]指出,表达式值未匹配任何case时,会执行default块。 #### 4. **总结** 在C++的switch语句中嵌套if语句是合法的,但必须: - 用花括号`{}`包裹每个case的代码块。 - 确保if语句的条件正确,并处理悬空else风险。 - 合理使用break控制流程。 这种方法适用于需要基于主条件分支后添加子条件检查的场景,如菜单系统或状态机。引用[^1]提到,变量声明方式影响可读性,建议在case块内局部声明变量以提升性能[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值