《C语言程序设计:问题与求解方法》——3.4节验证算法的方法-阿里云开发者社区

开发者社区> 华章计算机> 正文

《C语言程序设计:问题与求解方法》——3.4节验证算法的方法

简介:
+关注继续查看

本节书摘来自华章社区《C语言程序设计:问题与求解方法》一书中的第3章,第3.4节验证算法的方法,作者:何 勤,更多章节内容可以访问云栖社区“华章社区”公众号查看

3.4 验证算法的方法
前面说过,找到求解问题的算法对解决编程问题至关重要。但如何验证算法的正确性呢?本节将介绍采用画变量(内存单元)取值变化图来验证算法的方法(参见对例题3.3的算法验证),这也是成为程序员或编程高手的一种极为重要的技能。采用这种方法有两个好处:
1)大大减少不必要的编程工作量。在写出算法而尚未编出程序时,就可以检查算法是否存在逻辑错误或边界错误(数组的边界错误,或者循环次数多一次或少一次)、程序的流程是否构造正确等,从而减少了不必要的编程工作量。这类似于在装修前画出立体效果图,让用户感受一下在其中生活是否会感到舒服一样。如果用户感觉不好,可重新修改设计,大大减少了实际装修完后才返工的极大损失。毕竟重写和修改伪代码要比重写或修改程序省事多了—尤其是对一个大型程序。
2)可使读者读懂较难程序或算法的能力得到极大的提高。而阅读程序和算法的能力,是一个人能够否成为编程高手的最重要的、决定性因素之一。
希望读者至少用这种方法来分析和阅读几十个你认为比较难懂而又比较有趣的算法或程序,使之成为你的编程工具箱中的一件“利器”,并且养成一种良好的编程习惯。在用伪代码写出算法后,不要急于把它转换成高级语言的程序,而是用这种在纸面上运行、走查的方法去验证算法,尽可能在早期找出并修改算法中的逻辑错误或边界错误。
当然,即使通过这种验证,也不能保证这个算法是完全正确和完善的。对于语法错误更是无能为力。但这种验证的重要价值,我们绝对不能否认。
如果不用此方法来进行验证,在写出算法后就立即编程。仅仅依赖于运行编译程序来进行简单调试,你很可能最终会得到一个没有任何语法错误和运行时错误的程序。然而,此程序得到的结果要么可能是完全不正确的(逻辑错),要么此程序存在边界错误。如果是逻辑错误,则整个编程和调试工作完全是白费力气。在编写大型程序时,这种时间的浪费是一个很严重的问题。
【例题3.3】将一个三位整数反向后输出。(类型:必修题;趣味性:;难度:*)
一级算法:
1 输入一个三位整数→n
2 通过利用学过的算术运算符整除 / 和取余数 % 进行分解,分别求出此三位整数n的百位数n3,十位数n2和个位数n1
3 反向后的三位整数为 num=n1100+n210+n3
4 输出此三位数
其中第2步由于不能立即写出C语言的语句,需要进一步求精:
2.1 求出n的百位数:n3=n/100
2.2 求出n的十位数:n2=(n-n3*100)/10
2.3 求出n的个位数:n1=n%10
算法验证:执行算法第1步,假设将一个任意指定的三位整数(比如315)输入变量n中,用于验证上述算法过程的正确性。执行算法第1步后,变量的内存单元取值将如图3-1所示。

 n3    n2    n1    num

315 不确定 不确定 不确定 不确定


173c5d8ee560b179ecd94bb518dc12aa3f82842d

执行算法2.2步的赋值语句n2=(n–n3100)/10。先计算表达式(n–n3100)/10,将n和n3的当前值从内存中取出代入表达式,进行表达式规定的运算:(315–3*100)/10,得到结果1 ,存入变量n2中。算法2.2步执行完后,变量的内存单元取值将如图3-3所示(变量n2的值发生了变化)。
n n3 n2 n1 num
315 3 1 不确定 不确定


3cff271bd4de9e52861dbdd00277152188195539

经过以上验证,315确实变成了513,算法逻辑上的确是正确的。
将上述经过纸面运行走查验证的算法,转化为C语言程序如下:

