第3周-任务2-改造坏程序

简介: 题目:(教材P261页第1题)上机前在纸上先找出错误,然后上机调试,使之正常运行。运行时输入时分秒,检查输出是否正确。 要求:在实验报告中,在改动处加注释说明理由 #include <iostream>using namespace std;class Time{ void set_time(void) ; void show_time(void); int

题目:(教材P261页第1题)上机前在纸上先找出错误,然后上机调试,使之正常运行。运行时输入时分秒,检查输出是否正确。

要求:在实验报告中,在改动处加注释说明理由

#include <iostream>
using namespace std;
class Time
{ 
	void set_time(void) ;
	void show_time(void);
	int hour;
	int minute;
	int sec;
};
Time t;

int main()
{
	set_time();
	show_time();
	return 0; 
}
int set_time(void)  
{
	cin>>t.hour;
	cin>>t.minute;
	cin>>t.sec;
}


int show_time(void) 
{
	cout<<t.hour<<":"<<t.minute<<":"<<t.sec<<endl;
}

反思同学们在后面编程中出现的问题,此题中的程序太坏了。甚至我有些后悔布置这道题,此题中的毛病有此传染哩。因此,必须坚决地揭露此程序中的坏分子,让其曝光于这朗朗乾坤。

在改错以前,我先将其中错误及不妥之处标出。我们要从全局的角度看待这个程序,否则,改一处带来的其他错误会将人绕晕。

#include <iostream>
using namespace std;
class Time  
{ 
	void set_time(void) ;
	void show_time(void);
	int hour;
	int minute;
	int sec;
};   //在这个类的定义中,语法并无错误,但其成员的属性都采用了默认值(private),这会导致在使用类的对象时,无法访问其任何成员
     //改进思路:在一般情况下,将数据成员声明为私有(private),而成员函数声明为公有(public)。
     //要极其谨慎地将数据成员声明为公有,必要时,只为本类内使用的成员函数作为私有类型

Time t; //从语法角度,也无任何问题。但是任何时候,使用全局变量(对象)
        //此处既是一坏,改造程序时将t的定义放入main()函数中,作局部变量(对象)使用。本题只在于创建一个时间对象并显示,这样做是合适的

int main()
{
	set_time();   //可以想到在面向对象的程序中,此句为对象的成员函数的调用。这句可能不会出问题,是因为set_time()在后面并未被定义为成员函数;
                      //另外,若真不将set_time()作为成员函数对待的话,先调用、后定义也不妥。
	show_time();  //同上
	return 0; 
}
int set_time(void)  //结合背景,显然这应该要定义在类中声明的成员函数,遗漏了类作用符“Time::”,这是大事。另外,返回值类型和类中的声明也不相同
{
	cin>>t.hour;     //在类的成员函数中,类的数据成员是可以直接使用的。之前将t不当地定义为全局变量(对象)可能避免了编译器检查出此问题|
                         //直接用,即cin>>hour,意味着该类中任何一个对象均可以通过cin为其hour成员获得值
                         //在类的成员函数中,cin>>t.hour意味着是为该类中的一个特殊对象t服务的,天理不容
	cin>>t.minute;   //同上
	cin>>t.sec;      //同上
}


int show_time(void)      //同上一成员函数
{
	cout<<t.hour<<":"<<t.minute<<":"<<t.sec<<endl;
}

所以,改正的程序是:

#include <iostream>
using namespace std;
class Time
{
public:   //成员函数为public型
	void set_time(void) ;
	void show_time(void);
private:  //数据成员为privte型
	int hour;
	int minute;
	int sec;
};

int main()
{
	Time t;    //声明局部于main()的对象
	t.set_time();   //调用类的公共成员是这样嘀……
	t.show_time();
	return 0; 
}
void Time::set_time(void)  //加上“Time::”,明确set_time是类的成员函数,前面已经声明,现在正式定义(实现)
                           //函数返回值类型改为void,与类中的声明一致
{
	cin>>hour;   //去除hour前的“t.”,意味着哪个对象调用set_time,输入的就是这个对象的hour值
	cin>>minute;
	cin>>sec;
}

