一、流程控制分类

流程控制可分为以下三种类型:

  1. 顺序结构
    代码从main函数开始,按编写顺序逐条执行,直至程序结束。

  2. 分支结构
    代码从main函数开始,根据条件判断选择性地执行特定代码块,直至程序结束。

  3. 循环结构
    代码从main函数开始,对特定代码段进行重复执行,直至满足终止条件后继续执行后续代码。

① 顺序结构的流程图

② 分支结构的流程图

③ 循环结构的流程图

二、关系运算符、逻辑运算符、三目运算符

2.1 关系(比较)运算符

    关系(比较)运算符,操作的对象数据类型 (int float double)

比较运算符 功能 备注
> 大于;双目
>= 大于等于;双目
< 小于;双目
<= 小于等于;双目
== 等于;左右两边等值;双目 注意和 =(赋值) 的区别
!= 不等于;左右两边不等值;双目

使用关系运算符连接的式子 → 关系表达式

  • 关系表达式的值:逻辑结果(1表示真,0表示假)
  • 关系表达式的类型:int
    • 由于int类型的值域范围较大,除0和1外还包含其他数值
    • 因此遵循原则:非0即为真

2.2 逻辑运算符

   操作对象逻辑值 ( 0 ,1 )

运算符 功能
&& 逻辑与;双目
|| 逻辑或;双目
逻辑非;单目

逻辑表达式:返回值为 int 类型;逻辑结果:1(真)或 0(假)

逻辑与运算:当左值和右值同时为真时,整个表达式的值才为真(必须全部为真)。

逻辑或运算:当左值或右值中有一个为真时,整个表达式的值即为真(只需一个为真)。

逻辑非运算:这是单目运算符,具有右结合性。它将真值取反:真变假,假变真。

截断效应,短路效应 ,(&& 和|| 运算符有关)

     对于 && 运算符:当左操作数为假时,整个表达式结果为假,右操作数不会被执行。

     对于 || 运算符:当左操作数为真时,整个表达式结果为真,右操作数不会被执行。

#include <stdio.h> 
int  main()
{
    // 比较运算符
    3  > 5;  // 关系表达式比较,类型 int, 值 0 
// 这个地方是比较操作,在比较运算符的左值和右值,都可以是常量,变量,表达式 .只会读左右值,不会写入。
    3>=5; //  值  0
    3 ==  5;  // 值  0  假  

    int num =20;
    num >  10 ;   //  int类型,值为 1 
    10 > num ;   // int类型 值为 0 

    num  ==   20 +10; 
    ++num  !=  15;    // int类型,值为 1 
    printf("3>5 is  %d\n",3>5 );  // 3>5 is 0
    printf("3>5 is  %lu\n",sizeof(3>5) );  //3>5 is  4 

    int num = 5;
    num > 0  && num <10 ;  // 相当于 0<num < 10; 
    num >0 || num  <10;   //   1  int 
    !num ;  // !5   ,  0  int 
    
    int b = 1;
    num =0 ; 
    // 对于 &&操作,如果左操作数为 0 的情况下,右操作数是不会执行的。
    printf("express num&& b++ is  %d\n",num  && b++) ; //  表达式的值 0  ; b==1 
    printf("b is  %d\n",b);  //1

    num = 5; 
    // 对于 ||操作,如果左操作数为 1 的情况下,右操作数是不会执行的。
    printf("express num || b++ is  %d\n",num  || ++b) ; //  表达式的值1  ; b ==1  
    printf("b is  %d\n",b);  // b is  1
    return 0;
}

