新书推荐:7.1 do while语句

本节必须掌握的知识点:

    示例二十二

        代码分析

        汇编解析

do while语句其语法形式

do{

语句块;

}while(表达式)

语法解析:

●执行do循环体内的语句块;

●判断while语句里的表达式,表达式为真继续下次循环,若为假则跳出循环;

7.1.1 示例二十二

示例代码二十二

●第一步:分析需求,设计程序结构框架。

分析需求:重复输入一个整数并判断该整数是奇数还是偶数。

设计程序结构框架:循环结构(do/while语句)中嵌套一个if/else结构。

 ●第二步:数据定义,定义恰当的数据结构;

       int GoOn = 0;//定义一个int类型的整型局部变量,并初始化为0。GoOn变量作为do/while语句的循环控制变量。

int num;//定义一个int类型的整型局部变量,利用scanf_s接收键盘输入整数完成初始化。

   ●第三步:分析算法。

       利用do/while语句结构重复实现一个过程。

该过程为:从键盘输入一个整数,利用(num % 2)的算法判断和输出该整数是奇数还是偶数。

判断完成后,输出结果。

   ●第四步:编写伪代码,即用我们自己的语言来编写程序。

       int main(void) {

    定义一个int类型整型变量GoOn=0;

定义一个int类型整型变量num

    do{

        调用printf函数打印一个提示信息"请输入一个整数:\t"

        调用scanf_s函数接收键盘输入一个整数,并存入变量num;                           

        if(num%2)

            如果num%2的模为真:调用printf函数输出"这个数是奇数\n";

else

如果num%2的模为假:调用printf函数输出"这个数是偶数\n";      

调用printf函数打印一个提示信息"重复输入1,不重复输入2:\t"

调用scanf_s函数接收键盘输入一个整数,并存入变量GoOn;

}while(如果GoOn等于1则继续循环)

system("pause");

    return 0;                                                                                                    

}

●第五步:画流程图,使用Visio、Excel或者其他绘图工具绘制算法流程和逻辑关系图;

 

图7-1 示例二十二do while语句流程图

    

●第六步:编写源程序,其实就是将我们的伪代码翻译成计算机语言;

/*

   重复输入一个整数并判断该整数是奇数还是偶数

*/

#include <stdio.h>

#include <stdlib.h>

int main(void) {

    int GoOn = 0; //已初始化

    int num; //未初始化

    do {

        printf("请输入一个整数:\t");

        scanf_s("%d", &num);

        if (num % 2)

        {

            printf("这个数是奇数\n");

        }

        else

        {

            printf("这个数是偶数\n");

        }

        printf("重复输入1,不重复输入2:\t");

        scanf_s("%d", &GoOn);

    } while (GoOn == 1);

    system("pause");

    return 0;

}

输出结果:

请输入一个整数: 1

这个数是奇数

重复输入1,不重复输入2: 1

请输入一个整数: 2

这个数是偶数

重复输入1,不重复输入2: 2

●第七步:调试程序,修复程序中可能出现的BUG;

参见反汇编代码。

●第八步:优化代码,尝试更好的设计方案,效率更高的算法,逻辑更为清晰简洁明了。

(无)

7.1.2 代码分析

示例二十二是一个do/while结构嵌套一个if/else结构的程序。

1. 进入do语句主体,在控制台窗口输出“请输入一个整数”;

2. 在控制台输入:1;

3.判断 1%2有余数,执行printf(“这个数是奇数”);

4.执行printf("重复输入1,不重复输入2:\t");

5.如果我们输入1,那么将再次循环进入do语句主体;如果输入2则直接退出循环。

因为while里的表达式是GoOn的值判断是否等于1,如果等于1则继续循环,如果不等则退出循环。

显然这是一个标志循环,循环的次数是不确定的。根据循环控制变量GoOn是否为标志值1来决定是否继续循环。

7.1.3 汇编解析

汇编代码

;C标准库头文件和导入库

include vcIO.inc

.data

GoOn sdword  0

num  sdword  ?

.const    

szMsg1 db "请输入一个整数:",0

szMsg2 db "%d",0

szMsg3 db "这个数是奇数",0dh,0ah,0

szMsg4 db "这个数是偶数",0dh,0ah,0

