程序的十字路口:一文彻底搞懂分支结构(if & switch)

📝 前言:在程序的世界里,代码并不总是从上到下一成不变地“直线奔跑”。很多时候,程序需要根据不同的情况做出不同的选择,就像我们走到十字路口需要根据红绿灯决定是走是停一样。这就是今天我们要探讨的核心——分支结构(选择结构)

本文将从最基础的if语句出发,一路打怪升级到switch,并分享一些日常开发中的避坑经验代码规范。干货满满,建议收藏!⭐

🌟 一、 什么是分支结构?

在编程中,三大基本结构分别是:顺序结构、分支结构、循环结构。

  • 顺序结构:代码从上到下依次执行(默认情况)。
  • 分支结构:根据条件判断的结果,选择性地执行某段代码。

分支结构的灵魂在于条件判断,在Java/C等语言中,条件表达式的结果必须是一个布尔值true 或 false)。

🛤️ 二、 if 分支家族

if家族是最常用的分支结构,它有三种形态:单分支、双分支、多分支。

1. 单分支:如果…就… (if)

当你只有一个条件需要满足时使用。满足就执行,不满足就跳过。

// 语法
if (条件表达式) {
    // 条件为 true 时执行的代码
}

// 示例:如果下雨,就带伞
boolean isRaining = true;
if (isRaining) {
    System.out.println("外面下雨了,记得带伞!");
}

2. 双分支:如果…否则… (if-else)

非黑即白的选择。条件满足走A逻辑,不满足走B逻辑。

// 语法
if (条件表达式) {
    // 条件为 true 时执行
} else {
    // 条件为 false 时执行
}

// 示例:判断奇偶数
int num = 10;
if (num % 2 == 0) {
    System.out.println(num + "是偶数");
} else {
    System.out.println(num + "是奇数");
}

3. 多分支:如果…否则如果…否则… (if - else if - else)

面对多个条件判断时,按顺序从上往下判断,只要有一个条件满足,执行完毕后就会跳出整个if结构

// 语法
if (条件1) {
    // 满足条件1执行
} else if (条件2) {
    // 满足条件2执行
} else if (条件3) {
    // 满足条件3执行
} else {
    // 以上条件都不满足时执行(可省略,但建议保留作为兜底逻辑)
}

// 示例:成绩评级
int score = 85;
if (score >= 90) {
    System.out.println("优秀");
} else if (score >= 80) {
    System.out.println("良好"); // 执行这里后,直接跳出整个if
} else if (score >= 60) {
    System.out.println("及格");
} else {
    System.out.println("不及格");
}

⚠️ 避坑指南1else if 的顺序非常重要!如果把上面例子中 score >= 60 放在第一个判断,那么85分也会被判定为“及格”。多分支判断必须注意条件之间的互斥性和顺序

🔀 三、 switch 分支:精准匹配

当你需要对一个具体的值进行多路匹配时,switchif-else if看起来更清爽。

1. 基本语法与示例

// 示例:根据星期几输出日程
int day = 3;
switch (day) {
    case 1:
        System.out.println("周一:开会");
        break;
    case 2:
        System.out.println("周二:写代码");
        break;
    case 3:
        System.out.println("周三:改Bug"); // 匹配成功
        break;
    // ...省略其他天
    default:
        System.out.println("休息日");
        break;
}

2. switch 的三大铁律

  1. 支持的类型:在Java中,switch支持 byte, short, int, char, String(Java7+), 枚举不支持 long, float, double 及 boolean
  2. break 不能忘:如果漏写了break,会发生穿透现象(Fall-through),程序会无条件执行后续的case代码,直到遇到break为止。
  3. default 的位置default可以放在任何位置,但习惯上放在最后。它的作用类似于if-else中的else

💡 巧妙利用穿透:有时候穿透不是Bug而是Feature!比如判断季节:

int month = 5;
switch (month) {
    case 3: case 4: case 5:
        System.out.println("春季");
        break;
    case 6: case 7: case 8:
        System.out.println("夏季");
        break;
    // ...
}

⚔️ 四、 if vs switch:到底用哪个?

比较维度 if-else switch
判断条件 布尔表达式(范围、大小判断) 具体的常量值(等值判断)
适用场景 区间判断、复杂逻辑判断 离散值的多路匹配(如菜单选择、星期)
底层效率 逐条判断,效率逐渐降低 底层通过跳转表实现,效率恒定(JVM优化)
代码可读性 嵌套过多时容易变成“波纹状” 结构清晰,一目了然

总结口诀

  • 等值判断用 switch,区间判断用 if
  • 能用 switch 的场景一定能用 if,反之不然。

🚀 五、 进阶:如何写出优雅的分支代码?

在实际开发中,嵌套过深的 if-else 被称为“箭头代码”(缩进越来越深,形如箭头 >),极其难以阅读。这里分享两个优化技巧:

1. 卫语句提前返回

反面教材

