C语言笔记二——分支和循环(上)

分支和循环

1.if语句

1.1if语句的语法形式如下:

if(表达式)
    语句

表达式成立(为真)语句执行;表达式不成立(为假)语句不执行。

在C语言中,0为假,非0为真。

//instance
#include <stdio.h>
int main(){
    int num = 0;
    scanf("%d",&num);
    if(num%2 == 1){
        printf("%d 是奇数\n",num);
    }
    return 0;
}

1.2 else

如果一个数不是奇数,那就是偶数,当需要清楚判断数的奇偶需要引入if…else…语句,语法形式如下:

if()
    语句1
else
    语句2
//两个例子助于理解
//数的奇偶判断
#include <stdio.h>
int main()
{
 int num = 0;
 scanf("%d", &num);
 if(num % 2 == 1)
    printf("%d 是奇数\n", num);
 else
    printf("%d 是偶数\n", num);
 return 0;
}
//判断人是否成年
#include <stdio.h>
int main()
{
 int age = 0;
 scanf("%d", &age);
 if(age>=18)
     printf("成年\n");
 else
     printf("未成年\n");
 return 0;
}

1.3 分支中包含多条语句

默认if和else语句中默认都只控制一条语句

举个例子简单理解

if(今天学习了)
    printf("又进步了一点点");
    printf("日拱一卒,积少成多!");
//if语句只能控制第一个输出语句,即使你今天没有学习,也会输出“日拱一卒,积少成多!”

如果想自由设置if和else的控制语句,需要应用“{}”。将所对应的控制语句全装进去就可以了。

1.4 嵌套if

在if-else语句中,else可以与另一个if语句连用,构成多重判断。

//要求输入一个整数,判断输入的数是零、正数还是负数,代码实现如下:
#include <stdio.h>
int main()
{
 int num = 0;
 scanf("%d", &num);
 if(num == 0)
     printf("输⼊的数字是0\n");
 else if(num > 0) //这⾥的if 相当于嵌套在else语句中,形成了嵌套结构
    printf("输⼊的数字是正数\n");
 else
    printf("输⼊的数字是负数\n");
 
 return 0;
}
//新问题:输入一个整数,若为整数则判断其奇偶并输出;不是整数则输出为“非正数”
#include <stdio.h>
int main()
{
 int num = 0;
 scanf("%d", &num);
 if(num>0)
 {
    if(num%2 == 0)
        printf("偶数\n");
    else
        printf("奇数\n");
 }
 else
 {
    printf("⾮正数\n");
 }
 return 0;
}

1.5 悬空else问题

如果有多个if和else,牢记一个原则——else总是跟最近的if匹配。当我们读代码时,不要根据对齐的问题来进行条件判断。举例理解:

{
int a = 0;
 int b = 2;
 if(a == 1)
    if(b == 2)
        printf("hehe\n");
 else
 printf("haha\n");
 }
上下两代码块效果相同
 {
 int a = 0;
 int b = 2;
 if(a == 1)
    {
         if(b == 2)
         printf("hehe\n");
         else
         printf("haha\n");
    }
 }

2.关系操作符

C语言用于比较的表达式,称为“关系表达式”,里面使用的运算符就称为“关系运算符”,共6个:

【> ,大于运算符】、【< ,小于运算符】、【>= ,大于等于运算符】、【<= ,小于等于运算符】、【== ,相等运算符】、【!= ,不相等运算符】

关系表达式的返回值通常为0或1,表示真假(0假,非0真)

关系表达式常用于if或while结构。

【注意!!!在运用相等运算符“==”时,常常会出现使用了“=”的错误,这样就将比较变为了赋值,将判断的功能给抹掉了,会直接进行判断为真的操作。两种解决办法:1、认真敲代码,仔细检查;2、更为保准的方法是将数字放在运算符左侧,变量放在右侧,这样即使粗心犯了这种错误,编译器会及时报错,原理是“=”左边只能是变量╰( ̄ω ̄o)】

【另一个需要避免的错误就是:多个关系运算符不宜连用

i<j<k;
在此语句中,比较的顺序是从左到右,即(i<j)<k,当第一个比较完后,就变成了0<k或1<k的判断,这样难以保证j是区间(i,k)中的数,有违我们的本意

当需要进行上述情况的多重比较时,得使用逻辑操作符(下面呢)

3.条件操作符

条件操作符也叫三目操作符,需要结束3个操作数的,形式如下:

exp1 ? exp2 : exp3

条件操作符的计算逻辑是:exp1为真则exp2进行计算,结果是整个表达式的结果;exp1为假则exp3进行计算,结果是整个表达式的值。(1真算2,1假算3)

//instance
正常使用if-else语句
{
scanf("%d", &a);
 if (a > 5)
 b = 3;
 else
 b = -3;
 printf("%d\n", b); 
}
用条件操作符改写
{
scanf("%d", &a);
 b = a>5 ? 3:-3;
printf("%d\n", b);
} 

