嵌入式学习(四)

        我们学习编程的目的,其实就是让电脑帮我们做事。要想电脑能很好地、高效地为我们服务,就得学习一个重要知识点“程序控制结构”。比如我们要从1一直加到1000。如果我要输成百上千次加法运算,就有点不合适。学了程序控制结构后,我们只需要输入两三句语句就0k了。比如:

     int j=0;

     for (int i=1;i<=1000;i++)

    {

        j+=i;

        printf("i=%d,j=%d\n",i,j);

    }

【数据结构】

一、C语言的结构

顺序结构,代码从上到下执行

分支结构/选择结构

循环结构

二、分支结构

【1】if单分支结构

if(表达式)

{

    表达式成立执行的代码块;

}

【2】双分支结构

if(表达式)

{

    表达式成立执行的代码块;

}

else

{

    表达式不成立执行的代码块;

}

【3】多分支结构

if(表达式1)

{

    表达式1成立执行的代码块;

}

else if(表达式2)

{

    表达式1不成立但是表达式2成立执行的代码块;

}

else if()

{

    ····

}

····

else

{   

}

【4】嵌套if

if(表达式1)

{

    if(表达式2)

    {

        表达式1成立并且表达式2成立执行的代码块;   

    }

    else

    {

        表达式1成立但是表达式2不成立执行的代码块;   

    }

}

else if( ····)

·····

例如:

1、终端输入年份,判断是否是闰年,能被四整除但是不能被100整除或者能被400整除的叫闰年。

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int num;

    scanf("%d",&num);

    //判断是否是偶数

    if(num%2==0)

    {

        printf("%d是二的倍数\n",num);

    }

    else

    {

        printf("%d不是二的倍数\n",num);

    }

    printf("请输入新的数\n");

    scanf("%d",&num);

    if(!(num%7))    //!是一个单目运算符,优先级高于%

    {

        printf("%d是七的倍数\n",num);

    }

    else

    {

        printf("%d不是七的倍数\n",num);

    }

    printf("请输入年份\n");

    scanf("%d",&num);

    if(num%4==0&&num%100!=0||num%400==0)

    {

        printf("%d年是闰年\n",num);

    }

    else

    {

        printf("%d是平年\n",num);

    }

    return 0;

}

2、终端输入一个[100,999]之间的数,判断是否是是否是水仙花数,

  (水仙花数:个位*个位*个位+十位*十位*十位+百位*百位*百位=数本身)

#include <stdio.h>

#include <math.h>

int main(int argc, const char *argv[])

{

    int num,a,b,c;

    printf("请输入一个数\n");

    scanf("%d",&num);

    a = num/100;

    b = num/10%10;

    c = num%10;

    //使用pow函数需要包含<math.h>头文件,gcc编译需要加上-lm参数

    if(num==a*a*a+b*b*b+pow(c,3))

    {

        printf("%d是一个水仙花数\n",num);

    }

    return 0;

}

3、终端输入学生成绩,输出成绩等级,[100,90]A,(90,80]B,(80,70]C,(70,60]D,(60,0]不及格。

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int score;

    scanf("%d",&score);

    if(score<0||score>100)

    {

        printf("error\n");

    }

    else if(score>=90&&score<=100)

    {

        printf("A\n");

    }

    else if(score>=80&&score<90)

    {

        printf("B\n");

    }

    return 0;

}

4、狗的前两年每一年相当于人类的10.5岁,之后每增加一年就增加一岁,终端输入狗的年龄,输出该相当于人的多少岁。

#include <stdio.h>

int main(int argc, const char *argv[])

{

    float age;

    scanf("%f",&age);

    if(age>2)  //判断狗的年龄是否大于2,大于2时的计算逻辑

    {

        age = 10.5*2+age-2;

    }

    else  //小于等于2时的计算逻辑

    {

        age = 10.5*age;

    }

    printf("%f\n",age);

    return 0;

}

5、终端输入一个数,判断是否是3的倍数,如果是3的倍数再判断是否是5的倍数。

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int num;

    scanf("%d",&num);

    if(num%3==0&&num!=0)

    {

        if(num%5==0)

        {

            printf("%d既是3的倍数也是5的倍数\n",num);

        }

        else

        {

            printf("%d是3的倍数但是不是5的倍数\n",num);

        }

    }

    return 0;

}

