C程序设计——结构化程序设计的三种结构

news2024/11/19 17:27:39

前面我说过:“结构化编程语言,用语法限制程序员,只能使用顺序、选择、循环三种结构来解决问题。”

接下来,就讲解这三种结构。

顺序结构

前面我讲过,C语言所有的程序,都必须有一个 main 函数,C语言设计的程序,也是从 main 开始执行,所以,C语言的顺序结构,第一条就是:不论你的源码有多少个函数,都得先找 main,至于 main 运行之前在计算机在做什么,对于计算机科学来说很重要,但对于没什么计算机基础、且初学C语言的你来说,不重要,所以暂时不要在这个问题上浪费精力

当计算机进入 main 之后,就从main函数的第一条语句开始,按照从上到下顺序,一条一条的执行。比如下面这段代码,虽然 TestParam 函数在 main 函数的上面,但是所有C语言程序,都是从main 开始执行,因此这段代码,先执行 main 函数,进入main函数后,先定义两个变量 iA 和 iB ,并且分别初始化为 0x9 和0x29,然后调用函数 TestParam, iA 和 iB作为函数的实参。

进入 TestParam后,打印两个形参的值,然后返回0;TestParam 函数返回后,回到了main函数,我们可以看到,函数返回值赋值给了 iA,因此 iA被赋值为了0,所以接下来 打印 iA 的值为0。

int TestParam(int x, int y)
{
    printf("x == %x, y == %x\r\n", x, y);
    return 0;
}

int main(void)
{
    int iA = 0x9, iB = 0x29;
    iA = TestParam(iA, iB);
    printf("iA == %x", iA);
    return 0;
}

代码的执行结果如下:

选择结构

C语言的选择结构有两种:if 语句 和 switch 语句

if 语句

if 语句的形式如下:

    if(表达式)
    { // 左括号0

    } // 右括号0
    else
    { // 左括号1

    } // 右括号1

当表达式的值为真(非 0 值)时,执行左括号0 和 右括号0 括起来的程序;表达式的值为假时(为0),执行左括号1 和 右括号1 括起来的程序。

比如下面这段程序:

int main(void)
{
    int iA = 0x9, iB = 0x29;
    if(iA > 0x7)
    { // 左括号0
        printf("iA == %x\r\n", iA);
    } // 右括号0
    else
    { // 左括号1
        printf("iB == %x\r\n", iB);
    } // 右括号1
}

因为 iA 初始化为0x9,因此 iA > 0x7 的值为真(值为 1),因此应该执行左括号0 和 右括号0 括起来的程序,即打印 iA的值,执行结果如下:

如果我们修改一下程序,把iA 初始化为 0x2:

int main(void)
{
    int iA = 0x2, iB = 0x29;
    if(iA > 0x7)
    { // 左括号0
        printf("iA == %x\r\n", iA);
    } // 右括号0
    else
    { // 左括号1
        printf("iB == %x\r\n", iB);
    } // 右括号1
}

执行结果,就变成了打印 iB的值,即:

 

 表达式为假时,如果不需要做任何事情,那么else {} 的部分可以不要。

int main(void)
{
    int iA = 0x2, iB = 0x29;
    if(iA > 0x7)
    { // 左括号0
        printf("iA == %x\r\n", iA);
    } // 右括号0
}

switch 语句

switch 语句的基本形式如下:

    switch(整形变量)
    { // 左括号0
        case 整形常量0:
            //TODO
            break;
        case 整形常量1:
            //TODO
            break;
        default:
            //TODO
            break;
    } // 右括号0

当整形变量的值,与case后面的常量值一样时,执行case后面的程序,直到 break;如果整形变量的值,在任何一个case后面都找不到,那么就执行default 后面的程序,直到 break

比如某次考试,满分10分,所有成绩用自然数表示,低于6分为不及格,6分为及格,7分、8分为良好,9分和10分为优秀,其他分数无效,就可以写如下程序:

int main(void)
{
    int chengJi = 3;
    printf("成绩 %d 分\r\n", chengJi);
    switch(chengJi)
    { // 左括号0
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
            printf("不及格\r\n");
            break ;
        case 6:
            printf("及格\r\n");
            break ;
        case 7:
        case 8:
            printf("良好\r\n");
            break ;
        case 9:
        case 10:
            printf("优秀\r\n");
            break ;
        default:
            printf("分数无效\r\n");
            break;
    } // 右括号0
}

执行结果如下:

