C语言笔记3:输入输出与分支循环
2026/4/15 6:56:09 网站建设 项目流程

在C语言的学习中,流程控制是构建程序逻辑的核心,它决定了程序的执行顺序和执行逻辑,也是从基础语法过渡到实际程序开发的关键环节。本次总结围绕C语言流程控制展开,涵盖数据的输入与输出分支结构循环结构三大核心模块,梳理了printf/scanf格式化输入输出的细节、分支结构的多种实现方式、循环结构的使用技巧及典型案例,同时整理了各类语法的注意事项和实际开发中的避坑点,适合C语言初学者巩固基础,也可作为日常开发的速查笔记。

一、数据的输入与输出

输入输出是程序与用户交互的基础,C语言中通过标准库函数printf(输出)和scanf(输入)实现,核心是格式化符的正确使用输入输出的格式控制,需引入头文件#include <stdio.h>

1. 格式化输出printf

语法:printf("格式化控制字符串", 输出列表);

  • 格式化控制字符串:由格式说明符%+特定字符)和普通字符(原样输出)组成;
  • 输出列表:可包含常量、变量、表达式,个数需与格式说明符一一对应。
常用格式说明符

涵盖整型、字符型、字符串型、浮点型、指针型等,是printf的核心,需匹配数据类型:

格式符对应类型功能说明
%d/%uint/unsigned int十进制有符号/无符号整数
%cchar单个字符
%schar[]字符串(以\0结尾)
%f/%lffloat/double小数形式浮点型(%f兼容float/double,%lf仅double)
%e/%Efloat/double指数形式浮点型
%ld/%lldlong/long long长整型/长长整型
%x/%#xint/unsigned int十六进制输出(%#x带0x前缀)
%o/%#oint/unsigned int八进制输出(%#o带0前缀)
%p指针类型输出内存地址(十六进制,带0x前缀)
%%-输出百分号%本身
输出格式精细化控制

可指定宽度、对齐方式、保留小数位数等,实现格式化输出的定制化:

  • 整型:%[标志]m类型,如%6d(右对齐,宽度6)、%-6d(左对齐)、%06d(0填充)、%+6d(强制显示正负号);
  • 字符串:%[标志]m.ns,如%7.2s(宽度7,截取前2个字符)、%-5.3s(左对齐,宽度5,截取前3个字符);
  • 浮点型:%[标志]m.nf/%m.ne,如%8.2f(宽度8,保留2位小数,四舍五入)、%9.2e(指数形式,保留2位尾数);
  • 自动适配:%g/%G,自动选择%f%e中更简洁的格式,去除无意义的末尾0和小数点。

2. 格式化输入scanf

语法:scanf("格式化控制字符串", 地址列表);
核心作用:将键盘输入的数据存入地址列表指定的内存单元,地址列表必须是内存地址(普通变量加&取地址,字符串数组直接用数组名)。

核心注意事项
  1. 格式说明符需与输入数据类型、地址列表顺序一一对应,浮点型输入需严格区分:%f对应float,%lf对应double;
  2. 若格式化控制字符串包含普通字符(如,-、文字),输入时需在对应位置输入相同字符;
  3. %c会读取输入缓冲区的空白字符(空格、Tab、\n),需在%c前加空格跳过,如%c %c %c
  4. 可指定输入宽度(如%3d截取前3位),或用%*d跳过指定列数的输入;
  5. 实型输入不能用m.n的形式(如%7.2f是错误用法)。
输入缓冲区机制

程序启动时开辟输入缓冲区,执行scanf时先检查缓冲区:有数据则直接读取,无数据则等待用户输入,需注意缓冲区残留的空白字符对后续输入的影响。

3. 常见错误

格式说明符与数据类型不匹配,会导致输出/输入异常(如用%d输出double类型,会得到随机值),需严格保证类型一致,必要时使用强制类型转换

二、分支结构

分支结构根据条件表达式的真假(C语言中非0为真,0为假)决定程序的执行路径,分为单分支双分支多分支,核心是条件表达式的构建和分支语句的嵌套使用。

1. 条件表达式基础

分支的判断依赖关系表达式逻辑表达式,二者结果均为逻辑值(1为真,0为假)。

关系运算符(6种)

<<=>>===!=,优先级低于算数运算符,高于逻辑运算符。

逻辑运算符(3种)
  • &&(逻辑与):两边均为真则真,左假则右短路
  • ||(逻辑或):两边均为假则假,左真则右短路
  • !(逻辑非):单目运算符,真变假,假变真。
    优先级:!> 算数运算符 > 关系运算符 >&&>||> 赋值运算符。

2. if语句实现分支

单分支(if)

语法:if (条件表达式) { 语句块; }

  • 条件为真则执行语句块,为假则跳过;
  • 单语句可省略{},但建议始终添加,提升代码可读性。
双分支(if…else…)

语法:if (条件表达式) { 语句1; } else { 语句2; }

  • 条件为真执行语句1,为假执行语句2,二者必选其一;
  • else必须与最近的未配对if匹配,可通过{}强制指定配对关系。
多分支(if…else if…else…)

语法:if (表达式1) { 语句1; } else if (表达式2) { 语句2; } ... else { 语句n; }

  • 条件判断顺序执行,找到第一个真条件后执行对应语句,后续不再判断;
  • else为可选部分,无匹配条件时执行。
if语句嵌套

