为什么c语言加法错误,分数的加减法——C语言初学者代码中的常见错误与瑕疵(12)...

重构

题目的修正

我抛弃了原题中“其中a, b, c, d是一个0-9的整数”这样的前提条件,因为这种限制毫无必要。只假设a, b, c, d是十进制整数形式的字符序列。

我也不清楚这种题目应该如何结束输入。下面的代码假设在没有正确输入完整的运算式时结束。

数据结构

typedef

struct

{

int numer ; //分子

int denom ; //分母

}

frac_t ;//分数类型

数据

一共需要三个变量,两个记录分数,一个记录运算符。

#include

int main( void )

{

frac_t frc1 , frc2 ;//两个操作数

char op ; //运算符

return ;

}

总体结构

#define FAIL 0

int main( void )

{

frac_t frc1 , frc2 ;//两个分数

char op ; //运算符

while ( input_exp( &frc1 , &op , &frc2 ) != FAIL )//输入算式

{

//计算,输出

}

return ;

}

input_exp()的实现

int input_exp( frac_t * , char * , frac_t * );

int input_frac( frac_t * );

int input_exp( frac_t * p_f1 , char * p_o , frac_t * p_f2 )

{

if ( input_frac( p_f1 ) != )

return FAIL ;

if ( scanf(" %c" , p_o ) != )//if ( scanf(" %c " , p_o ) != )

return FAIL ;

switch ( * p_o )

{

default : return FAIL ;//不是加、减法

case '+':

case '-':

;

}

if ( input_frac( p_f2 ) != )

return FAIL ;

return !FAIL ;

}

int input_frac( frac_t * p_f )

{

return scanf("%d / %d" , &p_f->numer , &p_f->denom );

}

//计算,输出部分

首先排除无意义的输入

if ( frc1.denom == || frc2.denom == ) //无意义的输入

{

puts( "分数无意义" );

continue ;

}

把减法变为加法

switch ( op )

{

case '-':frc2.numer = - frc2.numer ;//把减法化为加法

case '+':add_to( &frc1 , &frc2 ); //计算结果放在frc1中

break ;

}

最后输出结果

output( frc1 );

putchar( '\n' );

完整的代码:

/*

分数的加减法

编写一个C程序,实现两个分数的加减法

输入:输入包含多行数据

每行数据的格式是 a/boc/d 。

其中a, b, c, d为十进制整数,o是运算符"+"或者"-"。

输出:对于输入数据的每一行输出两个分数的运算结果。

注意结果应符合书写习惯,没有多余的符号、分子、分母,并且化简至最简分数

样例输入:

1/8+3/8

1/4-1/2

1/3-1/3

输出:

1/2

-1/4

0

作者:薛非

出处:http://www.cnblogs.com/pmer/ “C语言初学者代码中的常见错误与瑕疵”系列博文

*/

#include

#include

typedef

struct

{

int numer ; //分子

int denom ; //分母

}

frac_t ;//分数类型

#define FAIL 0

int input_exp( frac_t * , char * , frac_t * );

int input_frac( frac_t * );

void add_to( frac_t * , frac_t const * );

int find_lcm( int , int );

int find_gcd( int , int );

void reduce( frac_t * );

void output( frac_t );

int main( void )

{

frac_t frc1 , frc2 ;//两个分数

char op ; //运算符

while ( input_exp( &frc1 , &op , &frc2 ) != FAIL )//输入算式

{

//计算,输出

if ( frc1.denom == || frc2.denom == ) //无意义的输入

{

puts( "分数无意义" );

continue ;

}

switch ( op )

{

case '-':frc2.numer = - frc2.numer ;//把减法化为加法

case '+':add_to( &frc1 , &frc2 ); //计算结果放在frc1中

break ;

}

output( frc1 );

putchar( '\n' );

}

return ;

}

void output( frac_t fr )

{

if ( fr.numer < )

{

putchar( '-' );

fr.numer = - fr.numer ;

}

if ( fr.denom == )

{

printf( "%d" , fr.numer );

return ;

}

printf( "%d/%d" , fr.numer , fr.denom );

}

void reduce( frac_t * p_f )

{

int gcd = find_gcd( abs( p_f->numer ) , abs( p_f->denom ) ) ;

p_f->denom /= gcd ;

p_f->numer /= gcd ;

}

int find_gcd( int m , int n )

{

int t ;

return (t = m % n) == ? n : find_gcd( n , t );

}

int find_lcm( int m , int n )

{

return m / find_gcd( m , n ) * n ;

}

void add_to( frac_t * p_f1 , frac_t const * p_f2 )

{

int lcm = find_lcm( abs( p_f1->denom ) , abs( p_f2->denom ) );

p_f1->numer = lcm / p_f1->denom * p_f1->numer

+ lcm / p_f2->denom * p_f2->numer ;

p_f1->denom = lcm ; //分母总是正的

reduce( p_f1 ); //约分

}

int input_frac( frac_t * p_f )

{

return scanf( "%d / %d" , &p_f->numer , &p_f->denom );

}

int input_exp( frac_t * p_f1 , char * p_o , frac_t * p_f2 )