这里要深入理解一下这句话:“执行case后面的程序,直到 break”。如果我们把上题改一下,输出成绩的等级之前,还得输出与成绩数量相同的 “*” ,那么程序可以写成下面这样:

    int chengJi = 3;
    printf("成绩 %d 分\r\n", chengJi);
    switch(chengJi)
    { // 左括号0
        case 5:
            printf("*");
        case 4:
            printf("*");
        case 3:
            printf("*");
        case 2:
            printf("*");
        case 1:
            printf("*");
        case 0:
            printf("不及格\r\n");
            break ;
        case 6:
            printf("******");
            printf("及格\r\n");
            break ;
        case 8:
            printf("*");
        case 7:
            printf("*******");
            printf("良好\r\n");
            break ;
        case 10:
            printf("*");
        case 9:
            printf("*********");
            printf("优秀\r\n");
            break ;
        default:
            printf("分数无效\r\n");
            break;
    } // 右括号0
}

执行结果如下:

这里要强调,程序进入相应的case后,会一直执行,直到break 。

关于default

首先说明,default 选项可以没有。switc语句中,如果所有case后面的常量,都不匹配,且程序里面有default,那么就会执行 default 后面的语句,直到break;

这里强调一下:default 一定是所有case都不匹配后,才会执行。比如下面这段代码:

int main(void)
{
    int chengJi = 100;
    printf("成绩 %d 分\r\n", chengJi);
    switch(chengJi)
    { // 左括号0
        case 5:
            printf("*");
        case 4:
            printf("*");
        // ***********注意 default 在这里
        default:
            printf("分数无效\r\n");
        case 3:
            printf("*");
        case 2:
            printf("*");
        case 1:
            printf("*");
        case 0:
            printf("不及格\r\n");
            break ;
        case 6:
            printf("******");
            printf("及格\r\n");
            break ;
        case 8:
            printf("*");
        case 7:
            printf("*******");
            printf("良好\r\n");
            break ;
        case 10:
            printf("*");
        case 9:
            printf("*********");
            printf("优秀\r\n");
            break ;
    } // 右括号0
}

执行结果如下:

循环结构

while 循环

while循环的形式如下:

    while(表达式)
    {
        循环体;
    }

首先明确一个概念,while后面有一对大括号,他们括起来的语句,叫做循环体。当表达式的值为真(值为非0,下同)时,执行一次循环体;当表达式的值为假(值为0,下同)时,退出循环,执行循环外面的语句。

比如下面这个代码:

int main(void)
{
    int i ;

    i = 10;
    while(i > 0) // 当i 大于0时,执行循环体
    {
     // 循环体有两条语句: 打印i的值,然后给 i 减一
        printf("i == %d\r\n", i);
        i --;
    }

    // 循环退出后,打印 while over 和 i的值
    printf("while over %d, \r\n", i);
}

运行结果如下:

do-while 循环

do-while循环的形式如下:

    do
    {
        循环体;
    }while(表达式);  // 注意,这里有个封号

注意:while(表达式) 的右边有一个封号。那个封号不能少。

do-while循环的执行方式是,先执行一次循环体,然后再判断表达式的值,如果表达式的值为真,就回到do那里,在执行一次循环体;如果表达式的值为假,就退出循环,执行循环后面的语句。

聪明如你,一定可以看出来,do-while 循环里的循环体,至少会执行一次

请看下面这段代码:

int main(void)
{
    int i ;

    i = 10;
    do
    {
     // 循环体有两条语句: 打印i的值,然后给 i 减一
        printf("i == %d\r\n", i);
        i --;
    }while(i > 0);

    // 循环退出后,打印 while over 和 i的值
    printf("while over %d, \r\n", i);
}

执行结果如下:

我们再深入理解一下这句话:do-while 循环里的循环体,至少会执行一次。理解一下,是至少执行一次,不是比 while循环多执行一次,从上面这个例子可以看出来,同样的逻辑,while和 do-while 执行的次数是一样的。

如果do-while循环和 while循环,逻辑相同,再大多数情况下,循环执行次数是一样的,只有当表达式初始为假时,他俩才有区别。

比如下面两段程序,跟前面的程序相比,用于控制循环表达式,变成了 i .> 100。因为 i 的初值是 10,减1之后是9,无论如何不可能大于100,运行一下,我们就会发现,do-while循环,比while循环多执行了一次。

int main(void)
{
    int i ;

    i = 10;
    do
    {
     // 循环体有两条语句: 打印i的值,然后给 i 减一
        printf("i == %d\r\n", i);
        i --;
    }while(i > 100);

    // 循环退出后,打印 while over 和 i的值
    printf("while over %d, \r\n", i);
}