2.3 三目运算符(条件运算符

语法:条件表达式 ? 表达式1 : 表达式2

运算符的结合方向从右向左;

运算符的结合方向有3个是自右至左:单目运算符、赋值运算符、三目运算符;

当 条件表达式 为 真 时,返回表达式 1 的值;否则返回表达式 2 的值。

#include <stdio.h>
int main()
{
    int num1 = 0 ;
    int num2 = 0;
    int max = 0 ;
    printf("找两数的最大数 :");
    scanf("%d%d",&num1,&num2);
    //  比较 num1 > num2 ,如果为真 ,整个表达式的值 num1 ,否则是num2
    max =  num1 > num2 ? num1:num2;
    printf("max is %d\n",max);

    int num1 = 0;
    int num2  = 0 ;
    int num3 = 0 ;
    int max =  0;
    printf("找3 数的最大数 :");
    scanf("%d%d%d",&num1,&num2,&num3);
    max =  num1 >num2 ? num1:num2;
    max = max> num3 ? max:num3;
    printf("max is %d\n",max);
    return 0;
}

三、分支结构

3.1 if--else

3.1.1 单分支结构

if ( 表达式 )   //  现对表达式进行求值, 如果表达式值为真,则执行 if 后紧挨着的代码块语句
  {
     

      代码块;

  }

#include <stdio.h>
int main()
{
    int num1 = 10;
    int num2 = 10;
    if(num1 ==  num2)
    {
        printf("num 1  num2  相等\n");
    }

    int num1 =0;
    int num2 = 0 ;
    printf("input 2 num:");
    scanf("%d%d",&num1,&num2);
    int max = num2 ;
    if(num1>num2)
    {
        max = num1;
    }
    printf("max is %d\n",max);
    return 0;
}

3.1.2 二分支结构

if( 表达式 ) // 对表达式求值,如果为真 ,就执行语句块1; 如果为假 ,就执行语句块2;

  {     

         语句块1;

   }

else    

  {    

         语句块2;

   }

#include <stdio.h>

int  main()
{
    int num1=0,num2=0,min=0,temp=0;
    printf("inpute 2 num:");
    scanf("%d%d",&num1,&num2);

    if(num1<num2)
    {
        min = num1;
    }
    else  
    {    
        min = num2;
        temp = num1;
        num1 = num2;
        num2 = temp; 
    }
    printf("min :%d\n",min);
    printf("num1:%d num2:%d\n",num1,num2);
    return 0;
}
#include <stdio.h>
int main()
{ 
    int num1 =0;
    int num2 = 0 ;
    int max = 0 ;
    printf("input 2 num:");
    scanf("%d%d",&num1,&num2);
    //二分支流程  
    if(num1 > num2)
    {
        max = num1;
    }
    else 
    {
        max = num2;
    }
    printf("max is %d\n",max);
    return 0;
}

注意:1)实现判断逻辑时需使用 if-else 语句。
           2)if 后面要紧跟表达式,并且要使用圆括号括起来。
           3) if 可单独使用,但 else 必须与 if 配对出现,else会和最近的if配对 。
           4) 建议将 if/else 的执行语句都用大括号包裹。
           5) if(表达式)、else 后面不要加分号,会出现逻辑错误。

实现两个数进行交换

#include <stdio.h>
int main()
{
    int a = 10;
    int b = 20;
    printf("before a %d, b %d\n", a, b);

    int temp = 0;
    temp = b;
    b = a;
    a = temp;
    printf("atfter a %d, b %d\n", a, b);
    return 0;
}

3.1.3 阶梯分支结构

if (表达式 1 )

{

    语句块1;

}

else if( 表达式 2 )

{

    语句块2;

}

else if( 表达式 3 )

{

     语句块3;

}

     ....

else

{

      语句块n;

}

流程图:

#include <stdio.h>
int main()
{
    int cost =  0;
    printf("1,幼儿园,100\n");
    printf("2,小学生,200\n");
    printf("3,初中生,300\n");
    printf("4,高中,400\n");
    int stu = 0 ;
    scanf("%d",&stu);
    if( 1 == stu ) // 等值比较 ,常量放左边
    {
        cost = 100;
    }
    else  if (2 == stu)
    {
        cost  =200;
    }
    else if(3 == stu)
    {
        cost = 300;
    }
    else  
    {
        cost = 400;
    } 
    printf(" stu : %d cost :%d\n",stu,cost);
    return 0;
}

3.1.4  if 嵌套形式

//   不建议嵌套层数太多 , 3-5 层。 多了就不要阅读。
if(表达式1) 
{
    if(表达式2)
    {
        if(表达式3)        等价于       if(表达式1 && 表达式2 && 表达式3)
        {
                       
                 语句1; 
            
        }
    }
}