void Time::show_time(void) //参见set_time的修改说明
{
	cout<<hour<<":"<<minute<<":"<<sec<<endl;   //数据成员前的“t.”全去除
}

总结:需要不断深刻理解类和对象的概念,并将其思想用于程序设计的实践;通过对此类程序的剖析,加深对基本概念的理解。相辅相成,循环往复,不断进步。


<本文完>

目录
相关文章
|
7月前
|
测试技术
缺少BA的软件交付过程是如何搞死团队的?
缺少BA的软件交付过程是如何搞死团队的?
|
3月前
|
Python
从零到零点五,编译zeno节点系统
本文介绍了如何从零开始编译Zeno节点系统,包括编译后运行的结果、核心编译代码、编译文件目录、解决zenvis编译问题的方法,以及相关参考链接。作者提供了详细的步骤和命令,帮助读者能够成功编译Zeno,并分享了解决问题的经验和技巧。
从零到零点五,编译zeno节点系统
|
7月前
|
算法 程序员
为何程序员在编写程序时难以一次性将所有代码完美无瑕地完成,而是需要经历反复修改Bug的过程?
为何程序员在编写程序时难以一次性将所有代码完美无瑕地完成,而是需要经历反复修改Bug的过程?
74 7
|
SQL 缓存 NoSQL
写代码有这16个好习惯,可以减少80%非业务的bug
每一个好习惯都是一笔财富,本文整理了写代码的16个好习惯,每个都很经典,养成这些习惯,可以规避多数非业务的bug!希望对大家有帮助哈,谢谢阅读,加油哦~1. 修改完代码,记得自测一下...
353 0
|
架构师 测试技术 uml
这才是业务用例,别再搞错了!
这才是业务用例,别再搞错了!
1183 0
|
设计模式 存储 JavaScript
🙅‍都说太多if...else不好,那有没有可以直接抄的改造方案呢?
开发过程中,经常遇到大量的if...else逻辑,这使得代码复杂、难以维护。但别担心!这里会引导你走出这个困境!
122 0
|
消息中间件 缓存 NoSQL
用一个月重构了同事写的烂代码,我总结了8条重写烂代码的经验!
用一个月重构了同事写的烂代码,我总结了8条重写烂代码的经验!
|
XML Java 数据库连接
工作几年了,原来我只用了数据校验的皮毛~
前言 什么是 JSR-303? 添加依赖 内嵌的注解有哪些? 如何使用? 简单校验 分组校验 嵌套校验 如何接收校验结果? BindingResult 接收 全局异常捕捉 spring-boot-starter-validation做了什么? 如何自定义校验? 自定义校验注解 自定义校验器 演示 总结
|
移动开发 前端开发 小程序
不愧是前端老油条,分分钟看出我方案的bug
国庆前刚开发完一个小需求,常规性的做了一次code review,不过这次review有所不同,我们组前端老油条竟然参会了,平时发会邀都不来的。 不过不愧是老油条,竟然分分中发现了问题,老油条的地位又在我们小前端的心里巩固了一下。 和往常一样,review前先过一遍技术方案,一让大家快速的了解需求,二来分析下技术方案是否存在问题,是否合理,一般情况下,技术方案没问题,后面的代码review感觉就没啥必要了,因为很少有人听。
139 0
不愧是前端老油条,分分钟看出我方案的bug
|
前端开发 JavaScript 测试技术
为了降低维护成本(早点下班),我在组件开发中所做的那些优化(偷懒)
组件开发中为了稳定性、健壮性,经常需要为组件编写测试用例,然后还要为了开发者方便使用编写文档,都是非常耗时间的差事。作为一个独立维护组件库的程序员,为了能够降低组件维护的成本(早点下班),我总结了一下自己过去几年为了让组件开发更加高效所做的那些事情(偷的那些懒)。