计算器--gtk--003

其实这次写这个程序,原本是帮一个学妹完成课程设计,不过写着写着就想要重新拿走这个项目了

现在在只是先记录一下,尔后还要在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>

tools.h


/** @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_ */

tools.c



#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;
}

node.h



/** @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_ */

node.c



#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;
}

stack.h



/** @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_ */

stack.c



#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;
}


bolan.h


/** @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_ */





bolan.c


#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;
}


main.c



#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);	
}


运行效果:


计算器--gtk--003

你可能感兴趣的:(计算器--gtk--003)