6、终端输入三条边,判断是否能构成三角形(判断两边之和大于第三边),在能构成三角形的基础上判断三角形的类型(等边,等腰和直角)

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int a,b,c;

    scanf("%d%d%d",&a,&b,&c);

    if(a+b>c&&a+c>b&&c+b>a)  //两边之和大于第三边,能构成三角形

    {

        if(a==b||b==c||a==c)  //是否是等腰三角形

        {

            if(a==b&&b==c)  //说明三边相等

            {

                printf("能构成等边三角形\n");

            }

            else

            {

                printf("能构成等腰三角形,但不能构成等边三角形\n");

            }   

        }

        if(a*a+b*b==c*c||c*c+b*b==a*a||a*a+c*c==b*b)

        {

            printf("能构成直角三角形\n");

        }

    }

    return 0;

}

7、从终端输入一个字符:如果是大写的 转换成小写,如果是小写的 转换成大写,如果是 0-9   按照 %d  输出对应整型的  0-9,其他字符 转换成 #并输出。

#include <stdio.h>

int main(int argc, const char *argv[])

{

    char c;

    scanf("%c",&c);

    if(c>='A'&&c<='Z')

    {

        c = c+32;  //把大写字母转成小写字母

        printf("%c\n",c);

    }

    else if(c>='a'&&c<='z')

    {

        c-=32;

        printf("%c\n",c);

    }

    else if(c>='0'&&c<='9')

    {

        printf("%d\n",c-48);

    }

    else

    printf("#\n");

    return 0;

}

小总结:if···else的注意事项

        1。else前面必须有一个if

        2。if后面如果只有一条语句可以不加{},如果有多条语句一定要加{},else同理

        3。if后面通常放的是条件运算表达式/逻辑运算的表达式/变量/赋值语句····,只要有明确结果的表达式都可以放在()里。

        4。由于if的条件中,可以放赋值语句,在判断相等时if(a==1)建议写成if(1==a)

【5】switch····case分支

格式:

switch(变量)

{

    case 常量表达式:

        语句块1;

        break;

    case 常量表达式:

        语句块2;

        break;

        ····

    case 常量表达式:

        语句块n;

        break;

    default:

        语句块n+1;

        break;           

}

switch和后面括号内的内容是,选择的变量,case后面的常量表达式,就是switch后面的变量可能出现的情况。

哪个case后面的常量是变量的结果,就执行哪个case后面的代码块。

switch···case的执行逻辑

        进入switch···case判断变量的结果,和case后的常量表达式判断,走满足的case后面的分支。如果一个case后面没有break,执行完该case后会顺序向后执行下面的case/switch···case语句。default的作用,如果不关心其他分支,就写一个default,其他分支就走default

使用switch···case的注意事项

        1、switch后面的变量只能是char/int

        2、如果不加break会顺序向后执行,叫做case击穿

        3、case的顺序,不会影响程序的执行

        4、default的位置也不会影响程序的执行,只有所有case都不满足时,才会走default分支

        5、case击穿可以根据使用场景的不用利用起来。

练习:

1、终端输入学生成绩,输出成绩等级,[100,90]A,(90,80]B,(80,70]C,(70,60]D,(60,0]不及格,使用switch····case完成。

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int score;

    scanf("%d",&score);

    int a = score/10;

    if(score>=0&&score<=100)  //判断成绩合理性

    {

        switch(a)

        {

        case 10: 

            //利用了case击穿,让case10和case9走同一个分支

        case 9:

            printf("A\n");

            break;

        case 8:

            printf("B\n");

            break;

        case 7:

            printf("C\n");

            break;

        case 6:

            printf("D\n");

            break;

        case 5||4||3||2||1:  // <==>case 1:

            //5||4||3||2||1 是一个逻辑或运算的表达式,是一个常量表达式,结果是1

            printf("不及格\n");

        }

    }

    else

    {

        printf("error\n");

    }

    return 0;

}

2、使用switch···case完成简易计算器功能(+、-、*、/、%),如3+5输出8,只完成个位数的计算

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int num1,num2;  //两个操作数

    char a; //运算符

    scanf("%c%d%d",&a,&num1,&num2);

    //switch用于判断操作符

    switch(a)

    {

        case '+':

            printf("%d+%d=%d\n",num1,num2,num1+num2);

            break;

        case '-':

            printf("%d-%d=%d\n",num1,num2,num1-num2);

            break;

        case '*':

            printf("%d*%d=%d\n",num1,num2,num1*num2);

            break;

        case '/':

            printf("%d/%d=%f\n",num1,num2,(float)num1/num2);

            //除法时,将其中一个整形数据强转成float类型

            break;

        case '%':

            printf("%d%%%d=%d\n",num1,num2,num1%num2);

                        //想输出一个%需要在""内打两个%%                         

            break;           

    }

    return 0;

}

