其实这次写这个程序,原本是帮一个学妹完成课程设计,不过写着写着就想要重新拿走这个项目了
现在在只是先记录一下,尔后还要在linux上重新测试
D:\code\xin\eclipse\cal>dir *.h *.c
驱动器 D 中的卷是 软件
卷的序列号是 0006-17B7
D:\code\xin\eclipse\cal 的目录
2015/07/25 01:32 671 bolan.h
2015/07/25 01:30 1,851 node.h
2015/07/24 23:33 1,587 stack.h
2015/08/31 21:53 1,729 tools.h
D:\code\xin\eclipse\cal 的目录
2015/08/31 21:43 4,290 bolan.c
2015/08/31 22:07 17,088 main.c
2015/08/31 21:42 4,573 node.c
2015/07/27 20:09 2,952 stack.c
2015/08/31 21:44 4,073 tools.c
9 个文件 38,814 字节
0 个目录 35,335,245,824 可用字节
D:\code\xin\eclipse\cal>
/** @file tools.h * * @param expPtr * @return */ #ifndef TOOLS_H_ #define TOOLS_H_ /** @brief 删除表达式中的空格及不可见字符 * * @param expPtr 原表达式字符串 * * @retval 0 执行成功 * @retval 1 执行失败 */ int tools_delete_spaces( char * expPtr ); /** @brief 表达式的正负号前加0 * * @param expPtr 表达式 * * @retval 0 执行成功 * @retval 1 执行失败 */ int tools_add_zero( char * expPtr ); /** @brief 判断当前字符是否为+ - * / 这四个运算符之一 * * @param ch 要判断的符号 * * @retval 0 是 * @retval 1 否 */ int tools_is_char_operator( char ch ); /** @brief 判断字符 ch 是否为括号 * * @param ch 要判断的字符 * * @retval 0 是 * @retval 1 否 */ int toolls_is_char_paren( char ch ); /** @brief 字符串末尾添加 # * * @param expPtr 字符串 * * @retval 0 执行成功 * @retval 1 执行失败 */ int tools_add_sharp( char * expPtr ); /** @brief 比较运算符优先级 * * @param ch1 当前运算符 * @param ch2 与之比较的运算符,也就是临时栈栈顶元素的值 * * @retval 1 当前运算符大于与之比较的运算符 * @retval 0 当前运算符等于与之比较的运算符 * @retval -1 当前运算符小于于与之比较的运算符 */ int tools_operator_compare(char ch1, char ch2); /** @brief 在字符串str中查找字符ch第一次出现的位置 * * @param str 要搜索字符串 * @param ch 要查找的字符 * @return 查找到的位置 */ int tools_str_ch_index_first( char * str, char ch ); /** @brief 处理表达式中的0 * 如果小数点后面全为0,则将小数点及之后的字符去除 * 如果小数点之后有数字,则将最后一个非0字符后面的0去除 * @param exp 要处理的字符串 * @retval 0 操作成功 * @retval 1 操作失败 */ int tools_exp_handle_zero(char * exp); #endif /* TOOLS_H_ */
#include<string.h>
#include<ctype.h>
#include "tools.h"
/** @brief 删除表达式中的空格及不可见字符
*
* @param expPtr 原表达式字符串
*
* @retval 0 执行成功
* @retval 1 执行失败
*/
int tools_delete_spaces(char * expPtr) {
int res = 1;
char tmp[100] = { ‘\0‘ };
strcpy(tmp, expPtr);
int i = 0;
int j = 0;
int len = strlen(tmp);
for (i = 0; i < len; i++) {
char ch = tmp[i];
//忽略不可见字符
if (!isspace(ch)) {
expPtr[j] = ch;
j++;
}
}
expPtr[j] = ‘\0‘;
res = 0;
return res;
}
/** @brief 表达式的正负号前加0
*
* @param expPtr 表达式
*
* @retval 0 执行成功
* @retval 1 执行失败
*/
int tools_add_zero(char * expPtr) {
int res = 1;
char tmp[100] = { ‘\0‘ };
strcpy(tmp, expPtr);
int len = strlen(tmp);
int i = 0;
int j = 0;
//如果第一个符号是正负号,则在其前加0
if (‘+‘ == tmp[0] || ‘-‘ == tmp[0]) {
expPtr[0] = ‘0‘;
expPtr[1] = tmp[0];
j = 2;
}else{
//如果不是,则直接复制
expPtr[j] = tmp[0];
j++;
}
for (i = 1; i < len; i++) {
char ch = tmp[i];
expPtr[j] = tmp[i];
j++;
//如果当前字符是 ( 且其后面是 + 或 - ,则在 ( 之后加 0
if (‘(‘ == ch) {
if (‘+‘ == tmp[i + 1] || ‘-‘ == tmp[i + 1]) {
expPtr[j] = ‘0‘;
j++;
}
}
}
expPtr[j] = ‘\0‘;
return res;
}
/** @brief 判断当前字符是否为+ - * / 这四个运算符之一
*
* @param ch 要判断的符号
*
* @retval 0 是
* @retval 1 否
*/
int tools_is_char_operator(char ch) {
int res = 1;
switch (ch) {
case ‘+‘:
case ‘-‘:
case ‘*‘:
case ‘/‘: {
res = 0;
break;
}
}
return res;
}
/** @brief 判断字符 ch 是否为括号
*
* @param ch 要判断的字符
*
* @retval 0 是
* @retval 1 否
*/
int toolls_is_char_paren(char ch) {
int res = 1;
switch (ch) {
case ‘(‘:
case ‘)‘: {
res = 0;
break;
}
}
return res;
}
/** @brief 字符串末尾添加 #
*
* @param expPtr 字符串
*
* @retval 0 执行成功
* @retval 1 执行失败
*/
int tools_add_sharp(char * expPtr) {
int res = 1;
int len = strlen(expPtr);
expPtr[len] = ‘#‘;
expPtr[len + 1] = ‘\0‘;
res = 0;
return res;
}
/** @brief 比较运算符优先级
*
* @param ch1 当前运算符
* @param ch2 与之比较的运算符,也就是临时栈栈顶元素的值
*
* @retval 1 当前运算符大于与之比较的运算符
* @retval 0 当前运算符等于与之比较的运算符
* @retval -1 当前运算符小于于与之比较的运算符
*/
int tools_operator_compare(char ch1, char ch2) {
int res = 0;
if (‘+‘ == ch1 || ‘-‘ == ch1) {
if (‘#‘ == ch2) {
res = 1;
} else if (‘+‘ == ch2 || ‘-‘ == ch2) {
res = 0;
} else if (‘*‘ == ch2 || ‘/‘ == ch2) {
res = -1;
} else if (‘(‘ == ch2) {
res = 1;
}
} else if (‘*‘ == ch1 || ‘/‘ == ch1) {
if (‘#‘ == ch2) {
res = 1;
} else if (‘+‘ == ch2 || ‘-‘ == ch2) {
res = 1;
} else if (‘*‘ == ch2 || ‘/‘ == ch2) {
res = 0;
} else if (‘(‘ == ch2) {
res = 1;
}
}
return res;
}
/** @brief 在字符串str中查找字符ch第一次出现的位置
*
* @param str 要搜索字符串
* @param ch 要查找的字符
* @return 查找到的位置
*/
int tools_str_ch_index_first( char * str, char ch ){
int i = 0;
int index;
int str_len = strlen(str);
for( i = 0; i < str_len; i++ ){
if( ch == str[i]){
break;
}
}
index = i--;
return index;
}
/** @brief 处理表达式中的0
* 如果小数点后面全为0,则将小数点及之后的字符去除
* 如果小数点之后有数字,则将最后一个非0字符后面的0去除
* @param exp 要处理的字符串
* @retval 0 操作成功
* @retval 1 操作失败
*/
int tools_exp_handle_zero(char * exp){
int res = 0;
//小数点的位置
int dot_index = tools_str_ch_index_first(exp,‘.‘);
int i = 0;
//结果字符串的长度
int exp_len = strlen(exp);
//小数点之后最后一个数字出现的位置
int last_num = 0;
for( i = exp_len - 1; i > dot_index ; i-- ){
if( ‘0‘ != exp[i]){
last_num = i;
break;
}
}
if( 0 == last_num ){
exp[dot_index] = ‘\0‘;
}else{
exp[i+1] = ‘\0‘;
}
res = 1;
return res;
}
/** @file node.h
* 保存由字符串转换后的数据
*
*/
#ifndef NODE_H_
#define NODE_H_
/** @struct __node
* 栈中的每个元素的类型
*
* flag 的值所代表的意义
* 0
* 数字 保存在num中
* + - / *
* 运算符 保存在operator中
* ( )
* 括号 保存在paren中
* #
* 结束符 保存在sharpt中
*/
struct __node{
/** @brief 保存数字 */
double num;
/** @brief 保存运算符 */
char operator;
/** @brief 保存括号 */
char paren;
/** @brief 保存 # */
char sharp;
/** @brief 标志,表达本 node所保存的数据的类型 */
char flag;
};
typedef struct __node _node;
typedef struct __node * nodePtr;
/** @brief 创建数字node
*
* @param num 数字
* @return 创建的node
*/
nodePtr node_create_num( double num );
/** @brief 创建运算符node
*
* @param operator 运算符
* @return 创建的node
*/
nodePtr node_create_operator( char operator );
/** @brief 创建括号node
*
* @param paren 括号
* @return 创建的node
*/
nodePtr node_create_paren( char paren );
/** @brief 创建结符
*
* @param sharp #
*
* @return 创建的node
*/
nodePtr node_create_sharp( char sharp );
/** @brief 根据指定的符号创建node
*
* @param ch 指定的node
*
* @retval 0 创建成功
* @retval 1 创建失败
*/
nodePtr node_create_from_char( char ch );
/** @brief 打印此node的内容
* 若是数字开型,则只打印数字,其它类似
*
* @param node 要打印的node
*
* @retval 0 执行成功
* @retval 1 执行失败
*/
int node_print( nodePtr node );
/** @brief 计算一个表达式应当用多少个node保存
*
* @param expPtr 表达式
*
* @return 就使用的node数
*/
int node_exp_num( char * expPtr );
/** @brief 把表达式字符串转换为node数组
*
* @param expPtr 表达式字符串
*
* @return 转换后的node数组
*/
nodePtr node_create_array( char * expPtr );
#endif /* NODE_H_ */
#include"node.h"
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include "tools.h"
/** @brief 创建数字node
*
* @param num 数字
* @return 创建的node
*/
nodePtr node_create_num(double num) {
nodePtr node = (nodePtr) malloc(sizeof(_node));
if ( NULL == node) {
puts("创建数字node失败...NULL == node ");
exit(0);
}
node->num = num;
node->flag = ‘0‘;
node->operator = ‘\0‘;
node->paren = ‘\0‘;
node->sharp = ‘\0‘;
return node;
}
/** @brief 创建运算符node
*
* @param operator 运算符
* @return 创建的node
*/
nodePtr node_create_operator(char operator) {
nodePtr node = (nodePtr) malloc(sizeof(_node));
if ( NULL == node) {
puts("创建数字node失败...NULL == node ");
exit(0);
}
node->operator = operator;
node->flag = operator;
node->num = 0;
node->paren = ‘\0‘;
node->sharp = ‘\0‘;
return node;
}
/** @brief 创建括号node
*
* @param paren 括号
* @return 创建的node
*/
nodePtr node_create_paren(char paren) {
nodePtr node = (nodePtr) malloc(sizeof(_node));
if ( NULL == node) {
puts("创建数字node失败...NULL == node ");
exit(0);
}
node->paren = paren;
node->flag = paren;
node->operator = ‘\0‘;
node->num = 0;
node->sharp = ‘\0‘;
return node;
}
/** @brief 创建结符
*
* @param sharp #
*
* @return 创建的node
*/
nodePtr node_create_sharp(char sharp) {
nodePtr node = (nodePtr) malloc(sizeof(_node));
if ( NULL == node) {
puts("创建数字node失败...NULL == node ");
exit(0);
}
node->sharp = sharp;
node->flag = sharp;
node->operator = ‘\0‘;
node->num = 0;
node->paren = ‘\0‘;
return node;
}
/** @brief 根据指定的符号创建node
*
* @param ch 指定的node
*
* @retval 0 创建成功
* @retval 1 创建失败
*/
nodePtr node_create_from_char(char ch) {
nodePtr node = NULL;
if (!tools_is_char_operator(ch)) {
node = node_create_operator(ch);
} else if (!toolls_is_char_paren(ch)) {
node = node_create_paren(ch);
} else if (‘#‘ == ch) {
node = node_create_sharp(ch);
}
return node;
}
/** @brief 打印此node的内容
* 若是数字开型,则只打印数字,其它类似
*
* @param node 要打印的node
*
* @retval 0 执行成功
* @retval 1 执行失败
*/
int node_print(nodePtr node) {
int res = 1;
//运算符
if (!tools_is_char_operator(node->flag)) {
printf("%c\n", node->operator);
} else if (!toolls_is_char_paren(node->flag)) {
printf("%c\n", node->paren);
} else if (‘0‘ == node->flag) {
printf("%.2lf\n", node->num);
} else if (‘#‘ == node->flag) {
printf("%c\n", node->sharp);
}
res = 0;
return res;
}
/** @brief 计算一个表达式应当用多少个node保存
*
* @param expPtr 表达式
*
* @return 就使用的node数
*/
int node_exp_num(char * expPtr) {
//需要的node数
int count = 0;
int len = strlen(expPtr);
int i = 0;
// int j = 0;
for (i = 0; i < len; i++) {
char ch = expPtr[i];
if (‘#‘ == ch) {
count++;
break;
}
//如果是运算符,count直接加1
if (!tools_is_char_operator(ch) || !toolls_is_char_paren(ch)) {
count++;
} else {
//如果是数字,则遍历至当前数字的最后一个字符,count加1
while ((‘0‘ <= ch && ch <= ‘9‘) || ‘.‘ == ch ) {
i++;
ch = expPtr[i];
}
count++;
i--;
}
}
return count;
}
/** @brief 把表达式字符串转换为node数组
*
* @param expPtr 表达式字符串
*
* @return 转换后的node数组
*/
nodePtr node_create_array(char * expPtr) {
//得到转换后的数组的长度
int array_len = node_exp_num(expPtr);
int len = strlen(expPtr);
int i = 0;
int j = 0;
int k = 0;
nodePtr tmp = NULL;
//创建数组
nodePtr node_array = (nodePtr) malloc(sizeof(_node) * array_len);
if ( NULL == node_array) {
puts("创建node数组失败...NULL == node_array");
exit(0);
}
for (i = 0; i < len; i++) {
char ch = expPtr[i];
//运算符
if (!tools_is_char_operator(ch)) {
tmp = node_create_operator(ch);
node_array[j] = *tmp;
j++;
} else if (!toolls_is_char_paren(ch)) {
//括号
tmp = node_create_paren(ch);
node_array[j] = *tmp;
j++;
} else if (‘#‘ == ch) {
//结束符
tmp = node_create_sharp(ch);
node_array[j] = *tmp;
j++;
} else {
//数字
char numArr[20] = { ‘\0‘ };
while ((‘0‘ <= ch && ch <= ‘9‘) || ‘.‘ == ch ) {
numArr[k++] = ch;
i++;
ch = expPtr[i];
}
double num = atof(numArr);
tmp = node_create_num(num);
node_array[j] = *tmp;
j++;
i--;
k = 0;
}
}
return node_array;
}
/** @file stack.h
* 栈的操作的声明
*
*/
#include"node.h"
#ifndef STACK_H_
#define STACK_H_
/** @brief 栈结构体
*
*/
struct __stack{
/** @brief node 数组头指针 */
nodePtr node_arr;
/** @brief 栈有效长度 */
int size;
/** @brief 栈实际长度 */
int length;
};
typedef struct __stack _stack;
typedef struct __stack * stackPtr;
/** @brief 创建栈
*
* @param length 栈的实际长度
* 如果length 指定为0,则默认的length值为40
*
* @return 创建好的栈
*
* @retval NULL 创建失败
*/
stackPtr stack_create( int length );
/** @brief 入栈
*
* @param stack 栈
* @param node 要入栈的node
*
* @retval 0 入栈成功
* @retval 1 入栈失败
*/
int stack_push( stackPtr stack, nodePtr node);
/** @brief 判断栈是否已满
*
* @param stack 栈
*
* @retval 0 已满
* @retval 1 未满
*/
int stack_is_full( stackPtr stack );
/** @brief 栈扩容
*
* @param stack 栈
*
* @retval 0 扩容成功
* @retval 1 扩容失败
*/
int stack_node_array_extends( stackPtr stack );
/** @brief 出栈
*
* @param stack 栈
* @param node 保存出栈的元素
*
* @retval 0 出栈成功
* @retval 1 出栈失败
*/
int stack_pop( stackPtr stack, nodePtr node);
/** @brief 取出栈顶元素的值
*
* @param stack 栈
* @param node 保存栈顶元素的值
*
* @retval 0 取出成功
* @retval 1 取出失败
*/
int stack_top( stackPtr stack, nodePtr node );
/** @brief 输出栈
*
* @param stack 栈
*
* @retval 0 输出成功
* @retval 1 输出失败
*/
int stack_print( stackPtr stack );
#endif /* STACK_H_ */
#include"stack.h"
#include"node.h"
#include<stdlib.h>
#include<stdio.h>
/** @brief 创建栈
*
* @param length 栈的实际长度
* 如果length 指定为0,则默认的length值为40
*
* @return 创建好的栈
*
* @retval NULL 创建失败
*/
stackPtr stack_create(int length) {
stackPtr stack = (stackPtr) malloc(sizeof(_stack));
if ( NULL == stack) {
puts("创建栈失败...NULL == stack ");
exit(0);
}
if (0 == length) {
stack->length = 40;
} else {
stack->length = length;
}
stack->node_arr = (nodePtr) malloc(sizeof(_node) * stack->length);
if ( NULL == stack->node_arr) {
puts("创建栈失败...NULL == stack->node_arr ");
exit(0);
}
stack->size = 0;
// stack->length = 40;
return stack;
}
/** @brief 入栈
*
* @param stack 栈
* @param node 要入栈的node
*
* @retval 0 入栈成功
* @retval 1 入栈失败
*/
int stack_push(stackPtr stack, nodePtr node) {
int res = 1;
if (!stack_is_full(stack)) {
stack_node_array_extends(stack);
}
//数据后移
int i = stack->size - 1;
for (i = stack->size - 1; i >= 0; i--) {
stack->node_arr[i + 1] = stack->node_arr[i];
}
//数据入栈
stack->node_arr[0] = *node;
//栈有效长度加1
stack->size++;
res = 0;
return res;
}
/** @brief 判断栈是否已满
*
* @param stack 栈
*
* @retval 0 已满
* @retval 1 未满
*/
int stack_is_full(stackPtr stack) {
int res = 0;
if (stack->size < stack->length) {
res = 1;
}
return res;
}
/** @brief 栈扩容
*
* @param stack 栈
*
* @retval 0 扩容成功
* @retval 1 扩容失败
*/
int stack_node_array_extends(stackPtr stack) {
int res = 1;
if ( NULL != stack) {
stack->length = stack->length * 1.75;
stack->node_arr = (nodePtr) realloc(stack->node_arr, stack->length);
res = 0;
}
return res;
}
/** @brief 出栈
*
* @param stack 栈
* @param node 保存出栈的元素
*
* @retval 0 出栈成功
* @retval 1 出栈失败
*/
int stack_pop(stackPtr stack, nodePtr node) {
int res = 1;
if ( NULL != stack && stack->size > 0) {
//保存栈顶元素
*node = stack->node_arr[0];
int i = 0;
for (i = 0; i <= stack->size - 2; i++) {
stack->node_arr[i] = stack->node_arr[i + 1];
}
stack->size--;
}
res = 0;
return res;
}
/** @brief 取出栈顶元素的值
*
* @param stack 栈
* @param node 保存栈顶元素的值
*
* @retval 0 取出成功
* @retval 1 取出失败
*/
int stack_top(stackPtr stack, nodePtr node) {
int res = 1;
if ( NULL != stack && stack->size > 0) {
*node = stack->node_arr[0];
res = 0;
}
res = 0;
return res;
}
/** @brief 输出栈
*
* @param stack 栈
*
* @retval 0 输出成功
* @retval 1 输出失败
*/
int stack_print(stackPtr stack) {
int res = 1;
if ( NULL != stack && stack->size > 0) {
int i = 0;
for (i = 0; i < stack->size; i++) {
nodePtr tmp = &stack->node_arr[i];
node_print(tmp);
}
}
res = 0;
return res;
}
/** @file bolan.h * 实现 逆波兰算法 * */ #include"stack.h" #ifndef BOLAN_H_ #define BOLAN_H_ /** @brief 将一个中缀表达式转换为逆波兰表达式 * * @param expPtr 表达式 * @param stack 保存逆波兰表达式的栈 * * @retval 0 转换成功 * @retval 1 转换失败 */ int bolan_from_exp( char * expPtr, stackPtr stack); /** @brief 对逆波兰式作逆序处理,并去除#符号 * * @param stack 后缀栈 * * @retval 0 执行成功 * @retval 1 执行失败 */ int bolan_inverted(stackPtr stack); /** @brief 计算逆波兰表达式 * * @param stack 保存逆波兰表达式的栈 * * @return 计算结果 */ double bolan_cal( stackPtr stack); #endif /* BOLAN_H_ */
#include"bolan.h"
#include"stack.h"
#include"node.h"
#include<stdio.h>
#include<stdlib.h>
#include "tools.h"
/** @brief 将一个中缀表达式转换为逆波兰表达式
*
* @param expPtr 表达式
* @param stack 保存逆波兰表达式的栈
*
* @retval 0 转换成功
* @retval 1 转换失败
*/
int bolan_from_exp(char * expPtr, stackPtr stack) {
int res = 1;
//临时保存运算符
stackPtr tmp = stack_create(0);
//向临时栈中压入#符号
nodePtr node_sharp = node_create_sharp(‘#‘);
stack_push(tmp, node_sharp);
//将中缀表达式字符串转换为node数组
nodePtr node_array = node_create_array(expPtr);
//node数组长度
int node_array_len = node_exp_num(expPtr);
int i = 0;
//遍历node数组
for (i = 0; i < node_array_len; i++) {
nodePtr node_now = &node_array[i];
if (‘0‘ == node_now->flag) {
//如果是数字,直接入结果线
stack_push(stack, node_now);
} else if (!tools_is_char_operator(node_now->flag)) {
//如果是运算符,则与运算符栈栈顶元素进行比较
//取出临时栈栈顶元素的值
nodePtr node_tt = &tmp->node_arr[0];
char ch = node_tt->flag;
nodePtr node_top = node_create_from_char(ch);
stack_top(tmp, node_top);
char node_now_ch = node_now->flag;
char node_top_ch = node_top->flag;
if (tools_operator_compare(node_now_ch, node_top_ch) > 0) {
stack_push(tmp, node_now); //将当前运算符进临时栈
} else {
while (1) {
stack_top(tmp, node_top);
node_top_ch = node_top->flag;
if (tools_operator_compare(node_now_ch, node_top_ch) <= 0) {
stack_pop(tmp, node_top); //将临时栈顶元素弹出
stack_push(stack, node_top); //将弹出的元素入后缀栈
} else {
stack_push(tmp, node_now);
break;
}
}
}
} else if (‘(‘ == node_now->flag) {
stack_push(tmp, node_now);
} else if (‘)‘ == node_now->flag) {
while (1) {
//弹出临时栈栈顶元素
nodePtr node_tt = &tmp->node_arr[0];
char ch = node_tt->flag;
nodePtr node_top = node_create_from_char(ch);
stack_pop(tmp, node_top);
char node_top_ch = node_top->flag;
//如果是 ( ,则结束
if (‘(‘ == node_top_ch) {
break;
} else {
//如果不是 ( ,则直接送入后缀栈
stack_push(stack, node_top);
}
}
} else if (‘#‘ == node_now->flag) {
nodePtr node_tt = &tmp->node_arr[0];
char ch = node_tt->flag;
nodePtr node_top = node_create_from_char(ch);
stack_top(tmp, node_top);
// char node_top_ch = node_top->flag;
while (‘#‘ != node_top->flag) {
stack_pop(tmp, node_top); //将临时栈顶元素弹出
stack_push(stack, node_top);
}
}
}
res = 0;
return res;
}
/** @brief 对逆波兰式作逆序处理,并去除#符号
*
* @param stack 后缀栈
*
* @retval 0 执行成功
* @retval 1 执行失败
*/
int bolan_inverted(stackPtr stack) {
int res = 1;
int i = 0;
int j = 0;
nodePtr node_arr_new = (nodePtr) malloc(sizeof(_node) * stack->size - 1);
for (i = stack->size - 1; i > 0; i--) {
node_arr_new[j] = stack->node_arr[i];
j++;
}
stack->node_arr = node_arr_new;
//去除 #
// stack->size--;
res = 0;
return res;
}
/** @brief 计算逆波兰表达式
*
* @param stack 保存逆波兰表达式的栈
*
* @return 计算结果
*/
double bolan_cal(stackPtr stack) {
//保存计算结果
double res = 0;
//保存结果的栈
stackPtr stack_tmp = stack_create(0);
int i = 0;
nodePtr node_b = node_create_num(0);
nodePtr node_a = node_create_num(0);
double a = 0;
double b = 0;
for (i = 0; i < stack->size - 1; i++) {
nodePtr node_t = &stack->node_arr[i];
if (‘0‘ == node_t->flag) {
nodePtr node_num = node_create_num(node_t->num);
stack_push(stack_tmp, node_num);
} else {
node_b = node_create_num(0);
node_a = node_create_num(0);
stack_pop(stack_tmp, node_b);
stack_pop(stack_tmp, node_a);
a = node_a->num;
b = node_b->num;
char ch = node_t->flag;
switch (ch) {
case ‘+‘: {
a = a + b;
break;
}
case ‘-‘: {
a = a - b;
break;
}
case ‘*‘: {
a = a * b;
break;
}
case ‘/‘: {
a = a / b;
break;
}
}
node_a = node_create_num(a);
stack_push(stack_tmp, node_a);
}
}
stack_pop(stack_tmp, node_a);
res = node_a->num;
return res;
}
#include <gtk/gtk.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include"node.h"
#include"stack.h"
#include"bolan.h"
#include "tools.h"
//处理中文乱码
char *_(char * c) {
return g_convert(c, -1, "UTF-8", "GB2312", NULL, NULL, NULL);
}
char expression[100] = { ‘\0‘ };
int i = 0;
/** @brief 创建数字,运算符和等于号部分
*
* @return 创建的表格容器
*/
GtkWidget * create_table(GtkWidget * entry);
/** @brief 创建平方开方三角函数等扩展功能
*
* @param entry 文本框
* @return 创建好的表格容器
*/
GtkWidget * create_extends(GtkWidget * entry);
/** @brief 等于单击
*
*
* @param button
* @param data 表达式处理器
*/
void on_button_eq_clicked(GtkWidget * button, gpointer data);
/** @brief 清除按钮,清除本次数字输入,以便重新输入
*
* @param button
* @param data 表达式处理器
*/
void on_button_clear_clicked(GtkWidget * button, gpointer data);
/** @brief 数字区数字区除 = 之外的按钮单击
*
* @param button
* @param data 文本框
*/
void on_button_clicked(GtkWidget * button, gpointer data);
/** @brief 求倒数
*
* @param button
* @param data
*/
void on_button_reciprocal(GtkWidget * button, gpointer data);
/** @brief x^2
*
* @param button
* @param data
*/
void on_button_square(GtkWidget * button, gpointer data);
/** @brief x^3
*
* @param button
* @param data
*/
void on_button_cube(GtkWidget * button, gpointer data);
/** @brief sqrt(x)
*
* @param button
* @param data
*/
void on_button_sqrt(GtkWidget * button, gpointer data);
/** @brief sin
*
* @param button
* @param data
*/
void on_button_sin(GtkWidget * button, gpointer data);
/** @brief cos
*
* @param button
* @param data
*/
void on_button_cos(GtkWidget * button, gpointer data);
/** @brief tan
*
* @param button
* @param data
*/
void on_button_tan(GtkWidget * button, gpointer data);
/** @brief asin
*
* @param button
* @param data
*/
void on_button_asin(GtkWidget * button, gpointer data);
/** @brief acos
*
* @param button
* @param data
*/
void on_button_acos(GtkWidget * button, gpointer data);
/** @brief atan
*
* @param button
* @param data
*/
void on_button_atan(GtkWidget * button, gpointer data);
int main(int argc, char *argv[]) {
//主窗体
GtkWidget *window;
//主容器
GtkWidget * vbox_contain;
//清除按钮和标签容器
GtkWidget * hbox_top;
//标签
GtkWidget * label;
//清除按钮
GtkWidget * button_clear;
//显示输入和结果
GtkWidget * entry;
//主功能区容器
GtkWidget * hbox_buttom;
//数字区表格容器
GtkWidget * table;
//扩展功能表格容器
GtkWidget * table_extends;
gtk_init(&argc, &argv);
//主窗体
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), _("通信工程14-4班 1406030430 赵鑫"));
gtk_window_set_default_size(GTK_WINDOW(window), 370, 220);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
//主容器
vbox_contain = gtk_vbox_new( FALSE, 0);
gtk_container_set_border_width(GTK_CONTAINER(vbox_contain), 3);
gtk_container_add(GTK_CONTAINER(window), vbox_contain);
//上半部窗口
hbox_top = gtk_hbox_new( FALSE, 0);
label = gtk_label_new(_("计算器--gtk002"));
button_clear = gtk_button_new_with_label(_("清除"));
gtk_box_pack_start(GTK_BOX(hbox_top), label, FALSE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(hbox_top), button_clear, FALSE, FALSE, 10);
gtk_box_pack_start(GTK_BOX(vbox_contain), hbox_top, FALSE, FALSE, 3);
//显示框
entry = gtk_entry_new();
//设置显示框从右向左显示
gtk_box_pack_start(GTK_BOX(vbox_contain), entry, FALSE, FALSE, 3);
g_signal_connect(G_OBJECT(button_clear), "clicked",
G_CALLBACK(on_button_clear_clicked), (gpointer )entry);
//下半部分主功能区
hbox_buttom = gtk_hbox_new( FALSE, 0);
table = create_table(entry);
table_extends = create_extends(entry);
gtk_box_pack_start(GTK_BOX(hbox_buttom), table_extends, FALSE, FALSE, 3);
gtk_box_pack_start(GTK_BOX(hbox_buttom), table, TRUE, TRUE, 3);
gtk_box_pack_start(GTK_BOX(vbox_contain), hbox_buttom, FALSE, FALSE, 3);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
/** @brief 创建数字区
*
* @return
*/
GtkWidget * create_table(GtkWidget * entry) {
//表格容器
GtkWidget * table;
//数字
GtkWidget * button_0;
GtkWidget * button_1;
GtkWidget * button_2;
GtkWidget * button_3;
GtkWidget * button_4;
GtkWidget * button_5;
GtkWidget * button_6;
GtkWidget * button_7;
GtkWidget * button_8;
GtkWidget * button_9;
//小数点
GtkWidget * button_dot;
//等于号
GtkWidget * button_eq;
//运算符
GtkWidget * button_sum;
GtkWidget * button_minus;
GtkWidget * button_ride;
GtkWidget * button_divide;
//创建各个组件并与相关事件处理函数连接起来
button_0 = gtk_button_new_with_label("0");
g_signal_connect(G_OBJECT(button_0), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
button_1 = gtk_button_new_with_label("1");
g_signal_connect(G_OBJECT(button_1), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
button_2 = gtk_button_new_with_label("2");
g_signal_connect(G_OBJECT(button_2), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
button_3 = gtk_button_new_with_label("3");
g_signal_connect(G_OBJECT(button_3), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
button_4 = gtk_button_new_with_label("4");
g_signal_connect(G_OBJECT(button_4), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
button_5 = gtk_button_new_with_label("5");
g_signal_connect(G_OBJECT(button_5), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
button_6 = gtk_button_new_with_label("6");
g_signal_connect(G_OBJECT(button_6), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
button_7 = gtk_button_new_with_label("7");
g_signal_connect(G_OBJECT(button_7), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
button_8 = gtk_button_new_with_label("8");
g_signal_connect(G_OBJECT(button_8), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
button_9 = gtk_button_new_with_label("9");
g_signal_connect(G_OBJECT(button_9), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
button_dot = gtk_button_new_with_label(".");
g_signal_connect(G_OBJECT(button_dot), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
button_eq = gtk_button_new_with_label("=");
g_signal_connect(G_OBJECT(button_eq), "clicked",
G_CALLBACK(on_button_eq_clicked), (gpointer )entry);
button_sum = gtk_button_new_with_label("+");
g_signal_connect(G_OBJECT(button_sum), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
button_minus = gtk_button_new_with_label("-");
g_signal_connect(G_OBJECT(button_minus), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
button_ride = gtk_button_new_with_label("*");
g_signal_connect(G_OBJECT(button_ride), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
button_divide = gtk_button_new_with_label("/");
g_signal_connect(G_OBJECT(button_divide), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
//创建表格容器
table = gtk_table_new(4, 4, TRUE);
// gtk_table_set_row_spacing(GTK_TABLE(table), 4, 5);
// gtk_table_set_col_spacing(GTK_TABLE(table), 4, 5);
//将各个组件添加到表格窗口
gtk_table_attach_defaults(GTK_TABLE(table), button_7, 0, 1, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(table), button_8, 1, 2, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(table), button_9, 2, 3, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(table), button_sum, 3, 4, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(table), button_4, 0, 1, 1, 2);
gtk_table_attach_defaults(GTK_TABLE(table), button_5, 1, 2, 1, 2);
gtk_table_attach_defaults(GTK_TABLE(table), button_6, 2, 3, 1, 2);
gtk_table_attach_defaults(GTK_TABLE(table), button_minus, 3, 4, 1, 2);
gtk_table_attach_defaults(GTK_TABLE(table), button_1, 0, 1, 2, 3);
gtk_table_attach_defaults(GTK_TABLE(table), button_2, 1, 2, 2, 3);
gtk_table_attach_defaults(GTK_TABLE(table), button_3, 2, 3, 2, 3);
gtk_table_attach_defaults(GTK_TABLE(table), button_ride, 3, 4, 2, 3);
gtk_table_attach_defaults(GTK_TABLE(table), button_0, 0, 1, 3, 4);
gtk_table_attach_defaults(GTK_TABLE(table), button_dot, 1, 2, 3, 4);
gtk_table_attach_defaults(GTK_TABLE(table), button_eq, 2, 3, 3, 4);
gtk_table_attach_defaults(GTK_TABLE(table), button_divide, 3, 4, 3, 4);
return table;
}
/** @brief 创建平方开方三角函数等扩展功能
*
* @param entry 文本框
* @return 创建好的表格容器
*/
GtkWidget * create_extends(GtkWidget * entry) {
//表格容器
GtkWidget * table;
//三角函数
GtkWidget * button_sin;
GtkWidget * button_cos;
GtkWidget * button_tan;
GtkWidget * button_asin;
GtkWidget * button_acos;
GtkWidget * button_atan;
//平方开方
GtkWidget * button_square; //平方
GtkWidget * button_cube; //三次方
GtkWidget * button_sqrt; //开方
GtkWidget * button_reciprocal; //倒数
//左右括号
GtkWidget * button_paren_left;
GtkWidget * button_paren_right;
//创建各个组件
button_sin = gtk_button_new_with_label("sin");
g_signal_connect(G_OBJECT(button_sin), "clicked", G_CALLBACK(on_button_sin),
(gpointer )entry);
button_cos = gtk_button_new_with_label("cos");
g_signal_connect(G_OBJECT(button_cos), "clicked", G_CALLBACK(on_button_cos),
(gpointer )entry);
button_tan = gtk_button_new_with_label("tan");
g_signal_connect(G_OBJECT(button_tan), "clicked", G_CALLBACK(on_button_tan),
(gpointer )entry);
button_asin = gtk_button_new_with_label("asin");
g_signal_connect(G_OBJECT(button_asin), "clicked",
G_CALLBACK(on_button_asin), (gpointer )entry);
button_acos = gtk_button_new_with_label("acos");
g_signal_connect(G_OBJECT(button_acos), "clicked",
G_CALLBACK(on_button_acos), (gpointer )entry);
button_atan = gtk_button_new_with_label("atan");
g_signal_connect(G_OBJECT(button_atan), "clicked",
G_CALLBACK(on_button_atan), (gpointer )entry);
button_reciprocal = gtk_button_new_with_label("1/x");
g_signal_connect(G_OBJECT(button_reciprocal), "clicked",
G_CALLBACK(on_button_reciprocal), (gpointer )entry);
button_square = gtk_button_new_with_label("x^2");
g_signal_connect(G_OBJECT(button_square), "clicked",
G_CALLBACK(on_button_square), (gpointer )entry);
button_cube = gtk_button_new_with_label("x^3");
g_signal_connect(G_OBJECT(button_cube), "clicked",
G_CALLBACK(on_button_cube), (gpointer )entry);
button_sqrt = gtk_button_new_with_label("sqrt(x)");
g_signal_connect(G_OBJECT(button_sqrt), "clicked",
G_CALLBACK(on_button_sqrt), (gpointer )entry);
button_paren_left = gtk_button_new_with_label("(");
g_signal_connect(G_OBJECT(button_paren_left), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
button_paren_right = gtk_button_new_with_label(")");
g_signal_connect(G_OBJECT(button_paren_right), "clicked",
G_CALLBACK(on_button_clicked), (gpointer )entry);
//创建表格容器
table = gtk_table_new(4, 3, TRUE);
gtk_table_attach_defaults(GTK_TABLE(table), button_reciprocal, 0, 1, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(table), button_paren_left, 1, 2, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(table), button_paren_right, 2, 3, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(table), button_square, 0, 1, 1, 2);
gtk_table_attach_defaults(GTK_TABLE(table), button_sin, 1, 2, 1, 2);
gtk_table_attach_defaults(GTK_TABLE(table), button_asin, 2, 3, 1, 2);
gtk_table_attach_defaults(GTK_TABLE(table), button_cube, 0, 1, 2, 3);
gtk_table_attach_defaults(GTK_TABLE(table), button_cos, 1, 2, 2, 3);
gtk_table_attach_defaults(GTK_TABLE(table), button_acos, 2, 3, 2, 3);
gtk_table_attach_defaults(GTK_TABLE(table), button_sqrt, 0, 1, 3, 4);
gtk_table_attach_defaults(GTK_TABLE(table), button_tan, 1, 2, 3, 4);
gtk_table_attach_defaults(GTK_TABLE(table), button_atan, 2, 3, 3, 4);
return table;
return NULL;
}
/** @brief 等于单击
*
*
* @param button
* @param data 表达式处理器
*/
void on_button_eq_clicked(GtkWidget * button, gpointer data) {
GtkWidget * entry = (GtkWidget*) data;
tools_delete_spaces(expression);
tools_add_zero(expression);
tools_add_sharp(expression);
stackPtr stack = stack_create(0);
bolan_from_exp(expression, stack);
bolan_inverted(stack);
double res = bolan_cal(stack);
sprintf(expression, "%lf", res);
tools_exp_handle_zero(expression);
gtk_entry_set_text((GtkEntry*) entry, expression);
}
/** @brief 清除按钮,清除本次数字输入,以便重新输入
*
* @param button
* @param data 表达式处理器
*/
void on_button_clear_clicked(GtkWidget * button, gpointer data) {
GtkEntry * entry = (GtkEntry*) data;
gtk_entry_set_text(entry, "");
for (i = 0; i < 100; i++) {
expression[i] = ‘\0‘;
}
i = 0;
}
/** @brief 数字区数字区除 = 之外的按钮单击
*
* @param button
* @param data 文本框
*/
void on_button_clicked(GtkWidget * button, gpointer data) {
const gchar * num = gtk_button_get_label((GtkButton*) button);
GtkWidget * entry = (GtkWidget*) data;
expression[i] = *num;
i++;
gtk_entry_set_text((GtkEntry*) entry, expression);
}
/** @brief 求倒数
*
* @param button
* @param data
*/
void on_button_reciprocal(GtkWidget * button, gpointer data) {
GtkWidget * entry = (GtkWidget*) data;
double res = atof(expression);
res = 1 / res;
sprintf(expression, "%lf", res);
tools_exp_handle_zero(expression);
gtk_entry_set_text((GtkEntry*) entry, expression);
}
/** @brief x^2
*
* @param button
* @param data
*/
void on_button_square(GtkWidget * button, gpointer data) {
GtkWidget * entry = (GtkWidget*) data;
double res = atof(expression);
res = res * res;
sprintf(expression, "%lf", res);
tools_exp_handle_zero(expression);
gtk_entry_set_text((GtkEntry*) entry, expression);
}
/** @brief x^3
*
* @param button
* @param data
*/
void on_button_cube(GtkWidget * button, gpointer data) {
GtkWidget * entry = (GtkWidget*) data;
double res = atof(expression);
res = res * res * res;
sprintf(expression, "%lf", res);
tools_exp_handle_zero(expression);
gtk_entry_set_text((GtkEntry*) entry, expression);
}
/** @brief sqrt(x)
*
* @param button
* @param data
*/
void on_button_sqrt(GtkWidget * button, gpointer data) {
GtkWidget * entry = (GtkWidget*) data;
double res = atof(expression);
res = sqrt(res);
sprintf(expression, "%lf", res);
tools_exp_handle_zero(expression);
gtk_entry_set_text((GtkEntry*) entry, expression);
}
/** @brief sin
*
* @param button
* @param data
*/
void on_button_sin(GtkWidget * button, gpointer data) {
GtkWidget * entry = (GtkWidget*) data;
double res = atof(expression);
res = sin(3.1415926 * res / 180.0);
sprintf(expression, "%lf", res);
tools_exp_handle_zero(expression);
gtk_entry_set_text((GtkEntry*) entry, expression);
}
/** @brief tan
*
* @param button
* @param data
*/
void on_button_cos(GtkWidget * button, gpointer data) {
GtkWidget * entry = (GtkWidget*) data;
double res = atof(expression);
res = cos(3.1415926 * res / 180.0);
sprintf(expression, "%lf", res);
tools_exp_handle_zero(expression);
gtk_entry_set_text((GtkEntry*) entry, expression);
}
/** @brief tan
*
* @param button
* @param data
*/
void on_button_tan(GtkWidget * button, gpointer data) {
GtkWidget * entry = (GtkWidget*) data;
double res = atof(expression);
res = tan(3.1415926 * res / 180.0);
sprintf(expression, "%lf", res);
tools_exp_handle_zero(expression);
gtk_entry_set_text((GtkEntry*) entry, expression);
}
/** @brief asin
*
* @param button
* @param data
*/
void on_button_asin(GtkWidget * button, gpointer data) {
GtkWidget * entry = (GtkWidget*) data;
double res = atof(expression);
res = asin(res)*180.0/3.141592;
sprintf(expression, "%lf", res);
tools_exp_handle_zero(expression);
gtk_entry_set_text((GtkEntry*) entry, expression);
}
/** @brief acos
*
* @param button
* @param data
*/
void on_button_acos(GtkWidget * button, gpointer data) {
GtkWidget * entry = (GtkWidget*) data;
double res = atof(expression);
res = acos(res)*180.0/3.141592;
sprintf(expression, "%lf", res);
tools_exp_handle_zero(expression);
gtk_entry_set_text((GtkEntry*) entry, expression);
}
/** @brief atan
*
* @param button
* @param data
*/
void on_button_atan(GtkWidget * button, gpointer data){
GtkWidget * entry = (GtkWidget*) data;
double res = atof(expression);
res = atan(res)*180.0/3.141592;
sprintf(expression, "%lf", res);
tools_exp_handle_zero(expression);
gtk_entry_set_text((GtkEntry*) entry, expression);
}
原文:http://my.oschina.net/iamhere/blog/500731