int main(void)
{
    int i ;

    i = 10;
    while(i > 100)
    {
     // 循环体有两条语句: 打印i的值,然后给 i 减一
        printf("i == %d\r\n", i);
        i --;
    }

    // 循环退出后,打印 while over 和 i的值
    printf("while over %d, \r\n", i);
}

for 循环

for循环的形式如下:

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

for循环中的执行顺序是:

  1. 执行表达式1
  2. 判断表达式2的值如果为真,则执行 3. ,否则退出循环;
  3. 执行循环体
  4. 执行表达式3,回到 2. 继续执行

聪明如你,一定可以看出来,for循环中,表达式1 只执行一次,所以它通常用来初始化循环条件。表达式3,通常用来改变循环条件。像下面这样:

int main(void)
{
    int i ;


    for(i = 10; i > 0; i --)
    {
     // 循环体有一条语句: 打印i的值
        printf("i == %d\r\n", i);
    }

    // 循环退出后,打印 while over 和 i的值
    printf("while over %d, \r\n", i);
}

执行结果如下:

 

C语言所有的循环,都是当型循环

聪明如你,C语言中一定发现了无论 while, do-while,还是for,都是当循环条件为真时,执行循环,这种循环叫做:当型循环

还有一种循环是循环条件为假时执行条件,直到循环条件为真后退出循环,这种循环叫做:直到型循环,C语言里没有这种循环。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2178098.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TCP\IP标准与OSI标准

TCP/IP 模型和 OSI 模型都是用于描述网络体系结构的模型,但它们的设计理念和层次结构有所不同。TCP/IP 模型更注重实际实现,而 OSI 模型更注重抽象和标准化。 1. OSI 模型 (Open Systems Interconnection Model) OSI 模型是一个七层模型,从…

828华为云征文|部署在线论坛网站 Flarum

828华为云征文|部署在线论坛网站 Flarum 一、Flexus云服务器X实例介绍二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置2.4 Docker 环境搭建 三、Flexus云服务器X实例部署 Flarum3.1 Flarum 介绍3.2 Flarum 部署3.3 Flarum 使用 四、总结 一、…

针对考研的C语言学习(定制化快速掌握重点2)

1.C语言中字符与字符串的比较方法 在C语言中&#xff0c;单字符可以用进行比较也可以用 > , < ,但是字符串却不能用直接比较&#xff0c;需要用strcmp函数。 strcmp 函数的原型定义在 <string.h> 头文件中&#xff0c;其定义如下&#xff1a; int strcmp(const …

Vue.js组件开发指南

Vue.js组件开发指南 Vue.js 是一个渐进式的 JavaScript 框架&#xff0c;用于构建用户界面。它的核心是基于组件的开发模式。通过将页面分解为多个独立的、可复用的组件&#xff0c;开发者能够更轻松地构建复杂的应用。本文将深入探讨 Vue.js 组件开发的基础知识&#xff0c;并…

基于springoot新能源充电系统的设计与实现

新能源充电系统的设计与实现 摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统新能源充电系统信息管理难度…

国产纯电SUV都在秀,只有Model Y在挨揍

文/王俣祺 导语&#xff1a;如果想知道纯电SUV应该怎么选&#xff0c;一定有人告诉你“无脑选Model Y”&#xff0c;虽说特斯拉确实粉丝多&#xff0c;但这也恰恰证明Model Y一度成为了纯电SUV的标杆。有标杆自然就有挑战者&#xff0c;随着阿维塔07、智己LS6以及乐道L60先后上…

云南省职业院校技能大赛赛项规程(软件测试)

赛项名称&#xff1a;软件测试 英文名称&#xff1a;Software Testing 赛项组别&#xff1a;高等职业教育 赛项编号&#xff1a;GZ034 目录 一、 赛项信息 二、竞赛目标 三、竞赛内容 1、本赛项考查的技术技能和涵盖的职业典型工作任务 2、专业核心能力与职业综合能力…

商标名称注册查询,到底是查询什么!

在商标注册前是需要商标名称注册查询&#xff0c;那这个到底是查询什么&#xff0c;普推知产商标老杨发现&#xff0c;近日国家知产局发布《商标代理委托合同示范文本》征求意见稿&#xff0c;虽然是参考使用不具有强制性&#xff0c;里面对商标名称注册查询描述是申请前商标检…

完成UI界面的绘制

绘制UI 接上文&#xff0c;在Order90Canvas下创建Image子物体&#xff0c;图片资源ui_fish_lv1&#xff0c;设置锚点&#xff08;CountdownPanelImg同理&#xff09;&#xff0c;命名为LvPanelImg,创建Text子物体&#xff0c;边框宽高各50&#xff0c; &#xff0c;重名为LvT…

