分支和循环

分支和循环

  • 在C语言中,程序的执行流程并非总是按照代码的书写顺序来执行的。为了更加灵活地控制程序的执行流程,C语言提供了重要的结构:分支结构,循环结构,顺序结构。
  • 我们可以用ifswitch实现分支结构,用forwhiledo-while实现循环结构

1.if语句

1.1 if语句的基本语法形式:

if(表达式)
	语句

表达式成立(为真),则语句执行,表达式不成立(为假),则语句不执行
(C语言中,0表示假,非0表示真)

#include <stdio.h>  
int main() {  
    int number;  
    printf("请输入一个整数:");  
    scanf("%d", &number); // 读取用户输入的整数  
  
    if (number % 2 == 1) {  
        printf("%d 是奇数。\n", number);  
    } 
    return 0;  
}

1.2 else

  • else语句的基本语法形式:
if(表达式)
	语句1
else
	语句2
#include <stdio.h>  
int main() {  
    int age;  
    printf("请输入年龄:");  
    scanf("%d", &age); // 读取用户输入的年龄  
  
    if (age >= 18) {  
        printf("成年\n");  
    } else {  
        printf("未成年\n");  
    }  
    return 0;  
}

注意

  • 分支中包含多条语句时,就必须使用大括号{}将代码括起来;
  • ifelse语句默认都只控制一条语句

2.关系操作符

C语言中用于比较的表达式 称为 “关系表达式”。里面运用的运算符就称为“关系运算符”
关系操作符包括:

小于(<)判断左边的操作数是否小于右边的操作数。
大于(>)判断左边的操作数是否大于右边的操作数。
小于或等于(<=)判断左边的操作数是否小于或等于右边的操作数。
大于或等于(>=)判断左边的操作数是否大于或等于右边的操作数。
等于(==)判断两个操作数是否相等。
不等于(!=)判断两个操作数是否不相等。
  • 关系表达式通常返回01,表示真假
  • 关系表达式常用于if,while结构

值得注意的是:
1.在使用关系操作符时,需要注意操作数的类型和数据结构,以确保比较操作的有效性和正确性。同时,也要注意避免将赋值操作符(=)与等于操作符(==)混淆,以免导致逻辑错误。
2.多个关系运算符不易连用,因为这可能会导致一些意外的结果或逻辑错误。如果必须连续使用多个运算符时,则必须清楚运算符的优先级和结合性,以确保代码按照预期执行。

3. 条件操作符(三目运算符)

  • 条件操作符(也称为三目运算符)在许多编程语言中都是一个非常有用的特性,它会根据某个条件的结果来返回两个值中的一个。
  • 其基本的语法形式如下:
exp1 ? exp2 : exp3

计算逻辑

  • 如果exp1为真,则返回exp2的值,即计算exp2的结果是整个表达式的结果;
    如果exp1为假,则返回exp3的值,即计算exp3的结果是整个表达式子的结果
  • 假设我们有一个简单的程序,它根据用户输入的分数来输出对应的等级。不使用三目运算符的形式如下:
#include <stdio.h>  
int main() {  
    int score;  
    printf("请输入分数:");  
    scanf("%d", &score);  
      
    char grade;  
    if (score >= 90) {  
        grade = 'A';  
    } else {  
        grade = 'B'; // 这里为了简化,只考虑了A和B两种等级  
    }  
      
    printf("等级是:%c\n", grade);  
    return 0;  
}

在这个例子中,我们使用了一个if-else语句来判断分数并设置等级。现在,我们将使用三目运算符来简化这段代码:

#include <stdio.h>  
  
int main() {  
    int score;  
    printf("请输入分数:");  
    scanf("%d", &score);  
      
    char grade = (score >= 90) ? 'A' : 'B'; // 使用三目运算符直接赋值  
      
    printf("等级是:%c\n", grade);  
    return 0;  
}

4.逻辑操作符

  • 逻辑运算符提供逻辑判断功能,用于构建更复杂的表达式,主要有下面三个运算符。
• !逻辑取反运算符(改变单个表达式的真假)。
• &&与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假)。
• ||或运算符,就是或者的意思(两侧⾄少有⼀个表达式为真,则为真,否则为假)。
4.1逻辑取反运算符( !)

在这里插入图片描述

#include <stdio.h>
int main()
{
int flag = 0;
if(!flag)
{
printf("do something\n");
}
return 0;
}

