代码非常烂的四则运算计算器(windows SDK 版)
本帖最后由 zaas 于 2011-2-23 15:29 编辑有兴趣的逆一下,看看到底有多烂。。。
修了下bug,
加了点东东,写成WIndows SDK版的,欢迎测试:
前两天写了个四则运算计算器,设计思路简单说的话,无非相当于设置一个堆栈,根据加减乘除括号的优先级,每次取出算式的一部分,在栈里计算结果,然后转换为字符串再填回去。用到的都是已经学过的知识。
这种方法有一定缺陷,字符串返回的时候sprintf(),返回的精度达不到double了,(当然如果增加对指数的判断会好很多:D ),算式越长越复杂,误差会越大,但精度控制在小数点后两位应该没有问题。
不过代码很烂。仅仅使用malloc设置了堆,代码写的乱七八糟。昨晚思考了一下,觉得改用struct 会比较清晰明了,因此先把框架搭出来了,发出来算作一种思路。
等将来学的更深入一点之后,可能会有更好的思路和方法?
立此存照。//main.cpp
#include "main.h"
void main()
{
CalStr cal;
InitCal( & cal); //初始化字符串
if(!Calculator( & cal)) //计算,不成功则退出
{
return;
};
Output( & cal); //输出
}//main.h
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct CalStr
{
char original; //输入的字符串
char replace; //待替换的括号内字符串
char childstr; //括号内字符串
char childreplace; //待替换的单一算式
interror; //出错的旗标
}CalStr;
void InitCal(CalStr *cal); //初始化
int Calculator(CalStr *cal); //计算
void Output(CalStr *cal); //输出
void Input(CalStr *cal); //输入
void CheckInput(CalStr *cal); //输入检查
int GetChildStr(CalStr *cal); //取得括号内子串
int CalChildStr(CalStr *cal); //计算子串
void ReplaceStr(CalStr *cal,double result);//用计算结果替换原串中的子串
int GetSymbol(CalStr *cal); //获取运算符
double GetFrontStr(CalStr *cal,int flag); //运算符前边的数字串
double GetBehindStr(CalStr *cal,int flag); //运算符后边的数字串
double CalDouble(double x,double y); //计算结果
int CheckLength (char * Str); //长度检测,防溢出//run.cpp
#include "main.h"
void InitCal(CalStr *cal)
{
do
{
Input(cal);
CheckInput(cal);
} while (cal->error); //输入有误,重新输入
}
int Calculator(CalStr *cal)
{
int flag;
double result;
do
{
flag=GetChildStr(cal); //取得括号内子串
result=CalChildStr(cal);
if (cal->error) //计算失败退出
{
return 0;
}
ReplaceStr(cal,result); //替换原串
} while (flag); //还有括号,继续
return 1;
}
void Output(CalStr *cal)
{
;
}
///////////////////////////////////
void Input(CalStr *cal)
{
}
void CheckInput(CalStr *cal)
{
cal->error=0;
}
///////////////////////////////////
intGetChildStr(CalStr *cal)
{
return 0;
}
int CalChildStr(CalStr *cal)
{
int flag;
double x,y,result;
do
{
flag=GetSymbol(cal);
x=GetFrontStr(cal,flag);
y=GetBehindStr(cal,flag);
if (cal->error) //长度溢出,退出
{
return 0;
}
result=CalDouble(x,y);
if (cal->error) //除零错误,退出
{
return 0;
}
ReplaceStr(cal,result); //替换单一算式
} while(!flag) //所有单一算式计算完成结束
}
void ReplaceStr(CalStr *cal,double result)
{
; //此处计算结果转回字符串并替换需替换的部分
}
///////////////////////////////////
int GetSymbol(CalStr *cal)
{
return 0; //加减乘除的优先级判定
}
double GetFrontStr(CalStr *cal,int flag)
{
return 0;
}
double GetBehindStr(CalStr *cal,int flag)
{
return 0;
}
double CalDouble(double x,double y)
{
return 0;
}
///////////////////////////////////
int CheckLength (char * Str)
{
return 0;
}
{:1_934:}不是很了解 干什么用的, 沙发下~ 如果LZ给出源代码,再加上一定的讲解,那不是更好:loveliness:。
我还可以给LZ加精华~ 我刚才又想了下。感觉不是很妥当:LZ没有给出源代码……
一是感觉LZ的帖子不值我给的评分,又摸不透LZ发这个帖子的用意在哪里。
我觉得LZ的帖子发在原创板块或者按照LZ所说,为了让大家逆下,那可以放在逆向板块……
希望LZ在一个星期之内能够补上源码,我会保留此评分,如果能再附上一定的讲解,我会给LZ加精华。
倘若LZ在一个星期内不由对帖子做任何改动,我会将帖子移动到相应板块中,并对评分做一定的减少。
希望LZ理解。{:1_903:} 本帖最后由 zaas 于 2011-2-23 15:27 编辑
bester 发表于 2011-2-23 08:49 static/image/common/back.gif
我刚才又想了下。感觉不是很妥当:LZ没有给出源代码……
一是感觉LZ的帖子不值我给的评分,又摸不透LZ发 ...
hoho。。。。发个框架吧,推翻重写的框架。新代码还没填上。
思路不错. 回头好好看看
页:
[1]