3、终端输入年月日,输出是这一年的第几天,如2023.3.1输出60,需要考虑闰平年,2月闰年29,平年28。

1 3 5 7 8 10 12 都是31天

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int year,month,day;

    scanf("%d%d%d",&year,&month,&day);

    switch(month)

    {

    case 12:

        day = day+30;

    case 11:

        day = day+31;

    case 10:

        day = day+30;

    case 9:

        day = day+31;

    case 8:

        day = day+31;

    case 7:

        day = day+30;

    case 6:

        day = day+31;

    case 5:

        day = day+30;

    case 4:

        day = day+31;

    case 3:

        //day = day+28;  //二月统一+28天,在switchcase外判断闰平年再加1

        //在switch```case的里面嵌套if判断

        if(year%4==0&&year%100!=0||year%400==0)

        {

            day = day + 29;

        }

        else

        {

            day = day+28;

        }

    case 2:

        day = day+31;

    case 1:

        break;

    }

    /*if(year%4==0&&year%100!=0||year%400==0)

    {

        day+=1;

    }*/

    printf("%d\n",day);

    return 0;

}

三、循环结构

【1】while循环

格式:

    while(条件)

    {

        代码块;

        改变循环变量的语句;

    }

先判断条件是否成立,如果条件成立,执行代码块里的语句

再判断条件是否成立,如果不成立退出while循环

注意:

    1、循环的次数,只和循环变量初始值、步长以及循环条件有关。

    2、如果while后面,只有一条语句,{}可以不写

    3、while()后面不要加;

    while(1){}死循环

练习:

1、使用while循环输出5行helloworld。

#include <stdio.h>

int main()

{

    int i = 2;

    while(i<=10)

    {

        printf("hello world\n");

        i+=2;    //让循环变量每次自增2

    }

}

2、1-100中的偶数

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int i = 1;  //循环变量的初始值

    while(i<=100)

    {

        if(i%2==0)

        {

            printf("%d是偶数\n",i);

        }

        i++;  //改变循环变量的语句

        //步长:循环变量的改变方式                           

    }

    return 0;

}

或者

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int i = 2;

    while(i<=100)

    { 

        printf("%d\n",i);

        i+=2;  //i的步长是2

    } 

    return 0;

3、求1-100的和,5050。

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int i = 1,sum =0;  //分别给循环变量和sum赋初值

    while(i<=100)

    {

        sum+=i;

        i++; //改变循环变量

    }

    printf("%d\n",sum);

    return 0;

}

4、输出100-999内的所有水仙花数,(各位的三次方相加等于该数)

使用pow函数,需要加编译选项-lm。

#include <stdio.h>

#include <math.h>

int main(int argc, const char *argv[])

{

    int num = 100,a,b,c;

    while(num<=999)  //while(i<1000)

    {

        a = num/100;

        b = num/10%10;

        c = num%10;

        if(pow(a,3)+pow(b,3)+pow(c,3)==num)

        //pow的使用方式pow(数,幂次),gcc -lm

        {

            printf("%d是一个水仙花数\n",num);

        }

        num++;

    }

    return 0;

}

5、猴子吃桃问题,猴子第一天摘了若干个桃,

当即就吃了一半的桃,没过瘾,又多吃一个

第二天,在剩下的桃里吃了一半的桃,没过瘾,又多吃一个

依次类推,知道第10天,猴子发现只剩一个桃了。

问:猴子第一天摘了几个桃子。

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int peach = 1,i=9;  //i进入循环时是第9天,第9天的桃子数才需要去计算

    while(i>=1)  //循环进行9次

    {

    peach=(peach+1)*2;

    i--;  //改变循环变量

    }

    printf("%d\n",peach);

    return 0;

}

【2】do···while循环

先执行再判断

do

{

    循环体;

}while(条件);

先执行循环体语句,再判断条件是否成立。

do···while语句不管条件是否满足,循环体内语句都会执行一次。

【3】for循环

【1】格式

for(表达式1;表达式2;表达式3)

{

    (循环体内)代码块;

}