if语句内部包含另一个完整的if/if…else,即为嵌套结构,嵌套层级建议≤3~4层,避免代码可读性差;需注意else的配对规则,必要时用{}明确作用域。

3. 三目运算符(简化双分支)

语法:表达式1 ? 表达式2 : 表达式3;

  • 本质是单语句双分支if的简写,仅适用于单语句场景;
  • 表达式1为真,执行表达式2并返回其值;为假则执行表达式3并返回其值;
  • 优先级:高于赋值运算符,低于逻辑运算符。

4. switch语句实现多分支

专门用于条件为离散值(整型、字符型)的多分支场景,比if多分支更简洁,语法:

switch(表达式){case常量表达式1:语句1;break;case常量表达式2:语句2;break;...default:语句n;break;}
核心规则
  1. 表达式结果必须是整型/字符型,不能是浮点型或字符串;
  2. case后的常量表达式值必须唯一,否则编译报错;
  3. break用于跳出switch,无break会触发穿透效应(执行完当前case后继续执行后续case);
  4. 多个case可共用一组语句(无需重复编写);
  5. default为可选部分,无匹配case时执行,建议写在所有case最后。
适用场景

当判断条件为固定值的等值判断时(如成绩等级、月份判断季节、简易计算器),优先使用switch;若为范围判断,则适合用if多分支。

三、循环结构

循环结构实现代码的重复执行,分为有限循环(指定循环次数/终止条件)和无限循环(死循环,谨慎使用),C语言中主要通过whilefor实现当型循环(先判断,后执行),核心是循环三要素:循环变量初始化、循环条件、循环变量更新,三者需形成闭环,否则会导致死循环。

1. while循环

语法:

// 循环变量初始化while(循环条件){// 条件为真执行循环体循环体语句;循环变量更新;// 向循环出口逼近}
  • 特点:先判断,后执行,循环体可能一次都不执行;
  • 单语句可省略{},循环条件为1时为死循环(while(1));
  • 适用场景:循环次数不确定的场景,仅知道循环终止条件。
典型案例
  1. 累加和/累乘积计算(1~100累加和、偶数和);
  2. 水仙花数判断(拆分数字的各位,计算n次幂之和);
  3. 清空输入缓冲区(while(getchar() != '\n');)。

2. for循环

for循环是while循环的特殊写法,结构更清晰,适合循环次数确定的场景,语法:

for(循环变量初始化;循环条件;循环变量更新){循环体语句;}
核心规则
  1. ()内的三个部分均可省略,但若省略循环条件,即为死循环(for(;;));
  2. 循环变量可初始化多个(用逗号分隔),更新也可多个(用逗号分隔);
  3. 执行顺序:初始化 → 判断条件 → 执行循环体 → 更新变量 → 再次判断条件,直至条件为假。
典型案例
  1. 阶乘计算(n! = 1×2×…×n);
  2. 斐波拉契数列生成(前两个数为1,后续每个数为前两个数之和);
  3. 固定次数的遍历、统计(如统计10个整数中的正数个数)。

3. 循环的核心注意事项

  1. 循环变量的初始化需在循环外(while)或for的初始化部分,避免每次循环重新初始化;
  2. 循环变量的更新必须存在,且能逐步让循环条件变为假,否则会陷入死循环;
  3. 浮点型数据因精度问题,不宜作为循环条件的判断依据(如while(f == 0.1));
  4. 循环体中可通过break(跳出循环)、continue(跳过本次循环,进入下一次)控制循环执行(后续拓展知识点)。

4. 典型循环案例

  1. 水仙花数/四叶玫瑰数查找(拆分数字各位,计算n次幂之和);
  2. 累加/累乘运算(含条件的累加,如奇数和、指定规律的数列和);
  3. 数列生成(斐波拉契数列、等差数列/等比数列);
  4. 数据统计(如统计输入数据的最大值、平均值)。

四、核心避坑点与编程规范

  1. 格式符匹配printf中%f兼容float/double,scanf中%f仅对应float、%lf仅对应double,严格匹配避免数据错误;
  2. scanf地址:普通变量必须加&取地址,字符串数组直接用数组名,避免编译错误;
  3. else配对:if/else嵌套时,用{}明确作用域,避免else匹配错误;
  4. switch穿透:除多case共用语句外,每个case末尾必须加break,避免逻辑错误;
  5. 循环三要素:确保循环变量初始化、条件、更新形成闭环,杜绝死循环;
  6. 变量初始化:局部变量未初始化会为随机值,使用前必须赋值,全局变量/静态变量默认初始化为0;
  7. 代码可读性:分支/循环的单语句也建议添加{},嵌套层级不宜过深,合理添加注释。

五、总结

流程控制是C语言程序的“骨架”,输入输出是程序与用户交互的基础,核心在于格式化符的灵活使用和输入输出的细节把控;分支结构实现了程序的“选择逻辑”,if语句适合范围判断,switch语句适合离散值的等值判断,三目运算符简化单语句双分支;循环结构实现了程序的“重复逻辑”,while适合循环次数不确定的场景,for适合循环次数确定的场景,二者的核心都是循环三要素的闭环。

掌握流程控制的关键在于理解语法规则+多做实际案例,从简单的累加、判断开始,逐步实现复杂的程序逻辑(如简易计算器、阶梯电价计算、百钱买百鸡等),在实践中熟悉避坑点,形成良好的编程习惯,为后续的数组、函数、指针等高级知识点打下坚实基础。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询