szMsg5 db "重复输入1,不重复输入2:",09h,0

.code     

start:

NEXT:    

       ;输入整数num

       invoke printf,offset szMsg1

       invoke scanf,offset szMsg2,ADDR num

       ;

       mov eax,num

       mov ebx,2

       cdq                ;被除数扩展到EDX:EAX

       idiv ebx

       .if edx

              invoke printf,offset szMsg3

       .else

              invoke printf,offset szMsg4 

       .endif     

       ;输入控制变量

       invoke printf,offset szMsg5

       invoke scanf,offset szMsg2,ADDR GoOn

       ;

       .if GoOn == 1

              jmp NEXT

       .endif

       ;     

       invoke _getch

       ret                       

end start

●输出结果:

请输入一个整数:1

这个数是奇数

重复输入1,不重复输入2: 1

请输入一个整数:2

这个数是偶数

重复输入1,不重复输入2: 1

请输入一个整数:3

这个数是奇数

重复输入1,不重复输入2: 2

       由上述的汇编代码我们可知,C语言中的do/while语句对应的汇编实现方法为:

NEXT:

       .if GoOn == 1

              jmp NEXT

       .endif

       当GoOn == 1时,使用jmp指令直接跳转到NEXT:地址标号处,开始下一轮循环。

反汇编代码

           int GoOn = 0;//已初始化