{

if ( input_frac( p_f1 ) != )

return FAIL ;

if ( scanf(" %c" , p_o ) != )//if ( scanf( " %c " , p_o ) != )

return FAIL ;

switch ( * p_o )

{

default : return FAIL ;//不是加、减法

case '+':

case '-':

;

}

if ( input_frac( p_f2 ) != )

return FAIL ;

return !FAIL ;

}

一个超复杂的间接递归——C语言初学者代码中的常见错误与瑕疵&lpar;6&rpar;

问题: 问题出处见 C语言初学者代码中的常见错误与瑕疵(5) . 在该文的最后,曾提到完成的代码还有进一步改进的余地.本文完成了这个改进.所以本文讨论的并不是初学者代码中的常见错误与瑕疵,而是对我自己 ...

C语言初学者代码中的常见错误与瑕疵&lpar;5&rpar;

问题: 素数 在世博园某信息通信馆中,游客可利用手机等终端参与互动小游戏,与虚拟人物Kr. Kong 进行猜数比赛. 当屏幕出现一个整数X时,若你能比Kr. Kong更快的发出最接近它的素数答案,你将 ...

C语言初学者代码中的常见错误与瑕疵&lpar;14&rpar;

见:C语言初学者代码中的常见错误与瑕疵(14) 相关链接:http://www.anycodex.com/blog/?p=87

C语言初学者代码中的常见错误与瑕疵&lpar;9&rpar;

题目 字母的个数 现在给你一个由小写字母组成字符串,要你找出字符串中出现次数最多的字母,如果出现次数最多字母有多个那么输出最小的那个. 输入:第一行输入一个正整数T(0

要心中有&OpenCurlyDoubleQuote;数”——C语言初学者代码中的常见错误与瑕疵&lpar;8&rpar;

在 C语言初学者代码中的常见错误与瑕疵(7) 中,我给出的重构代码中存在BUG.这个BUG是在飞鸟_Asuka网友指出“是不是时间复杂度比较大”,并说他“第一眼看到我就想把它当成一个数学问题来做”之后 ...

C语言初学者代码中的常见错误与瑕疵&lpar;7&rpar;

问题: 矩形的个数 在一个3*2的矩形中,可以找到6个1*1的矩形,4个2*1的矩形3个1*2的矩形,2个2*2的矩形,2个3*1的矩形和1个3*2的矩形,总共18个矩形.给出A,B,计算可以从中找到 ...

C语言初学者代码中的常见错误与瑕疵&lpar;1&rpar;

曾在豆瓣上看到过一个小朋友贴出他自己的代码(http://www.douban.com/group/topic/40293109/),当时随口指点了几句.难得这位小朋友虚心修正.从善如流,不断地改,又 ...

随机推荐

【转】Bootloader之uBoot简介(转)

原文网址:http://blog.csdn.net/sadamoo/article/details/8139946 来自http://blog.ednchina.com/hhuwxf/1915416/ ...

redis预切片技术,实现

平时,我们将创建多个redis实例,以缓解单redis压力范例.但,作为高速缓存的数量增加.对redis对于扩展是一种非 - 不要无所谓.对redis有几种方法用于扩张可能.让我们添加每个redis最 ...

Go如何使用实现继承的组合

Go它提供了一个非常值得称道的并发支持,但Go它不支持完全面向对象的.这并不意味着Go不支持面向对象,,和Go的OO系统做的很轻巧,学习降至最低成本.向对象让Go失去了一些OO的方便特性,可是更高的效 ...

服务器上定时自动执行php

两种方式: 一.Linux 服务器Linux原生支持crontab,所以可以利用这一功能做定时任务 步骤: 1.编辑crontab文件:Linux:crontab -e 2.输入代码:0 0 * * ...

Navicat Premium和Navicat for MySQL哪个好用&quest;

之前在Navicat官网下载了Navicat Premium和Navicat for MySQL使用.Navicat官网产品下载地址:https://www.navicat.com.cn/produc ...

java中的安全模型&lpar;沙箱机制&rpar;

java中的安全模型(沙箱机制) java安全沙箱(一)之ClassLoader双亲委派机制 java安全沙箱(二)之.class文件检验器 java安全沙箱(三)之内置于Java虚拟机(及语言)的安 ...

VS中子对话框的关闭回调函数

新建了QDialog的子类时,如果需要回调它的关闭函数 1.加入头文件#include 2.重写函数 protected: void closeEvent(QC ...

momenta

编程:1.dp的题 2.白纸写代码,给一串数和一个目标值,使用四则运算和括号使得这串数最后计算结果为目标值,打印出所有的方案,要求是这些数每个最多被使用一次,可以不被用到. 3.考了一个查找数组里,未 ...

Java基础—输入输出流

流的概念 在Java中,流是从源到目的地的字节的有序序列.Java中有两种基本的流——输入流(InputStream)和输出流(OutputStream). 根据流相对于程序的另一个端点的不同,分为节 ...

Nginx 配置 HTTPS自签名证书

工具: OpenSSL ssl的开源实现,几乎实现了市面上所有的加密 libcrypto: 通用加密库, 任何软件要实现加密功能 链接调用这个库 libssl: TLS/SSL 加密库 openssl ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值