其实这次写这个程序,原本是帮一个学妹完成课程设计,不过写着写着就想要重新拿走这个项目了
现在在只是先记录一下,尔后还要在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); }