如果 flag 为真, !flag 就是假,如果 flag 为假, !flag 就是真
所以上⾯的代码的意思就是 flag 为假,执行if语句中的代码。

4.2与运算符( && )

与运算符

4.3 或运算符( || )
aba||b
非0非01
非001
0非01
000
4.4短路
  • 逻辑与(&&)的短路行为
    对于逻辑与运算符(&&),如果第一个操作数为假(即为0),则不会计算第二个操作数,因为无论第二个操作数的值是什么,整个表达式的结果都将是假。这是一种短路行为。
int a = 5, b = 0;
if (a > 0 && b > 0) {
    printf("a 和 b 均为正数");
}

由于a的值大于0,但b的值等于0,所以第一个操作数为真,但第二个操作数为假。因此,整个表达式的结果将为假,第二个操作数不会被计算,也就不会执行printf语句。

  • 逻辑或(||)的短路行为
    对于逻辑或运算符(||),如果第一个操作数为真(即非0),则不会计算第二个操作数,因为无论第二个操作数的值是什么,整个表达式的结果都将是真。这也是一种短路行为。
int a = 5, b = 0;
if (a > 0 || b > 0) {
    printf("a 或 b 为正数.");
}

由于a的值大于0,所以第一个操作数为真。无论第二个操作数的值是什么,整个表达式的结果都将为真,因此第二个操作数不会被计算,也就不会执行printf语句。

5.switch语句

  • 除了if语句外,C语言还提供switch语句来实现分支结构。
  • switch语句是一种特殊形式的if-else语句,用于判断条件有多个结果的情况。它把多重else-if语句改写成了更易用,可读性更好的形式;
  • switch语句的基本语法形式为:
switch (expression) {
  case value1:
    // 当expression的值等于value1时执行的代码
    break;
  case value2:
    // 当expression的值等于value2时执行的代码
    break;
  case value3:
    // 当expression的值等于value3时执行的代码
    break;
  default:
    // 当expression的值不等于任何一个case时执行的代码
    break;
}

switch语句的执行流程是:

  • 首先计算expression的值,
  • 然后依次与每个case后的值进行比较,
  • 当找到匹配的值时,就执行对应的代码块,并通过break语句跳出switch语句,
  • 如果没有找到匹配的值,则执行default代码块(如果有的话),
  • 最后结束switch语句。

5.switch语句和if语句的比较

#include <stdio.h>

int main() {
    int num = 2;

    // 使用switch语句
    switch (num) {
        case 1:
            printf("Number is 1\n");
            break;
        case 2:
            printf("Number is 2\n");
            break;
        case 3:
            printf("Number is 3\n");
            break;
        default:
            printf("Number is not 1, 2, or 3\n");
            break;
    }

    // 使用if语句
    if (num == 1) {
        printf("Number is 1\n");
    } else if (num == 2) {
        printf("Number is 2\n");
    } else if (num == 3) {
        printf("Number is 3\n");
    } else {
        printf("Number is not 1, 2, or 3\n");
    }

    return 0;
}

使用switch语句时,可以直接根据num的值进行匹配,并执行相应的代码块。而使用if语句时,需要使用多个if-else语句进行条件判断,每个条件都需要进行比较操作。

6.while循环

while(表达式)
	语句

while语句执行图

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

定义一个整数变量i并初始化为0。然后,我们使用while循环来检查i是否小于10。如果i小于10,我们就打印出i的值,并将i增加1。这个过程会一直重复,直到i不再小于10为止。因此,这个程序会打印出0到9这十个数字。

7.for循环

在这里插入图片描述
for循环的结构通常包括初始化、条件和迭代三个部分,它们一起控制循环的执行。

#include <stdio.h>  
  
int main() {  
    int i;  
  
    // for循环的结构:初始化; 条件; 迭代  
    for (i = 0; i < 10; i++) {  
        printf("%d\n", i);  
    }  
  
    return 0;  
}
  • for循环的初始化部分i = 0将i设置为0。
  • 接着,条件部分i < 10检查i是否小于10。
  • 如果条件为真(即i小于10),则执行循环体内的代码块(在这个例子中是printf语句)。
  • 然后,迭代部分i++将i的值增加1。这个过程会重复进行,直到i不再小于10为止。
  • 因此,这个程序将打印出0到9这十个数字。

8.do-while循环

在这里插入图片描述

do
	语句
while(表达式)

