03流程控制

C语言-流程控制

一、C语言关系运算符

运算符说明例子
==等于a == b
!=不等于a != b
<、>小于和大于a > b, a < b
<=(=<)、=>(>=)小于等于和大于等于a <= b, a >= b
!!(0)、!(NULL)

逻辑返回值:bool 类型的 true 和 false。

false:0, null,‘\0’

!!(x): 逻辑归一化。假如 x = 3, !3 = 0, !!3 = 1。

二、分支结构

1. if 语句(选择语句)

// 第一种
if (表达式) {
}
// 第二种
if (表达式) {
	代码段1;
} else {
    代码段2;
}
// 第三种
if (表达式1) {
	代码段1;
} else if (表达式2){
    代码段2;
} else {
    代码段3;
}

if 作用一条语句(语句:单语句(分号结尾),复合语句(一个花括号所表示的一条语句))。

随堂练习-1

程序读入一个正整数 n,代表学生的成绩,根据分数输出分数档位。

n = 0, FOOLISH

0 < n < 60, FAIL

60 <= n < 75, MEDIUM

75 <= n <= 100, GOOD

代码演示

#include <stdio.h>

int main() {
 int n;
 while(~scanf("%d", &n)) {
     if (n == 0) {
         printf("FOOLISH\n");
     } else if (n > 0 && n < 60) {
         printf("FAIL\n");
     } else if (n >= 60 && n < 75) {
         printf("MEDIUM\n");
     } else {
         printf("GOOD\n");
     }
 }
 return 0;
}

优化:

#include <stdio.h>

int main() {
 int n;
 while(~scanf("%d", &n)) {
     if (!n) {
         printf("FOOLISH\n");
     } else if (n < 60) {
         printf("FAIL\n");
     } else if (n < 75) {
         printf("MEDIUM\n");
     } else {
         printf("GOOD\n");
     }
 }
 return 0;
}

2. switch 语句

switch (a) {
    case 1: 代码块1;
    case 2: 代码块2;
    case 3: 代码块3;
   	default : 代码块;
}

case 作为条件入口,程序进入 case 所对应的代码段,依次执行后续代码,直到遇到 break,或者 switch 结构末尾。a 要能映射成一个整形值。

随堂练习-2

请使用 switch 结构完成如下任务,程序读入一个整数 n:

​ 如果 n = 1:输出 one

​ 如果 n = 2:输出 two

​ 如果 n = 3:输出 three

​ 否则输出 error

代码:

#include <stdio.h>

int main() {
 int n;
 while (~scanf("%d", &n)) {
     switch (n) {
         case 1: {
             printf("one\n");
             break;
         }
         case 2: {
             printf("two\n");
             break;
         }
         case 3: {
             printf("three\n");
             break;
         }
         default: {
             printf("error\n");
             break;
         }
     }
 }
 return 0;
}

题目练习:回文整数。

操作系统底层:
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
// likely 代表 x 经常成立
// unlikely 代表 x 不经常成立

代码:
bool isPalindrome(int x) {
    // x < 0 是不经常出现的(这是站在 cpu 指令执行层面的代码优化)
    if (__builtin_expect(!!(x < 0), 0)) return false; // 等价于 if (x < 0) return false;
    int y = 0, z = x;
    while (x) {
        y = y * 10 + x % 10;
        x /= 10;
    }
    return z == y;
}

cpu 不喜欢分支结构,因为指令预加载,容易出错,cpu 有自带的分支预测功能,但是有可能失败。一旦发现分支预测之后的结果是错误的, 会回滚之前的操作。之前 cpu 的并行操作,也就相当于变成了串行操作。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tzbiejS3-1633061052375)(C:\Users\24980\AppData\Roaming\Typora\typora-user-images\image-20210930145538950.png)]

相关系列函数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uZobhMRj-1633061052377)(C:\Users\24980\AppData\Roaming\Typora\typora-user-images\image-20210930150056641.png)]

对于 if else 语句,我们可以用三目运算符去代替: ? : ,这样的话在 cpu 的底层就不需要分支预测。

三、循环结构

1. while 循环

// 每当表达式为真时,代码块就执行一次
while (表达式) {
	代码块;
}

// 每当代码段执行一次,就会判断一次表达式是否为真
do {
    代码块;
} while (表达式);

一般情况下,两种循环没有差异,都能完成相关任务。但是 while 与 do/while 的循环的差别仅在 while 至少做 0 次,后者至少做一次。

随堂练习-3

请使用 while 循环实现程序,输出 1 – 100

#include <stdio.h>

int main() {
    int n = 1;
    while (n <= 100) {
        printf("%d\n", n);
        n++;
    }
    return 0;
}
#include <stdio.h>

int main() {
    int n = 1;
    do {
        printf("%d\n", n);
        n++;
    } while (n <= 100);
    return 0;
}

2. for 语句

for (初始化;循环条件;执行后操作) {
	代码块;
}

step 1:初始化

step 2:循环条件判断

step 3:执行代码块

step 4:执行后操作

step 5:跳转到 step2

在使用变量前最近的地方定义变量。在 for 循环里,++i 要比 i++ 快,这是底层实现决定的,后++ 涉及值拷贝的问题。

逻辑与或者逻辑或配合表达式也能实现条件判断。比如: i && printf(“ ”);

回文数字判断

能对 int32 实现判断,因为当超过一定大小之后,如果不是回文数,翻转会超出 INT32_MAX = 2147483647,计算机会用一个负值去表示,也就不影响程序的正确性。

#include <stdio.h>

int rev_num(int n) {
    if (n < 0) return 0;
    int x = n, temp = 0;
    while (x) {
		temp = temp * 10 + x % 10;
        x /= 10;
    }
    return temp == n;
}

int main() {
	int n;
    scanf("%d", &n);
    printf("%s\n", rev_num(n) ? "yes" : "no");
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白的Soda

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值