public void process(Order order) {
    if (order != null) {
        if (order.isPaid()) {
            if (order.hasStock()) {
                // 核心业务逻辑(嵌套太深)
                System.out.println("开始发货...");
            } else {
                System.out.println("库存不足");
            }
        } else {
            System.out.println("订单未支付");
        }
    } else {
        System.out.println("订单不存在");
    }
}

优化后(提前Return,拒绝嵌套)

public void process(Order order) {
    if (order == null) {
        System.out.println("订单不存在");
        return; // 提前阻断
    }
    if (!order.isPaid()) {
        System.out.println("订单未支付");
        return;
    }
    if (!order.hasStock()) {
        System.out.println("库存不足");
        return;
    }
    
    // 核心业务逻辑(只有一层缩进,清爽!)
    System.out.println("开始发货...");
}

2. 永远加上大括号 {}

哪怕 if 里面只有一行代码,也必须加上 {}。这不仅是为了规范,更是为了防止后续维护时添加代码造成的逻辑错误(著名的苹果SSL漏洞就是这么来的)。

// 极度危险!不要这样写!
if (condition)
    doSomething();

// 规范写法
if (condition) {
    doSomething();
}

🎯 总结

  1. if 是分支结构的主力,适用于所有条件判断;switch 是等值匹配的利器,注意别忘了 break
  2. 多分支 if-else if 要注意条件顺序;switch 不支持浮点型和长整型。
  3. 实际开发中,要警惕深层嵌套,使用卫语句提前 return 优化代码结构。
  4. 好习惯:永远写上大括号 {}

💬 互动时间:你在开发中遇到过最离谱的 if-else 嵌套有几层?欢迎在评论区吐槽分享!如果觉得本文对你有帮助,别忘了点赞👍 + 关注❤️哦!

💡 给你的发布小贴士(发布前必看):

  1. 替换代码语言:如果你主要写C/C++,把代码块里的 java 换成 c,把 System.out.println 换成 printf,把 boolean 换成 bool 即可。
  2. 封面图:在CSDN发布时,加一张好看的封面图(比如一个岔路口的图片,或者代码截图)会大大增加点击率。
  3. 标签设置:在CSDN发布时,添加标签:Java基础初学者分支结构if-else编程思维,有助于获得更多系统推荐流量。

用户_jWywoW

我现在还要写一篇关于循环结构的csdn

思考结束

太棒了!写完分支结构,紧接着写循环结构,这两篇完全可以作为你的“程序控制流系列”博客,风格上我也帮你保持了统一,依然是用通俗易懂的比喻 + 代码示例 + 避坑指南的模式。

这篇以Java语法为基准(C/C++高度兼容,Python/Go等逻辑一致),直接复制即可发布!

标题建议(选一个你喜欢的):

  1. 拒绝重复造轮子!一文彻底搞懂循环结构
  2. 【Java基础】循环结构详解——for、while与do-while的相爱相杀
  3. 程序的“永动机”:掌握循环结构,看这篇就够了!

正文内容:

拒绝重复造轮子!一文彻底搞懂循环结构

📝 前言:在上一篇《程序的十字路口:一文搞懂分支结构》中,我们学会了如何让程序做选择。但现实世界中,很多时候我们需要重复做某件事,比如跑圈、比如批量处理数据。如果每次都把代码复制粘贴,不仅让代码臃肿不堪,维护起来更是灾难。这就是今天的主角——循环结构出场的时刻!

循环是计算机最擅长的能力(毕竟它本来就是个不知疲倦的机器)。本文将带你全面拆解三大循环语法,并分享如何写出高效、优雅的循环代码。🚀

🔄 一、 循环的本质:四要素

无论哪种循环语言,其核心都离不开这四个要素:

  1. 初始化语句:在循环开始前执行,通常用来定义循环变量(如 int i = 0)。
  2. 条件判断:决定循环是否继续执行,结果必须是布尔值(如 i < 10)。
  3. 循环体:需要重复执行的代码逻辑。
  4. 迭代语句(步进):每次循环后改变循环变量,让循环趋近于结束(如 i++)。

⚠️ 致命陷阱:如果缺少“迭代语句”或“条件判断永远为true”,程序就会陷入死循环,犹如脱缰的野马永远跑不停!

🏃‍♂️ 二、 三大循环语句

1. for 循环:精准控制的计数器

当你明确知道循环要执行多少次时,首选 for 循环。它的四要素最集中,一目了然。

// 语法:四要素一行搞定
for (初始化语句; 条件判断; 迭代语句) {
    // 循环体
}

// 示例:打印 1 到 5
for (int i = 1; i <= 5; i++) {
    System.out.println("当前是第 " + i + " 次循环");
}

执行顺序(面试常考):
① 初始化语句 -> ② 条件判断 -> ③ 循环体 -> ④ 迭代语句 -> ② 条件判断 -> ③ 循环体 -> … 直到条件为 false 退出。

2. while 循环:谨慎的侦察兵

当你不确定循环多少次,只知道满足某个条件就继续时,用 while。它是“先判断,后执行”,如果一开始条件就不满足,循环体一次都不会执行!

// 语法
初始化语句;
while (条件判断) {
    // 循环体;
    迭代语句; // 千万别忘了!
}