它与while循环类似,但有一个重要的区别:do-while循环至少会执行一次循环体,因为循环体是在检查条件之前执行的。这意味着即使初始条件不满足,do-while循环体内的代码也会执行一次。之后,它会检查条件,如果条件为真,则继续执行循环体;如果条件为假,则循环终止。

#include <stdio.h>  
  
int main() {  
    int i = 0;  
    do {  
        printf("%d\n", i);  
        i++;  
    } while (i < 10);  
    return 0;  
}
  • 定义一个整数变量i并初始化为0。
  • 然后,使用do-while循环来打印i的值,并将i增加1。
  • 与while循环不同的是,无论i的初始值是多少,循环体至少会执行一次。
  • 因此,即使初始时i不小于10,程序仍然会打印出i的初始值,
  • 然后因为条件不满足而退出循环。

9.breakcontinue语句

  • break 的作⽤是⽤于永久的终止循环,只要 break 被执行,直接就会跳出循环,继续往后执行。
  • continue 的作用是跳过本次循环 continue 后边的代码,在 for 循环和while 循环中有所差异的

10.goto 语句

  • C语言中的goto语句是一种无条件跳转语句,可以将程序的执行直接跳转到指定处,从而改变程序的执行顺序。
#include <stdio.h>  
  
int main() {  
    int i = 0;  
    int sum = 0;  
  
    for (i = 0; i < 10; i++) {  
        sum += i;  
  
        if (i == 5) {  
            printf("在 i 等于 5 时跳出循环。\n");  
            goto end_loop; // 跳转到标记的位置  
        }  
    }  
    end_loop: // 标记的位置  
    printf("循环结束,sum 的值为: %d\n", sum);  
    return 0;  
}
  • for 循环,用于计算 0 到 9 的整数和。
  • i 等于 5 时,我们使用 goto 语句跳转到标记为 end_loop 的位置,从而提前结束循环。
  • 然后,程序继续执行并打印 sum 的值。

10.随机数的生成

  • C语言中有一种函数叫rand函数,它可以生成随机数,原型如下:
    int rand (void);

  • rand函数会返回一个伪随机数,这个随机数的范围是0 ~ RAND_MAX之间,RAND_MAX取决于编译器,但大多数编译器上为32767.

  • rand函数的使用需要包含头文件<stdlib.h>

  • rand函数生成的随机数是伪随机的,是通过某种算法生成的随机数,因为rand函数是对一个叫“种子”的基准数运算生成的随机数,所以我们只要让种子随时变化就可以生成随机数

  • 所以C语言中提供了一个srand函数来初始化随机数的生成器

10.1 srand函数

  • srand函数,⽤来初始化随机数的生成器的,srand的原型如下:
void srand (unsigned int seed);

为了确保每次生成的随机数序列都是不同的,程序在调用rand函数之前会先调用srand函数来设置随机数的种子。srand函数的参数seed决定了随机数的种子,只要种子不同,生成的随机数序列就会不同。这就意味着,只要给srand函数的种子是随机的,rand函数就能生成随机数。然而,这就产生了一个矛盾:在生成随机数时又需要一个随机数

为了解决这个矛盾,可以使用当前的**系统时间**作为随机数的种子。由于系统时间是不断变化的,每次调用srand函数时都会传入一个不同的种子,从而生成不同的随机数序列.

  • 那我们要怎样用系统时间作为种子参数呢,那就涉及到time函数

10.2 time函数

time函数的原型如下:

time_t time(time_t* timer);
  • timer == NULL时得到当前日历时间(从1970-01-01 00:00:00到现在的秒数),
  • timer=时间数值时,用于设置日历时间,time_t是一个unsigned long类型。如果 timer不为空,则返回值也存储在变量 timer中。
  • time函数使用时需要包含头文件<time.h>

总的来说,由于系统时间是不断变化的,每次调用srand函数时都会传入一个不同的种子,从而生成不同的随机数序列。以下是一个示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
    // 使用当前系统时间作为种子
    srand(time(NULL));

    // 生成随机数
    for (int i = 0; i < 10; i++) {
        int randNum = rand();
        printf("%d\n", randNum);
    }
    return 0;
}

  • 首先调用srand函数,传入time(NULL)作为种子,以使用当前系统时间初始化随机数生成器。
  • 然后,使用for循环生成10个随机数,并使用printf函数将它们输出到控制台上。
  • 以至于每次运行程序时,生成的随机数序列都会不同。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值