C语言学习第四天

004_控制流

一、二路分支

核心逻辑​​:基于单一条件选择执行路径
if (条件)
{ 
    // 条件为真时执行 
} 
else 
{ 
    // 条件为假时执行 
}
​关键点​​:
  1. else必须依附if​:else不能独立存在。
  2. ​大括号不可省略​​:即使只有一行代码,也需用{}明确作用域。
  3. ​分号陷阱​​:if后误加分号(如if(条件);)会导致逻辑错误,无论条件是否成立均执行后续代码块。
  4. ​常见应用​​:
  • 输入验证(如判断数字奇偶性)
  • 简单条件筛选(如触摸屏坐标范围检测)
​示例问题​​:
if (num % 2 == 0); // 分号导致逻辑失效 
{ 
    printf("偶数"); // 无论num是否为偶数均会执行 
}

二、多路分支

核心逻辑​​:根据多个互斥条件选择不同执行路径
​两种实现方式​​:
  1. if-else if-else链​​:
if (条件1) { /* 代码1 */ }
else if (条件2) { /* 代码2 */ }
else { /* 默认代码 */ }
  • ​特点​​:灵活支持复杂条件表达式(如范围判断)。
  1. switch-case结构​​:
switch (整型表达式) {
    case 常量1: 代码1; break;
    case 常量2: 代码2; break;
    default: 默认代码;
}
  • ​限制​​:
    • case后必须为整型常量(如'A'或100),不能是变量或const修饰的“常量”。
    • 缺少break会导致“穿透”执行后续case。
​典型场景​​:
  • 菜单选择(如指纹识别流程控制)
  • 状态机实现(如界面跳转逻辑)
​易错点​​:
const int CODE = 100;
switch (num) {
    case CODE:  // 错误!const变量不被视为编译期常量
    case 100:   // 正确
        break;
}

三、const

核心作用​​:声明只读变量,防止意外修改
​语法​​:
const int num = 100; // 推荐写法 
int const num = 100; // 等效写法
​关键规则​​:
  • ​初始化必须​​:const变量定义时需赋值。
  • ​非真常量​​:C语言中const仅为“只读”提示,仍可通过指针间接修改(与C++不同)。
  • switch限制​​:case标签不接受const变量(因其非编译期常量)。
​示例​​:
const int MAX = 100; 
int *p = (int*)&MAX; 
*p = 200; // 未定义行为!可能引发运行时错误

四、while循环

核心逻辑​​:先判断条件,后执行循环体(可能零次执行)
​语法​​:
while (条件) { // 循环体 }
​应用场景​​:
  • ​不确定次数的循环​​(如读取用户输入直到合法)
  • ​事件轮询​​(如嵌入式设备状态检测)
​优化技巧​​:
  • while(1)+break​:替代do-while实现“至少执行一次”逻辑。
  • ​界面跳转​​:通过标志变量(如inf1_flag)控制多层循环嵌套。
​对比for​:
int i = 0; // 初始化 
while (i < 10)
 { // 条件 
printf("%d", i); 
i++; // 更新 
} 
// 等效for循环:
for (int i = 0; i < 10; i++)

五、do-while循环

核心逻辑​​:先执行循环体,后判断条件(至少执行一次)
​语法​​:
do { 
    // 循环体 
} while (条件); // 注意结尾分号
​独特价值​​:
  • ​输入验证​​:强制用户至少输入一次。
  • ​资源初始化​​:确保初始化代码至少运行一次。

六、for循环

核心逻辑​​:集初始化、条件检查、更新于一体
​标准语法​​:
for (初始化; 条件; 更新) 
{ 
    // 循环体 
}
​灵活变体​​:
  • ​省略表达式​​:for (;;)等效while (1)。
  • ​逗号运算符​​:多变量控制(如for (i = 0, j = 10; i < j; i++, j--))。
​底层开发注意​​:
  • 某些嵌入式编译器要求循环变量在for外声明(如int i; for (i=0; ...))。
​示例陷阱​​:
for (int i = 0; i < 5; i++); // 分号导致空循环 
{ 
    printf("%d", i); // 错误!i的作用域仅限于for循环 
}

七、break和continue

 

​使用场景​​:
  • break​:
    • 提前终止循环(如找到目标元素时退出搜索)
    • 避免switch穿透
  • continue​:
    • 跳过无效数据(如处理数组时忽略负数)
    • 优化循环效率(如仅处理偶数)
​嵌套循环注意​​:break仅跳出当前层循环,如需跳出多层需配合标志变量。

八、goto语句

核心逻辑​​:无条件跳转到标签处
​合理使用场景​​:
  1. ​错误处理​​:集中释放资源(如goto cleanup;)。
  2. ​深层嵌套退出​​:快速跳出多层循环(替代多个break)。
​争议与规范​​:
  • ​反对理由​​:破坏结构化编程,降低可读性。
  • ​最佳实践​​:
    • 限制跳转方向(只向前或只向后)
    • 避免在循环和switch中使用goto
​示例(错误处理)​​:
if (open_file() == FAIL) 
    goto error; 
if (read_data() == FAIL) 
    goto error; // ...正常流程... 


error: 
    close_file(); 
    return FAIL;

实验

【1】、实验1:(循环控制)

编写一个程序,输出26个小写字母。
解题思路​​:
  1. ​字符变量初始化​​:从'a'开始,ASCII码值为97。
  2. ​循环结构选择​​:

【2】、实验2:(循环控制)

编写一个程序,在用户输入某个大写字母后,产生一个金字塔图案。
例如:输入字母E,则产生如下图案:
提示:找规律
解题思路​​:
  1. ​输入处理​​:读取大写字母(如'E'),计算层数(layers = ch - 'A' + 1)。
  2. ​双层循环设计​​:
  • ​外层循环​​:控制行数(1到layers)。
  • ​内层循环​​:
    • ​空格​​:每行空格数为layers - current_row。
    • ​升序字母​​:从'A'输出到'A' + current_row - 1。
    • ​降序字母​​:从'A' + current_row - 2反向输出到'A'。

【3】、实验3:(循环控制、多路分支)

编写一个程序,接收用户的输入信息,当用户输入完成后('#'代表输入完成),自动统计用户输入的空格数、大小写字母数和其他字符数。
提示:scanf函数如何输入空格字符?
char buf[128] = {0}; 
scanf("%[^#]", buf); // 除非遇到#号,否则不退出输入界面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值