#include <stdio.h>
int main()
{
    int score = 0;
    printf("input score:");
    scanf("%d",&score);

    if(score>=0 && score<=100)
    {
        if(score>=90 && score<=100)
        {
            printf("A\n");
        }
        else if (score >=80 && score<90)
        {
            printf("B\n");
        }
        else if (score >=70 && score<80)
        {
            printf("C\n");
        }
        else if (score >=60 && score<70)
        {
            printf("D\n");
        }
        else 
        {
            printf("E\n");
        }
    }
    else 
    {
        printf("输入错误\n");
    }

    return 0;
}

3.2 switch(多分支情况)

switch(整形表达式)

{

   case 整形常量表达式1: // 5

            语句块1;

            break;

   case 整形常量表达式2: // 6 

            语句块2;

            break;

    case 整形常量表达式3: // 7

            语句块3;

            break;

 default: 

            语句块n;

}

整形表达式计算的结果会与 case 后面的整型常量表达式进行等值比较。若值相等,则执行该 case 对应的语句块,直至遇到 break 为止。

② break 表示终止执行。在 switch 语句中,遇到 break 意味着当前分支结束。

③ default 为可选分支。若存在且所有 case 均未匹配成功时,将执行 default 对应的语句块。通常将其置于末尾。

注意:

     ① switch 后面必须是一个整形表达式

     ② case 后面必须是整形的常量 ,不能是变量或表达式

     ③ 如果 case 后面没有 break 则会顺序向下执行。

#include <stdio.h>
int  main()
{
    int cost = 0;
    int stu = 0 ;
    printf("1,幼儿园,100\n");
    printf("2,小学生,200\n");
    printf("3,初中生,300\n");
    printf("4,高中,400\n");
    printf("5, tech\n");

    scanf("%d",&stu);
    switch( stu )
    {
    case  1:
        printf("幼儿园\n");
        cost =100;
        break;
    case  2:
        printf("小学生\n");
        cost =200;
        break;
    //  3 ,5 情况 后续处理是一样的
    case  5:
    case  3:
        printf("初中生\n");
        cost =300;
        break;
    default :
        printf("其他\n");
        cost =400;
    }
    printf("你花费是 %d\n",cost);
    return 0;
}
#include <stdio.h>
int main()
{
    int score =  0;
    char c = 0;
    printf("input 0-100:");
    scanf("%d",&score);

    if(score>=0 && score<=100)
    {
        switch(score/10)
        {
            case 9:
            case 10:
                c ='A';
                break;
            case 8:
                c ='B';
                break;
            case 7:
                c ='C';
                break;
            case 6:
                c ='D';
                break;
            default:
                c='E';
        }
        printf("grade is %c\n",c);
    }
    else  
    {
        printf("input  error\n");
    }
    return 0;
}

四、循环结构

① 含义:代码执行的时候,有多次执行同一段代码需求。

    如果执行次数已知,可以使用 for 循环

    如果执行次数未知,可以使用 while 循环

② 循环三要素:

1) 初始化循环控制变量;

2) 检测循环条件是否满足;

3)循环中,需要包含控制变量变化的语句如 ++,-- 操作;

4.1 while 循环

while(表达式)

{

    循环体;

}

注意:

① 表达式是一个逻辑判断值:1 表示 true,0 表示 false。

② 循环执行流程:

    1)对表达式求值:

          若结果为 1(真),执行循环体;否则结束循环。

    2)执行循环体内的代码;

    3)重复步骤 1;

③ 循环体内需包含能使循环趋于结束的变量控制(如自增/自减操作)

④ while(表达式) 后不要加分号,控制循环变量要初始化

⑤ 死循环 
    while(1)//   循环会一直运行
    {
         循环体;
     }

#include <stdio.h>
#include <unistd.h>
int main()
{
    int sum = 0 ;
    int i = 0 ;
    while(i<10)
    {
        printf(" i is %d\n",i);
        sum =  i+ sum;
        ++i;
    }
    printf("0-9 sum  is  %d\n",sum);
    
    int i = 0 ; // index 
    //  死循  ctrl+c  停止程序
    while(1)
    {
        printf("%d\n", i++);
        sleep(1); // 休眠 1s  
    }

    int i = 100 ;
    while(i)
    {
        if(0 ==  i%3  )
        {
            printf(" %%3 == 0  is %d\n",i);
        }
        i--;
    }
return 0;
}

