分数的加减法——C语言初学者代码中的常见错误与瑕疵(12)
题目的修正
我抛弃了原题中“其中a, b, c, d是一个0-9的整数”这样的前提条件,因为这种限制毫无必要。只假设a, b, c, d是十进制整数形式的字符序列。
我也不清楚这种题目应该如何结束输入。下面的代码假设在没有正确输入完整的运算式时结束。
数据结构
typedef
struct
{
int numer ; //分子
int denom ; //分母
}
frac_t ;//分数类型
数据
一共需要三个变量,两个记录分数,一个记录运算符。
#include <stdio.h>
int main( void )
{
frac_t frc1 , frc2 ;//两个操作数
char op ; //运算符
return 0;
}
复制代码
总体结构
#define FAIL 0
int main( void )
{
frac_t frc1 , frc2 ;//两个分数
char op ; //运算符
while ( input_exp( &frc1 , &op , &frc2 ) != FAIL )//输入算式
{
//计算,输出
}
return 0;
}
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 ) != 2 )
return FAIL ;
if ( scanf(" %c " , p_o ) != 1 )
return FAIL ;
switch ( * p_o )
{
default : return FAIL ;//不是加、减法
case '+':
case '-':
;
}
if ( input_frac( p_f2 ) != 2 )
return FAIL ;
return !FAIL ;
}
int input_frac( frac_t * p_f )
{
return scanf("%d / %d" , &p_f->numer , &p_f->denom );
}
//计算,输出部分
首先排除无意义的输入
if ( frc1.denom == 0 || frc2.denom == 0 ) //无意义的输入
{
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
*/
#include <stdio.h>
#include <stdlib.h>
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 == 0 || frc2.denom == 0 ) //无意义的输入
{
puts( "分数无意义" );
continue ;
}
switch ( op )
{
case '-':frc2.numer = - frc2.numer ;//把减法化为加法
case '+':add_to( &frc1 , &frc2 ); //计算结果放在frc1中
break ;
}
output( frc1 );
putchar( '/n' );
}
return 0;
}
void output( frac_t fr )
{
if ( fr.numer < 0 )
{
putchar( '-' );
fr.numer = - fr.numer ;
}
if ( fr.denom == 1 )
{
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) == 0 ? 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 ) != 2 )
return FAIL ;
if ( scanf( " %c " , p_o ) != 1 )
return FAIL ;
switch ( * p_o )
{
default : return FAIL ;//不是加、减法
case '+':
case '-':
;
}
if ( input_frac( p_f2 ) != 2 )
return FAIL ;
return !FAIL ;
}
>更多相关文章
- 09-29如何通过wrap malloc定位C/C++程序的内存泄漏
- 02-25打车软件大战升级,补贴还能维持多久?
- 12-23BMP文件右旋90度[c语言]
- 12-23寻找直方图中面积最大的矩形(C语言版)
- 12-23[ndk,2]ndk开发案例和错误处理
- 12-23[ndk,1]ndk开发,C语言入门讲解
- 12-23C语言连续存储实现队列机制
- 12-23Objective-c 数据类型
首页推荐
佛山市东联科技有限公司一直秉承“一切以用户价值为依归
- 01-11全球最受赞誉公司揭晓:苹果连续九年第一
- 12-09罗伯特·莫里斯:让黑客真正变黑
- 12-09谁闯入了中国网络?揭秘美国绝密黑客小组TA
- 12-09警示:iOS6 惊现“闪退”BUG
- 12-05亚马逊推出新一代基础模型 任意模态生成大模
- 12-05OpenAI拓展欧洲业务 将在苏黎世设立办公室
- 12-05微软质疑美国联邦贸易委员会泄露信息 督促其
- 12-05联交所取消宝宝树上市地位 宝宝树:不会对公
- 12-04企业微信致歉:文档打开异常已完成修复
相关文章
24小时热门资讯
24小时回复排行
热门推荐
最新资讯
操作系统
黑客防御