先执行表达式1,表达式1通常是循环变量初始化语句,

再执行表达式2,表达式2是for循环判断条件,

如果条件成立,执行循环体内的语句,再执行表达式3,表达式3就是循环变量的步长

如果条件不成立,退出for循环.

练习

1、求1-100内奇数的和。

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int i,sum=0;

    for(i=1;i<=100;i++)  //i=1,只会执行一次,i++执行的次数和循环次数一致

    {

        if(i%2!=0)

        {

            sum+=i;

        }

    }

    //循环结束,说明奇数和求完了

    printf("%d\n",sum);

    return 0;

}

2、终端输入一个数,求该数的所有因子,如12,输出1 2 3 4 6 12

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int num;

    scanf("%d",&num);

    int i;

    for(i=1;i<=num;i++)  //循环从1-num的每一个数

    {

        if(num%i==0)  //判断循环到的数是否是num的因子

        {

        printf("%d\n",i);

        }

    }

    return 0;

}

3、输出下三角的九九乘法表

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int i,j;

    for(i=1;i<=9;i++)  //外层循环控制行数

    {

            for(j=1;j<=i;j++) //内层循环控制每行打印的列数

              {

            printf("%d*%d=%d\t",j,i,i*j);

        }

        printf("\n"); //每一行打印完输出换行

    }

    return 0;

}

四、goto  跳转

【1】goto的基本使用

goto的本质是代码跳转,也可以用它实现循环,只能在同一个函数中跳转。

尽量不要在代码中使用goto,降低代码的可读性

语句块1;

goto NEXT;    //NEXT就是一个标签

语句块2;

语句块3;

NEXT:

      语句块4;


执行逻辑:

先执行语句块1,接着走到goto,跳转到goto后面的标签,执行语句块4


#include <stdio.h>

int main(int argc, const char *argv[])

{

    int a = 100;

    goto NEXT;

    printf("%d\n",a);

NEXT:

//    int b = 9;  //把变量的声明放在goto的标签里面

    printf("*******\n");

    int b = 9;

    printf("%d\n",b);

    return 0;

}

【2】使用goto实现循环

如果想要使用goto实现循环,需要把标签放在goto的上面,这样就会一直执行goto

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int a = 100;

    goto NEXT;

    printf("%d\n",a);

NEXT:

//    int b = 9;  //把变量的声明放在goto的标签里面

    printf("*******\n");

    int b = 9;

    printf("%d\n",b);

    return 0;

}


#include <stdio.h>

int main(int argc, const char *argv[])

{

    int a = 9;

NEXT:

    printf("%d\n",a);

    goto NEXT;

    return 0;

}

//使用goto实现循环输出5行hello world

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int a = 1;

NEXT:

    printf("hello world\n");

    a++;

    //循环条件,如果没有判断一直goto就死循环了

    if(a<=5)

    {

        goto NEXT;  //使用goto打印的hello world有4个

        //第一次进入if判断的a=2

    }

    return 0;

}


练习:

1、使用goto实现1-100的求和

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int i = 1,sum=0;

LOOP:

    sum+=i; //先让sum计数

    i++;  //再让循环变量自增

    if(i<101)

    {

        goto LOOP;

    }

    printf("%d\n",sum);

    return 0;

}

辅助控制关键字

        return  break  continue

【1】break

break只能用在循环和switch···case中,不能再goto中使用

break用在循环中,表示退出本层循环。

for循环

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int i,j;

    for(i=1;i<4;i++)

    {

        printf("i=%d\t",i);

        for(j=1;j<5;j++)

        {

            if(j==3)

            {

                //break;  //跳出本层循环

                continue;  //跳出本层本次循环

                //return ;  //退出当前函数

            }

            printf("j=%d\t",j);

        }

        printf("\n");

    }

    return 0;

}

while循环

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int i=1,j=1;

    while(i<4)

    {

        printf("i=%d\t",i);

        j=1;  //让内层循环变量j,每一次进入循环前都重置一次

        while(j<5)

        {

            if(j==3)

            {

                //break;  //跳出本层循环

                //continue;  //跳出本层本次循环,死循环,因为j永远=3

                return 1;

            }

            printf("j=%d\t",j);

            j++;

        }

        printf("\n");

        i++;

    }

    return 0;

}

【2】continue

退出本层本次循环,不能再goto中使用

continue放在while中时,需要把修改循环变量的语句放在continue的上面

【3】return

退出当前函数

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容