4.2 for 循环

4.2.1 单层 for 循环

for(表达式1;表达式2;表达式3)
 {
    循环体;
 }

   表达式1 :用于在循环开始前初始化变量;
   表达式2:决定循环是否继续执行的条件判断。如果为真,循环执行,否则循环停止;
   表达式3:用于修改循环控制变量的值如(++,--)

执行的流程
1)初始化阶段:执行表达式1,完成控制变量初始化(仅在循环开始时执行一次)。
2)条件判断阶段:对表达式2进行求值,如果为真,执行循环体。否则终止循环
3)执行循环体代码
4)执行表达式3, 更新控制变量(如i++、i--等)
5)跳转回步骤2,进行下一次循环条件判断

死循环形式
 for(;;)   //  分号不可以省略
 {
    循环体;

 }

#include <stdio.h>
#include <unistd.h>
int main()
{
    int i = 0 ;
    /*
    for(i=0;i<10;i++)
    {
        printf("i is %d\n",i);
    }
    for(;i<10;i++)
    {
        printf("i is %d\n",i);
    }

    for(;;)
    {
        printf("i:%d\n",i++);
        sleep(1);
    }
    */
    for(i=0;i<=100;i++)//  0-100
    {
        if( 0 == i % 7)
        {
            printf("i:%d\n",i);
        }
    }
 return 0;
}

4.2.2 双层 for 循环

int i =0;
int j = 0 ;  // 外层循环 j++ 一次 ,则内层循环 执行5次
for(j=0;j<3;j++) // 外层
{

    for(i=0;i<5;i++)// 内层循环
     {
         语句;
     }
}

输出九九乘法表

#include <stdio.h>
int main()
{
    int i = 0 ;
    int j = 0 ;
    for(j = 1 ;j <=9;j++)// row  
    {
        
        for(i=1;i<=j;i++)
        {
            printf("%d*%d=%d ",i,j,j*i);
        }
       // printf("\n");
       puts(" ");  //会输出\n
    }
return 0;
}

4.3 goto 循环语句

goto 语句是一种无条件跳转语句。

使用限制:只能在当前函数内部跳转,功能类似于汇编语言中的 jmp 指令

使用规范:

  •  在应用层程序开发中应避免使用
  • 在 Linux 内核编程中常用于错误处理场景

#include <stdio.h>
int  main()
{
    int i = 0 ;
    int sum = 0;
    //标号
loop:    
    sum+=i;
    i++;
    if(i<=10)
    {
        goto loop;
    }
    else  
    {
        goto end; 
    }
end:
    printf("sum is %d\n",sum);
    return 0;
}

4.4 do ...while 循环

do  //  循环体至少执行一次 

  {

     循环体;

  } while (表达式);

注意:while() 后的分号不可省略,否则将导致语法错误。

执行流程:

  1)先执行循环体;

  2)再计算表达式的值;若为真,则重复执行循环体;否则终止循环。

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

4.5 循环辅助控制

4.5.1 continue

① 在循环中,可以使用 continue 语句跳过当前迭代(本次循环),直接进入下一次循环。

② 当需要疲敝特定循环时,可通过条件判断配合continue实现选择性跳过。

#include <stdio.h>
int main()
{
    int i =  0;
    for(i=0;i<10;i++)
    {
        if(3 == i || 5 == i || 7 == i )
        {
            continue;   // 在循环过程中,i 如果是3,5,7 ,直接执行下一次循环
        }
        printf("i is %d\n",i);
    }
    return 0;
}

4.5.2 break

① 跳出当前循环或switch语句。

② 当不再需要继续执行后续迭代或分支时,调用break。


#include <stdio.h>
int main()
{
    int i =  0;
    for(i=1;i<10;i++)
    { 
        if(3==i || 5==i || 7==i )
        {
            break; //提前结束循环
        }
        printf("i is %d\n",i);
    }
    printf("end...\n");

}

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