4.逻辑运算符:&&、||、!

逻辑运算符提供了判断功能,用于构建更复杂的表达式,有三个运算符。

  • !:逻辑取反运算符;

  • &&:逻辑与运算符,并且的意思(两边同时为真整个表达式才为真)

    双目操作符,使用方式a&&b

  • ||:逻辑或运算符,或的意思(两边有一个为真整个表达式就为真)

    双目操作符,使用方式a||b

逻辑运算符最经典的应用问题:闰年判断

输入一个年份year,判断year是不是闰年。

首先明确闰年的判断规则:

  • 能被4整除并且不能被100整数是闰年;

  • 能被400整除是闰年。

    代码实现:

#include<stdio.h>
int main(){
    int year;
    scanf("%d",&year);
    if(year%4==0&&year%100!=0)
        printf("%d是闰年\n",year);
    else if(year%400==0)//也可以将这两句判断改为条件运算符模式if((year%4==0 && year%100!=0) || (year%400==0))
        printf("%d是闰年\n",year);
    else
        printf("%d不是闰年\n",year);
    return 0;
}

【短路问题】

C语言逻辑运算符的一个特点——总是先对左侧表达式求值,再对右侧表达式求值,顺序固定。

如果左边的表达式满足逻辑运算符的条件时,就不再对右边的表达式求值。这种情况称为短路

像这种仅仅根据左操作数的结果就能知道整个表达式的结果,不再对右操作数进行计算的运算称为短路求值

//instance
#include <stdio.h>
int main()
{
    int i = 0,a=0,b=2,c =3,d=4;
    i = a++ && ++b && d++;
    printf("i = %d\n a = %d\n b = %d\n c = %d\nd = %d\n",i, a, b, c, d);
    return 0;
}//结果输出为i=0 a=1 b=2 c=3 b=4
​
#include <stdio.h>
int main()
{
    int i = 0,a=0,b=2,c =3,d=4;
    i = a++||++b||d++;
    printf("i=%d\n a = %d\n b = %d\n c = %d\nd = %d\n",i, a, b, c, d);
    return 0;
}//结果输出为i=1 a=1 b=3 c=3 b=4

5.switch语句

switch语句也是C语言中用来实现分支结构的语句(另一个是if语句)

应用情况:用于判断条件有多个结果的情况。它把多重的else-if改成更易用、可读性更好的形式。

switch(expression){
    case value1:statement
    case value2:statement
    default:statement
}

简述含义:根据表达式expression不同的值,执行相应的case分支,找不到对应的值,执行default分支。

注:

  • switch后的expression必须是整型表达式;

  • case后的值必须是整形常量表达式。

代码注意:case和后面的数字之间必须有空格。

【每一个case语句中的代码执行完成后,需要加上break,才能跳出这个switch语句】

当我们switch语句进入的case语句中无break,代码则会继续往下执行,包括其他case中的代码,直到遇见break语句或者switch语句结束。【break语句很重要,它保证了分支效果能够得到真正地实现!】

switch语句中的case语句和default语句没有顺序要求,随便设置先后,一般将default放在最后处理。

//instance
#include <stdio.h>
int main()
{
 int day = 0;
 scanf("%d", &day);
 switch(day)
 {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        printf("⼯作⽇\n");
        break;
    case 6:
    case 7:
        printf("休息⽇\n");
            break;
    default:
        printf("输⼊错误\n");
        break;
 }
 return 0;
}

6.while循环语句

C语言中有三种循环语句,while是其中一种。

while(表达式)
    语句;

while的执行流程:首先执行判断表达式,表达式值为0(假),循环之间结束;表达式值不为0(真),则执行循环语句,语句执行完后再继续判断,否则进行下一次判断。

//instance
#include <stdio.h>
int main()
{
    int i = 1;
    while(i<=10)
    {
        printf("%d ", i);
        i = i+1;
    }
    return 0;
}//输出数字1~10

7.for循环

7.1 语法形式

for(表达式1;表达式2;表达式3)
    语句;//多个语句使用大括号包上,同if用法
  • 表达式1用于循环变量的初始化;

  • 表达式2用于循环结束条件的判断;

  • 表达式3用于循环变量的调整。

7.2 for循环的执行过程

首先执行表达式1初始化循环变量,接下来执行表达式2的判断部分,表达式2 的结果如果==0(即超过临界条件),则循环结束;表达式2的结果如果!=0则执行循环语句,循环语句执行完后,再去执行表达式3,调整循环变量,然后再去表达式2继续执行,判断是否再次循环。

7.3 for循环实践

//打印1~10
#include<stdio.h>
int main(){
    int i=0;
    for(i=1;i<=10;i++)
    {
        printf("%d\n",i);
    }
    return 0;
}

7.4 while循环和for循环的对比

for和while在实现循环过程中都有初始化、判断、变量调整这三部分,但是for循环的三个部分非常集中,便于代码维护,而代码较多时,while循环的三个部分较为分散,所以从形式上讲,for循环更具优越性。