1  #include<stdio.h>
2  int  main(void)
3  {
4   int  n;/*输入变量*/    
5   int  n3,n2,n1;/*中间变量*/
6   int  num; /* 结果变量*/
7   /*输入一个三位整数n*/
8   printf("请输入一个三位整数\n");  
9   scanf("%d", &n);  
10
11  /*分别求出它的百位数n3,十位数n2,个位数n1*/
12   n3=n/100;            
13   n2=(n-n3*100)/10; 
14   n1=n%10;          
15
16  /*反向后的三位整数为*/
17  num=n1*100+n2*10+n3;  
18
19  /*输出此三位数*/
20  printf("num=%d",num);      
21  return 0;         
22 }
【问题1】是否可以将第17行和第20行合并为下面这一句并删掉第6行?
printf("num=%d", n1*100+n2*10+n3);

答:可以。printf()函数调用时,格式串后的输出项可以是一个表达式。
【问题2】是否可以将第12行和第13行颠倒语句次序?用画变量内存单元取值变化图的方法验证你的结论。
答:不可以。变量n3会出现初始化错误。第13行表达式中的n3依赖第12行的语句初始化。
【问题3】是否可以将第13行与第14行互换?
答:可以。因为两条赋值语句之间的变量并没有依赖关系。
【问题4】是否可以将所有变量n,n3,n2,n1都用float型来定义?
答:不可以。程序第12行、第13行的赋值语句的表达式,都要求是整除运算。第14行的n%10,运算符 % 也要求变量n是整型,而不是实型。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
《Java 7程序设计入门经典》一2.6 运算符
本节书摘来自华章出版社《Java 7程序设计入门经典》一书中的第2章,第2.6节,作者(美)Herbert Schildt Dale Skrien,更多章节内容可以访问云栖社区“华章计算机”公众号查看
903 0
C语言及程序设计进阶例程-25 排序问题及其求解
贺老师教学链接 C语言及程序设计进阶 本课讲解 快速排序实现 #include&lt;stdio.h&gt; void quicksort(int data[],int first,int last) { int i, j, t, base; if (first&gt;last) return; base=data[first];
1025 0
《Java 7程序设计入门经典》一2.10 赋值运算符
本节书摘来自华章出版社《Java 7程序设计入门经典》一书中的第2章,第2.10节,作者(美)Herbert Schildt Dale Skrien,更多章节内容可以访问云栖社区“华章计算机”公众号查看
873 0
函数计算部署机器学习遇到的问题和解法
随着 Serverless 的流行,将应用迁移到云上已经成了一种必然的趋势。我们今天来看一下如何将机器学习应用迁移到函数计算上。 1. 本地开发 首先我们看一下本地开发机器学习应用的步骤。我们大概可以将本地开发概括为三个步骤,分别是代码编写,安装依赖,运行调试。
3391 0
《算法设计编程实验:大学程序设计课程与竞赛训练教材》——3.3 积性函数的实验范例
本节书摘来自华章计算机《算法设计编程实验:大学程序设计课程与竞赛训练教材》一书中的第3章,第3.3节,作者:吴永辉,王建德著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1212 0
带你读《Java程序设计与计算思维》之一:计算思维与Java设计初步体验
程序设计的过程就是一种计算思维的表现,《Java程序设计与计算思维》结合Java程序设计语言的教学特点,遵循计算思维的方式,图解重要概念,通过大量的范例程序讲解和上机编程实践来指导读者活用Java程序语法,兼顾培养计算思维和学习面向对象程序设计的双目标。
871 0
面试题:使用递归的方法计算1到100的累加。
今天去面试,遇到这道题目,有段时间没写程序了,温习一下: 题目是使用递归的方法计算1到100的累加,也就是计算1+2+3+4+........+100。大家想必已经听说过高斯如何计算这道题的故事,也知道答案是5050。
954 0
C语言及程序设计进阶例程-27 贪心法问题求解
贺老师教学链接 C语言及程序设计进阶 本课讲解 找零钱问题及其求解 #include &lt;stdio.h&gt; int main ( ) { int money[10]={100,50,10,0}; /*最大面额的硬值面值排在最前面,将被优先处理*/ int x; /*找零金额*/ int i=0, n=0, m; scanf
1072 0
10059
文章
0
问答
来源圈子
更多
+ 订阅
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载