阻焊层解析:PCB的“保护伞”是什么?

在电子制造行业中&#xff0c;尤其是PCBA贴片加工领域&#xff0c;阻焊层是一个重要的概念。以下是对阻焊层的详细讨论分析&#xff0c;包括其定义、作用以及类型。 阻焊层的定义 阻焊层&#xff0c;顾名思义&#xff0c;是一种用于阻止焊接的材料层。在PCB&#xff08;印刷电…

11.C++程序中的常用函数

我们将程序中反复执行的代码封装到一个代码块中&#xff0c;这个代码块就被称为函数&#xff0c;它类似于数学中的函数&#xff0c;在C程序中&#xff0c;有许多由编译器定义好的函数&#xff0c;供大家使用。下面就简单说一下&#xff0c;C中常用的函数。 1.sizeof sizeof函…

Perceptually Optimized Deep High-Dynamic-RangeImage Tone Mapping

Abstract 我们描述了一种深度高动态范围&#xff08;HDR&#xff09;图像色调映射算子&#xff0c;该算子计算效率高且感知优化。 我们首先将 HDR 图像分解为归一化拉普拉斯金字塔&#xff0c;并使用两个深度神经网络 (DNN) 根据归一化表示估计所需色调映射图像的拉普拉斯金字…

Mybatis缓存机制(图文并茂!)

目录 一级缓存 需求我们在一个测试中通过ID两次查询Monster表中的信息。 二级缓存 案例分许(和上述一样的需求) EhCache第三方缓存 在了解缓存机制之前&#xff0c;我们要先了解什么是缓存&#xff1a; ‌缓存是一种高速存储器&#xff0c;用于暂时存储访问频繁的数据&…

利用大模型改进知识图谱补全的研究

人工智能咨询培训老师叶梓 转载标明出处 尽管现有的基于描述的KGC方法已经利用预训练语言模型来学习实体和关系的文本表示&#xff0c;并取得了一定的成果&#xff0c;但这些方法的性能仍然受限于文本数据的质量和结构的不完整性。 为了克服这些限制&#xff0c;中国科学技术…

PG高可靠模拟

模拟延迟 主库故障&#xff0c;备库尝试切换为主库

9.29 LeetCode 3304、3300、3301

思路&#xff1a; ⭐进行无限次操作&#xff0c;但是 k 的取值小于 500 &#xff0c;所以当 word 的长度大于 500 时就可以停止操作进行取值了 如果字符为 ‘z’ &#xff0c;单独处理使其变为 ‘a’ 得到得到操作后的新字符串&#xff0c;和原字符串拼接 class Solution { …

MySQL - 运维篇

一、日志 1. 错误日志 2. 二进制日志 3. 查询日志 记录了所有的增删改查语句以及DDL语句 4. 慢查询日志 二、主从复制 1. 概述 2. 原理 3. 搭建 三、分库分表 1. 介绍 2. Mycat概述 3. Mycat入门 4. Mycat配置 5. Mycat分片 6. Mycat管理及监控 四、读写分离 1. 介绍 2. 一…

【ADC】使用运算放大器驱动 SAR 型 ADC 时的线性输入范围

概述 本文学习于TI 高精度实验室课程&#xff0c;总结使用运算放大器驱动 SAR ADC 时的注意事项。具体包括&#xff1a;了解运算放大器共模范围和输出摆幅限制如何影响 SAR ADC 性能&#xff0c;研究运算放大器设计技术以避免共模和输出摆幅限制&#xff0c;讨论轨到轨放大器与…

PCB敷铜敷不了相同网络的线怎么办?

图片上的情况就是今天需要讲的内容&#xff0c;可以看出出来的线头是GND,敷的铜也是GND但是相同网络就是不能连在一起。 解释&#xff1a; 这是因为我们敷铜的时候属性选的是连接相同的net,如图所示&#xff1a; 解决办法&#xff1a; 只需要设置改为相同的Object就可以了&…

[Linux#60][HTTPS] 加密 | 数字指纹 | 详解HTTPS工作方案 | CA认证

目录 一.预备知识 1. 什么是HTTPS&#xff1f; 2. HTTP与HTTPS的区别 3. 什么是加密&#xff1f; 4. 常见的加密方式 4.1 对称加密 4.2 非对称加密 4.3 数据摘要与数据指纹 4.4 数字签名 二. HTTPS的工作方案 1 方案一&#xff1a;对称加密 2 方案二&#xff1a;非…