//instance,计算1~100之间3的倍数之和
#include <stdio.h>
int main(){
    int i = 0;
    int sum = 0;
    for(i=1; i<=100; i++)
    {
        if(i % 3 == 0)
        sum += i;
    }
    printf("%d\n", sum);
    return 0;
}
//优化
#include <stdio.h>
int main(){
    int i = 0;
    int sum = 0;
    for(i=3; i<=100; i+=3)//减少冗余的循环过程
    {
        sum += i;
    }
    printf("%d\n", sum);
    return 0;
}

8.do-while循环

8.1语法形式

do
    语句;
while(表达式)

while和for这两种循环都是先进行判断,满足条件进入循环,执行循环语句;

而do-while循环则是先进行循环体,执行循环语句,然后再执行while后的判断表达式,表达式为真,进行下一次循环,否则不再进行循环。

8.2 do-while循环的执行流程

在do while循环中先执行图上的“语句”,执行完语句,再去执行“判断表达式”,判断表达式结果是!=0,则继续循环,执行循环语句;否则循环结束。

【所以在do while语句循环体至少执行一次】

8.3 do while循环实例

//打印1~10
#include <stdio.h>
int main(){
    int i = 1;
    do
    {
        printf("%d\n", i);
        i = i + 1;
    }while(i<=10);
    return 0;
}
//计算输入数是几位数
#include<stdio.h>
int main(){
    int t=0;
    scanf("%d",&t);
    int n=0;
    do
    {
        n++;
        t/=10;
    }while(t);
    printf("输入数是%d位数",n);
    return 0;
}

9.break和continue语句

在循环执行过程中,某些状况发送时,需要提前终止循环,在C语言中提供了break和continue两个关键字。

  • break的作用时用于永久的终止循环,只要break被执行,直接跳出循环,继续往后执行;

  • continue作用是跳过本次循环中continue后面的代码,在for循环和while循环中有所差异。

9.1 while循环中的break和continue的举例

#include <stdio.h>
int main(){
    int i = 1;
    while(i<=10)
    {
        if(i == 5)
            break;//当i等于5后,执⾏break,循环终⽌
        printf("%d", i);//等于5后这句当然不执行^.^
        i = i+1;
    }
    return 0;
}//只输出“1 2 3 4”
//当我们将上面的break语句换位continue语句
#include <stdio.h>
int main(){
    int i = 1;
    while(i<=10)
    {
        if(i == 5)
            continue;
        printf("%d", i);
        i = i+1;
    }
    return 0;
}//千万不要认为此时会输出除了5以外的1~10,因为continue会跳过“i=i+1”这个代码,所以程序陷入死循环。

9.2 for循环中的break和continue的举例

#include <stdio.h>
int main()
{
    int i = 1;
    for(i=1; i<=10; i++)
    {
        if(i == 5)
            break;
        printf("%d ", i);
    }
    return 0;
}//效果同while循环
#include <stdio.h>
int main()
{
    int i = 1;
    for(i=1; i<=10; i++)
    {
        if(i == 5)
            continue;//这⾥continue跳过了后边的打印,来到了i++的调整部分
        printf("%d ", i);
    }
    return 0;
}//此时会正常打印除了5以外的1~10

【for循环中continue并不会耽误变量调整的进行】

9.3 do while循环中的break和continue的举例

//效果和while一致
#include <stdio.h>
int main()
{
    int i = 1;
    do
    {
        if(i == 5)
        break;
        printf("%d ", i);
        i = i + 1;
    }while(i<=10);
    return 0;
}
#include <stdio.h>
int main()
{
    int i = 1;
    do
    {
        if(i == 5)
        continue;
        printf("%d ", i);
        i = i + 1;
    }while(i<=10);
    return 0;
}

10.循环的嵌套

//instance
//打印100~200中的素数(判定条件:除了1和其本身,再无其他因数)
#include <stdio.h>
int main()
{
    int i = 0;
    //循环产⽣100~200的数字
    for(i=100; i<=200; i++)
    {
        //判断i是否为素数
        //循环产⽣2~i-1之间的数字
        int j = 0;
        int flag = 1;//假设i是素数
        for(j=2; j<i; j++)
        {
            if(i % j == 0)
            {
                flag = 0;
                break;
            }
        }
        if(flag == 1)
            printf("%d ", i);
    }
    return 0;
}

11.goto语句

C语言中提供了goto语句和跳转标号,goto语句可以实现在同一个函数内跳转到设置好的标号处。

#include <stdio.h>
int main()
{
    printf("1\n");
    goto next;
    printf("2\n");
next:
    printf("跳过了2的打印\n"); 
    return 0;
}
  • goto语句使用不当会导致函数内部随意乱转,打乱程序的执行流程,建议少使;

  • 但goto语句在多层循环的代码中,如果想快速跳出就使用它(就决定是你了!goto语句)。

    【break语句跳出的是单层循环体】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值