00AD1952  mov         dword ptr [GoOn],0 

    int num;//未初始化

    do {

        printf("请输入一个整数:\t");

00AD1959  push        offset string "\xc7\xeb\xca\xe4\xc8\xeb\xd2\xbb\xb8\xf6\xd5\xfb\xca\xfd:\t" (0AD7B30h) 

00AD195E  call        _printf (0AD104Bh) 

00AD1963  add         esp,4 

        scanf_s("%d", &num);

00AD1966  lea         eax,[num] 

00AD1969  push        eax 

        scanf_s("%d", &num);

00AD196A  push        offset string "%d" (0AD7B44h) 

00AD196F  call        _scanf_s (0AD1154h) 

00AD1974  add         esp,8 

        if (num % 2)

00AD1977  mov         eax,dword ptr [num] 

00AD197A  and         eax,80000001h 

00AD197F  jns         main+66h (0AD1986h;如果num为正整数,则跳转到0AD1986h地址处

00AD1981  dec         eax  ;num为负整数

00AD1982  or          eax,0FFFFFFFEh 

00AD1985  inc         eax 

00AD1986  test        eax,eax  ;测试eax是否为0

00AD1988  je          main+79h (0AD1999h) ;如果eax==0为偶数,跳转到0AD1999h地址处

        {

            printf("这个数是奇数\n");

00AD198A  push        offset string "\xd5\xe2\xb8\xf6\xca\xfd\xca\xc7\xc6\xe6\xca\xfd\n" (0AD7B48h) 

00AD198F  call        _printf (0AD104Bh) 

00AD1994  add         esp,4 

        }

00AD1997  jmp         main+86h (0AD19A6h) 

        else

        {

            printf("这个数是偶数\n");

00AD1999  push        offset string "\xd5\xe2\xb8\xf6\xca\xfd\xca\xc7\xc5\xbc\xca\xfd\n" (0AD7B58h) 

00AD199E  call        _printf (0AD104Bh) 

00AD19A3  add         esp,4 

        }

        printf("重复输入1,不重复输入2:\t");显示提示信息

00AD19A6  push        offset string "\xd6\xd8\xb8\xb4\xca\xe4\xc8\xeb1\xa3\xac\xb2\xbb\xd6\xd8\xb8\xb4\xca\xe4\xc8\xeb2:\t" (0AD7B68h) 

00AD19AB  call        _printf (0AD104Bh) 

00AD19B0  add         esp,4 

        scanf_s("%d", &GoOn);键盘输入整数值并存入变量GoOn地址处

00AD19B3  lea         eax,[GoOn] 

00AD19B6  push        eax 

00AD19B7  push        offset string "%d" (0AD7B44h) 

00AD19BC  call        _scanf_s (0AD1154h) 

00AD19C1  add         esp,8 

    } while (GoOn == 1);

00AD19C4  cmp         dword ptr [GoOn],1   ;比较GoOn和1是否相等

00AD19C8  je          main+39h (0AD1959h; GoOn == 1时,跳转到0AD1959h地址处

    system("pause");

00AD19CA  mov         esi,esp 

00AD19CC  push        offset string "pause" (0AD7B88h) 

00AD19D1  call        dword ptr [__imp__system (0ADB168h)] 

00AD19D7  add         esp,4 

       由上述反汇编代码可知:

       C语言中的do/while语句翻译为汇编指令语句为:

00AD1959:do循环的开始地址

} while (GoOn == 1);循环条件判断语句

00AD19C4  cmp         dword ptr [GoOn],1   ;比较GoOn和1是否相等

00AD19C8  je          main+39h (0AD1959h; GoOn == 1时,跳转到0AD1959h地址处

结论

1.while语句是先判断后执行(下一节详细讲述);

2.do while语句是先执行后判断,属于标志循环,循环次数不确定;

3.do while语句通常用于输入检查。

4.不要忘记while后面的条件语句以’;’结尾。

    在C语言中 for,while ,do while语句本质没有区别,可以相互转换,只是在使用形式上,do while 语句适合用于至少执行一次的循环。而while语句中,如果条件不成立,永远不会执行循环体内的代码。

实验四十二:do while语句实现输入检查

在VS中新建项目7-1-2.c,使用do while语句改写示例二十一,实现循环输入并对输入进行错误检查。

/*

   do/while语句实现循环输入并对输入进行错误检查

*/

#include <stdio.h>

#include <stdlib.h>

int main(void) {

    int GoOn = 0;//已初始化

    int day = 0;

    printf("\t\t☆☆☆☆☆天气查询☆☆☆☆☆\n");

    printf("\t\t   ☆查询周一天气请输入:1\n");

    printf("\t\t   ☆查询周二天气请输入:2\n");

    printf("\t\t   ☆查询周三天气请输入:3\n");

    printf("\t\t   ☆查询周四天气请输入:4\n");

    printf("\t\t   ☆查询周五天气请输入:5\n");

    printf("\t\t   ☆查询周六天气请输入:6\n");

    printf("\t\t   ☆查询周日天气请输入:7\n");

    do {

        do

        {

            printf("请输入查询天气:");

            scanf_s("%d", &day);

            if (day < 1 || day > 7)

                printf("输入错误,请重新输入(1,2,3,4,5,6,7任意一个整数值)\n");

        } while (day < 1 || day > 7);

        switch (day)

        {

        case 1:

            printf("周一天气:晴天\n");

            break;

        case 2:

            printf("周二天气:阴天\n");

            break;

        case 3:

            printf("周三天气:大雨\n");

            break;

        case 4:

            printf("周四天气:中雪\n");

            break;

        default:

            printf("周%d天气:雨夹雪\n", day);

            break;

        }

        printf("重复输入1,不重复输入2:\t");

        scanf_s("%d", &GoOn);

    } while (GoOn == 1);

    system("pause");

    return 0;

}

●输出结果:

请输入查询天气:1

周一天气:晴天

重复输入1,不重复输入2: 1

请输入查询天气:7

周7天气:雨夹雪

重复输入1,不重复输入2: 1

请输入查询天气:0

输入错误,请重新输入(1,2,3,4,5,6,7任意一个整数值)

请输入查询天气:8

输入错误,请重新输入(1,2,3,4,5,6,7任意一个整数值)

请输入查询天气:3

周三天气:大雨

重复输入1,不重复输入2: 2

实验四十二使用了两个do while语句进行了嵌套,外层的do while语句实现了重复查询天气的功能,内层的do while语句对输入的变量day的值进行了错误检查。如果day <1或day > 7,则提示重新输入正确的值。确保了键盘输入的整数值必须在1~7之间,防止输入错误的出现。这种设计是非常有必要的,增强了程序的稳定性和人性化设计。

练习

  1. 请读者书写程序7-1-2.c伪代码,并绘制流程图。
  2. 请读者将7-1-2.c翻译成汇编语言实现。
  3. 请读者分析7-1-2.c的反汇编代码。

4、假设用户的密码是一个三位整数,令用户输入密码,如果输入成功,则提示“正确”。如果输入错误,则提示“您输入的密码有误”,并提示重新输入密码。最多输入三次,如果三次没有成功,则退出程序。

5、  (1)打印0~100中所有的偶数。

(2)打印0~100中所有的奇数

       6、根据读取的整数值显示所出的拳(只接收0,1,2),【0...石头/1...剪刀/2...布】。

7、不停的输入整数,显示和及平均值。

8、编写一段程序重复实现:读取两个整数的值,然后计算并显示两个整数的和。

9、编写一段程序重复实现:读取两个整数的值,然后计算并显示两个整数的平均值。

10、编写一段程序重复实现:读取一个整数的值,然后判断该整数是正数、负数或零。

本文摘自编程达人系列教材《汇编的角度——C语言》。

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

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

相关文章

stm32学习-串口收发(HEX/文本)数据包

串口收发HEX数据包 接线 TXDPA10RXDPA9按键PB1 配置流程 定义为固定包长&#xff0c;含包头包尾&#xff08;其中包头为0xFF&#xff0c;载荷数据固定为4字节&#xff0c;包围为0xFE&#xff09; 注意&#xff1a;固定包长/可变包长&#xff0c;或者包头包围是什么&#xf…

UI控件与视图层次:探索界面的无限可能

[OC]UI学习笔记 文章目录 [OC]UI学习笔记视图和视图层次结构CGRectUILabelUIButtonUIView控件UIView的层级关系UIWindow定时器和视图移动UISwitch进度条和滑动条控件步进器和分栏控件警告对话框与等待指示器UITextField 视图和视图层次结构 Objective-C中的UI编程主要围绕视图…

C++的哈希 哈希表 哈希桶

目录 Unordered系列关联式容器 什么是哈希 哈希表 闭散列 载荷因子α 扩容 查找 删除 字符串哈希算法 最终代码 开散列 插入 查找 删除 最终代码 完整代码 Unordered系列关联式容器 C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0…

大学校园广播“录编播”与IP广播系统技术方案

一、项目概述 1、校园IP网络广播系统概述 大学校园广播系统是学校整个弱电系统中的子系统&#xff0c;它是每个学校不可缺少的基础设施之一&#xff0c;在传递校园文化、传播校园新闻资讯方面发挥着重要的作用。近几年来&#xff0c;虽然视频技术和网络技术在飞速发展&#xf…

行为设计模式之策略模式

文章目录 概述原理结构图 代码实现小结 概述 策略模式(strategy pattern)的原始定义是&#xff1a;定义一系列算法&#xff0c;将每一个算法封装起来&#xff0c;并使它们可以相互替换。策略模式让算法可以独立于使用它的客户端而变化。 在软件开发中也会遇到相似的情况&…

基于双差分值和RR间隔处理的心电信号R峰检测算法(MATLAB R2018A)

心电信号中的R峰是确定心率和节律、以及检测其它波形特征点&#xff08;图1A&#xff09;的基础。R峰的准确检测是心率变异性分析、心拍分割和心律失常识别重要的处理步骤。 现有的心电信号R峰检测方法主要为基于规则的决策法和基于深度学习的检测方法。基于规则的决策法通常对…

中国低调海外巨头,实力超乎想象!

在全球化的浪潮中&#xff0c;中国公司正以前所未有的速度和规模走向世界。他们或许低调&#xff0c;但却实力非凡&#xff0c;在国际市场上掀起了一股不可小觑的“中国风暴”。今天&#xff0c;就让我们揭开那些在国外牛逼到爆炸的中国公司的神秘面纱&#xff0c;深度解析他们…

mysql中InnoDB的表空间--系统表空间

大家好。上篇文章我们讲了InnoDB的独立表空间&#xff0c;我们知道了表空间被划分为许多连续的区&#xff0c;对于大小为16KB的页面来说&#xff0c;每个区默认由64个页组成&#xff0c;每256个区为一组&#xff0c;每个组最开始的几个页的类型是固定的。&#xff08;在这里强烈…

HCIP-Datacom-ARST自选题库__BGP判断【20道题】

1.传统的BGP-4只能管理IPV4单播路由信息&#xff0c;MP-BGP为了提供对多种网络层协议的支持&#xff0c;对BGP-4进行了扩展。其中MP-BGP对IPv6单播网络的支持特性称为BGP4&#xff0c;BGP4通过Next Hop属性携带路由下一跳地址信息。 2.BGP4通过Update报文中的Next Hop属性携带…

RK3568笔记二十六:音频应用

若该文为原创文章&#xff0c;转载请注明原文出处。 一、介绍 音频是我们最常用到的功能&#xff0c;音频也是 linux 和安卓的重点应用场合。 测试使用的是ATK-DLR3568板子&#xff0c;板载外挂RK809 CODEC芯片&#xff0c;RK官方驱动是写好的&#xff0c;不用在自己重新写。…

智慧城市运维可视化:透视未来城市高效管理的新视窗

行业痛点 现代城市运维是一个复杂而庞大的系统&#xff0c;涉及到诸多方面&#xff0c;包括交通、环境、能源等等。然而&#xff0c;在城市运维中&#xff0c;存在着一些现实的痛点&#xff0c;给城市管理者带来了不小的压力和困扰&#xff1a; 1、交通拥堵 随着城市化进程的…

帝国cms自定义专题列表模板list.var中获取对应专题下的信息、信息数量及信息所属栏目名称

帝国cms自定义专题列表模板list.var中获取对应专题下的信息、信息数量及信息所属栏目名称 代码如下&#xff1a; $rr $empire->fetch1("SELECT GROUP_CONCAT(id) from phome_enewsztinfo where ztid$r[id]"); $ff $rr[0]; $ga explode(",", $ff); …

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑分布式光伏高效消纳与负荷损失最小的区域配电网应急资源协同配置策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

一款网站源码下载开源工具 Website Downloader

一、简介 Website Downloader 是一款免费的网站源码下载器&#xff0c;下载任何网站的完整源代码&#xff0c;包括 JavaScript、样式表、图像等等&#xff0c;而且使用也非常简单&#xff0c;只需要粘贴网址&#xff0c;用户即可将网页链接内容下载到本地&#xff0c;而且自动…

堆(建堆算法,堆排序)

目录 一.什么是堆&#xff1f; 1.堆 2.堆的储存 二.堆结构的创建 1.头文件的声明&#xff1a; 2.向上调整 3.向下调整 4.源码&#xff1a; 三.建堆算法 1.向上建堆法 2.向下建堆法 四.堆排序 五.在文件中Top出最小的K个数 一.什么是堆&#xff1f; 1.堆 堆就…

Docker之xfs文件系统下安装报错解决方案

一、需求说明 centos系统下安装docker最新版的时候&#xff0c;安装成功&#xff0c;启动的时候报错。报错信息“failed to start daemon: error initializing graphdriver: overlay2: the backing xfs filesystem is formatted without d_type support, which leads to incorr…

ROS添加GDB调试

文章目录 一、问题描述二、配置步骤1. debug 模式编译2. rosrun 添加GDB指令3. launch 添加GDB指令 三、GDB基本命令1. 基本2. 显示被调试文件信息3. 查看/修改内存4. 断点5. 调试运行 一、问题描述 在享受ROS带来便利的同时&#xff0c;但因每运行出现错误&#xff0c;ROS不会…

风电机组的振动控制

文章目录 0. 背景1. 原文记录 0. 背景 混塔机组的频率大概是目前业内遇见的比较普遍的通病。最近在了解风电机组振动控制的知识&#xff0c;看到一篇科普性质的文章&#xff0c;感觉不错&#xff0c;所以记录下来。想要看原文的点击这里。感谢原作者。 1. 原文记录

一文带你了解.NET能做什么?

前言 在DotNetGuide技术社区微信交流群经常看到有小伙伴问&#xff1a;.NET除了能写桌面应用和Web应用还能做什么&#xff1f;今天大姚将通过本篇文章来简单讲讲.NET能做哪些开发&#xff0c;对.NET感兴趣的小伙伴也可以自行领取文末附带的.NET相关学习资料。 .NET简单介绍 .…

多层派生时的构造函数和派生类的析构函数

一、多层派生时的构造函数 目录 一、多层派生时的构造函数 二、派生类的析构函数 析构函数的作用&#xff1a; 例&#xff1a;多级派生情况下派生类的构造函数 #include <iostream> #include<string> using namespace std; class Student { public:Student(int…