// 示例:折纸问题,一张纸厚0.1mm,对折多少次能超过珠穆朗玛峰(8848860mm)?
double thickness = 0.1;
int count = 0;
while (thickness < 8848860) {
    thickness *= 2; // 对折
    count++;        // 记录次数
}
System.out.println("需要折叠 " + count + " 次"); // 结果:27次

3. do-while 循环:先斩后奏的实干家

它和 while 的唯一区别是:先执行一次循环体,再判断条件。也就是说,无论条件是否满足,循环体至少会执行一次

// 语法
初始化语句;
do {
    // 循环体;
    迭代语句;
} while (条件判断); // ⚠️ 注意这里的分号千万不能丢!

// 示例:密码验证,至少需要输入一次
Scanner sc = new Scanner(System.in);
String password;
do {
    System.out.println("请输入密码:");
    password = sc.nextLine();
} while (!"123456".equals(password)); // 不是123456就继续输
System.out.println("密码正确,登录成功!");

⚔️ 三、 循环界的红黄牌:break 与 continue

循环就像一条环形跑道,而 break 和 continue 就是跑道上的出口和跳板。

关键字 作用 形象比喻
break 结束整个循环,跳出到循环外的代码 玩游戏直接拔电源 / 跑步直接离场
continue 跳过本次循环,直接进入下一次循环迭代 跑步跨过某一圈 / 玩游戏跳过当前关卡
// break 示例:找到数字 5 就停止寻找
for (int i = 1; i <= 10; i++) {
    if (i == 5) {
        System.out.println("找到了5,下班!");
        break; // 整个for循环直接结束,6-10都不会打印
    }
    System.out.println("正在寻找..." + i);
}

// continue 示例:逢7过(7的倍数不打印)
for (int i = 1; i <= 10; i++) {
    if (i % 7 == 0) {
        continue; // 跳过本次打印,直接执行 i++ 进入下一轮
    }
    System.out.println("当前数字:" + i);
}

🍬 四、 语法糖:增强型 for 循环

在遍历数组或集合时,如果不需要操作索引,强烈推荐使用增强型 for 循环(也叫 for-each 循环)。它简洁且不易出错。

int[] nums = {10, 20, 30, 40};

// 传统 for 循环
for (int i = 0; i < nums.length; i++) {
    System.out.println(nums[i]);
}

// 增强 for 循环(读作:从 nums 中依次取出每个 num)
for (int num : nums) {
    System.out.println(num);
}

⚠️ 注意for-each 无法获取当前索引,也不能在循环中修改数组/集合元素的值(对于基本类型),它只适合纯粹的“遍历读取”。

🚀 五、 进阶:循环优化与避坑指南

日常开发中,循环往往是性能瓶颈的重灾区。掌握以下技巧,让你的代码从“能跑”变成“跑得快”:

1. 避免在循环内部频繁创建对象

每次循环都 new 一个新对象,不仅消耗内存,还会增加垃圾回收(GC)的压力。

// ❌ 反例:每次循环都创建新对象
for (int i = 0; i < 10000; i++) {
    Date date = new Date(); // 极度浪费
    System.out.println(date);
}

// ✅ 正例:在循环外创建,循环内复用
Date date = new Date();
for (int i = 0; i < 10000; i++) {
    date.setTime(System.currentTimeMillis()); // 修改状态即可
    System.out.println(date);
}

2. 将耗时的计算移到循环外

不要让循环做无用的重复计算!

// ❌ 反例:list.size() 每次循环都要计算一次
for (int i = 0; i < list.size(); i++) { ... }

// ✅ 正例:提前算好,用常量接收
int len = list.size();
for (int i = 0; i < len; i++) { ... }

3. 尽量减少循环嵌套的层数

双层循环的时间复杂度是 O(n²),数据量一大,程序直接卡死。如果业务允许,尝试通过 Map 空间换时间 来减少嵌套。

// ❌ 反例:找两个列表的交集,双层嵌套,O(n²)
for (String s1 : list1) {
    for (String s2 : list2) {
        if (s1.equals(s2)) { ... }
    }
}

// ✅ 正例:用 HashSet 降维打击,O(n)
Set<String> set = new HashSet<>(list2);
for (String s1 : list1) {
    if (set.contains(s1)) { ... } // 查找复杂度降为 O(1)
}

🎯 总结

  1. 明确次数用 for,不明次数用 while,至少一次用 do-while
  2. break 彻底退出,continue 跳过本轮。
  3. 遍历数组/集合优先考虑 for-each,简洁优雅。
  4. 循环优化三大法:少创建对象、少重复计算、用Map降维减嵌套

循环是编程中最具魔力的结构,掌握它,你就掌握了让计算机为你“不知疲倦地打工”的秘密武器!

💬 互动时间:你在写循环时遇到过最头疼的Bug是什么?是死循环烧干CPU,还是数组越界?欢迎在评论区分享你的“血泪史”!如果觉得有收获,别忘了点赞👍 + 收藏⭐,下期见!

更多推荐