要求以实现十进制浮点数的连续四则运算,并能够对括号的嵌套进行正确解析,能够解析“减号”和“负号”
花了一个多小时纯手工帮你写好了,你只需要加上你的学号姓名即可交差,如果满意,还请赏个采纳吧,谢谢
// Q7937325.cpp : 定义控制台应用程序的入口点。
//
//#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
/*****************************************/
/* 将数字字符转化成浮点型实数进行计算 */
/*****************************************/
double readnum(char f[], int*i)
{
double x = 0.0;
int k = 0;
while (f[*i] >= '0'&&f[*i] <= '9')
{
x = x * 10 + (f[*i] - '0');
(*i)++;
}
if (f[*i] == '.')
{
(*i)++;
while (f[*i] >= '0'&&f[*i] <= '9')
{
x = x * 10 + (f[*i] - '0');
(*i)++;
k++;
}
}
while (k-->0)
{
x = x / 10.0;
}
return (x);
}
/*******************************/
/* 计算后缀表达式的值 */
/*******************************/
double evalpost(char f[])
{
double obst[10];
int top = 0;
int i = 0;
double x1, x2;
while (f[i] != '=')
{
if (f[i] >= '0'&&f[i] <= '9')
{
obst[top] = readnum(f, &i); top++;
}
else if (f[i] == ' ')
i++;
else if (f[i] == '+')
{
x1 = obst[--top];
x2 = obst[--top];
obst[top] = x1 + x2;
i++;
top++;
}
else if (f[i] == '-')
{
x1 = obst[--top];
x2 = obst[--top];
obst[top] = x2 - x1;
i++;
top++;
}
else if (f[i] == '*')
{
x1 = obst[--top];
x2 = obst[--top];
obst[top] = x1*x2;
i++;
top++;
}
else if (f[i] == '*')
{
x1 = obst[--top];
x2 = obst[--top];
obst[top] = x1*x2;
i++;
top++;
}
else if (f[i] == '/')
{
x1 = obst[--top];
x2 = obst[--top];
obst[top] = x2 / x1;
i++;
top++;
}
}
return obst[0];
}
/***********************************/
/* 判断字符是否为操作字符 */
/***********************************/
int is_operation(char op)
{
switch (op)
{
case'^':
case'K':
case'+':
case'-':
case'*':
case'/': return 1;
default: return 0;
}
}
/*****************************/
/* 判断字符的优先级 */
/*****************************/
int priority(char op)
{
switch (op)
{
case'=': return -1;
case'(': return 0;
case'+':
case'-': return 1;
case'*':
case'/': return 2;
default: return -1;
}
}
/******************************/
/* 中缀表达式转化成后缀表达式*/
/******************************/
void postfix(char e[], char f[])
{
int i = 0, j = 0, k = 0;
char opst[100];
int top = 0;
opst[0] = '='; top++;
while (e[i] != '=')
{
if ((e[i] >= '0'&&e[i] <= '9') || e[i] == '.')
f[j++] = e[i];
else if (e[i] == '(')
{
opst[top] = e[i]; top++;
}
else if (e[i] == ')')
{
k = top - 1;
while (opst[k] != '(') { f[j++] = opst[--top]; k = top - 1; }
top--;
}
else if (is_operation(e[i]))
{
f[j++] = ' ';
while (priority(opst[top - 1]) >= priority(e[i]))
f[j++] = opst[--top];
opst[top] = e[i];
top++;
}
i++;
}
while (top) f[j++] = opst[--top]; f[j] = '\0';
}
void print_1(char val[])
{
system("cls");
printf("| ______________________________________ | \n");
printf("| | | | \n");
printf("| | 欢迎使用多功能计算器 | | 本计算器能够进行10进制数 \n");
printf("| |____________________________________| | +,/,*,/,()的连续运算\n");
printf("| |____________________________________| | \n");
printf("| | 设计人:这里放你的学号姓名 | | 输入所要经计算的表达式 \n");
printf("| |____________________________________| | 如:a*b/(c-d)\n");
printf("| | \n");
printf("| %s", val);
for (int i = 0; i < 35 - strlen(val); i++)
printf(" ");
printf(" | \n");
printf("| ___ ___ ___ ___ ___ ___ ___ ___ | \n");
printf("| ________ ________ ________ ________ | \n");
printf("| | | | | | | | | | \n");
printf("| | ⑨ | | ⑧ | | ⑦ | | × | | \n");
printf("| |______| |______| |______| |______| | \n");
printf("| ________ ________ ________ ________ | \n");
printf("| | | | | | | | | | \n");
printf("| | ⑥ | | ⑤ | | ④ | | - | | \n");
printf("| |______| |______| |______| |______| | \n");
printf("| ________ ________ ________ ________ | \n");
printf("| | | | | | | | | | \n");
printf("| | ③ | | ② | | ① | | + | | 继续计算/退出?1/0\n");
printf("| |______| |______| |______| |______| | \n");
printf("| ________ ________ ________ ________ | \n");
printf("| | | | | | | | | | \n");
printf("| | 〇 | | = | | AC | | ÷ | | \n");
printf("| |______| |______| |______| |______| | \n");
printf("|________________________________________| \n");
getch();
system("cls");
}
void printf_2()
{
system("cls");
printf("\n\n\n\n\n\n\n\n\t\t\t ##############################\n");
printf("\t\t\t # #\n");
printf("\t\t\t #----------谢谢使用----------#\n");
printf("\t\t\t # #\n");
printf("\t\t\t ##############################\n");
printf("\t\t\t --制作\n ");
}
/****************/
/* 转化 */
/****************/
void zhuanhuan(char g[], char e[])
{
int k, i, j = 0;
for (i = 0; g[i] != '='; i++)
{
k = i + 1;
if (g[i] == '('&&g[k] == '-')
{
e[j++] = g[i];
e[j++] = '0';
}
else e[j++] = g[i];
}
e[j] = '=';
}
int main()
{
int wei;
char e[100], f[100], g[100];
int sign; int flag;
print_1("0");
do
{
printf("输入所要经计算的表达式(如:a*b/(c-d)=):\n");
scanf("%s", g);
zhuanhuan(g, e);
postfix(e, f);
printf("输出保留几位小数:\n");
scanf("%d", &wei);
char resstr[100];
sprintf(resstr, "%s%.*lf", g, wei, evalpost(f));
print_1(resstr);
while (1)
{
flag = 3;
printf("继续计算/退出?1/0?");
sign = getch();
printf("%c\n", sign);
switch (sign)
{
case '1':flag = 1; getch(); break;
case '0':flag = 0; getch(); break;
default: printf("非法输入,请重新输入:\n");
}
if (flag == 1 || flag == 0)break;
}
} while (flag == 1);
printf_2();
return 0;
}
开发截图
以下是程序运行效果
首先是看清情况,程序的任务、程序的预期表现与程序工作的实际表现,大概是什么方面的“病”——对于常见的小“病”,经验丰富的专家不用后续检查就能知道问题所在。经验当然重要,但对于初学者而言,掌握正确的调试思路则更加重要,因为初学者很难通过观察程序而发现问题所在。
threenewbee 不错
以下是一个简单的用C语言实现计算器的例子,可以支持四则运算和括号嵌套,仅供参考,可以根据实际需求进行优化。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX_EXPR_LEN 1024
char expr[MAX_EXPR_LEN + 1];
int cur_pos;
double parse_expr();
// 解析数字
double parse_number() {
double num = 0.0;
int decimal = 0;
while (isdigit(expr[cur_pos])) {
num = num * 10.0 + (expr[cur_pos] - '0');
cur_pos++;
}
if (expr[cur_pos] == '.') {
cur_pos++;
while (isdigit(expr[cur_pos])) {
num = num * 10.0 + (expr[cur_pos] - '0');
decimal++;
cur_pos++;
}
}
while (decimal > 0) {
num /= 10.0;
decimal--;
}
return num;
}
// 解析加减法表达式
double parse_addsub() {
double left, right, result;
char op;
left = parse_expr();
while ((op = expr[cur_pos]) == '+' || op == '-') {
cur_pos++;
right = parse_expr();
if (op == '+') {
left += right;
} else {
left -= right;
}
}
return left;
}
// 解析乘除法表达式
double parse_muldiv() {
double left, right, result;
char op;
left = parse_number();
while ((op = expr[cur_pos]) == '*' || op == '/') {
cur_pos++;
right = parse_number();
if (op == '*') {
left *= right;
} else if (op == '/') {
if (right == 0) {
fprintf(stderr, "Error: divide by zero\n");
exit(-1);
}
left /= right;
}
}
return left;
}
// 解析表达式
double parse_expr() {
double result;
if (expr[cur_pos] == '(') {
cur_pos++;
result = parse_addsub();
if (expr[cur_pos] != ')') {
fprintf(stderr, "Error: missing ')'\n");
exit(-1);
}
cur_pos++;
} else {
result = parse_muldiv();
}
return result;
}
int main() {
printf("Please enter an expression: ");
scanf("%s", expr);
cur_pos = 0;
double result = parse_addsub();
printf("Result: %lf\n", result);
return 0;
}
这里提供一个简单的实现,只支持十进制浮点数的四则运算。同时支持括号嵌套,并可以解析减号和负号。另外需要注意的是,由于C语言中没有直接支持字符串处理的函数,所以本例中使用了字符数组来存储表达式。为了防止内存溢出,我们使用了一个宏定义MAX_EXPR_LEN
来约束表达式最长的长度,如果表达式超过这个长度,程序会报错。
C语言实现简易计算器
可以借鉴下
https://blog.csdn.net/weixin_46531416/article/details/117401042
这个是我的结课作业,本人南京某大学生,如果和我有同样需求的同学,ip也相同的话,可以借鉴,但请不要像我一样照抄,拜托了
以下是一个简单的计算器程序,支持十进制浮点数的四则运算和括号嵌套,可以解析减号和负号:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#include <math.h>
#define STACK_SIZE 100
typedef struct {
int top;
double items[STACK_SIZE];
} Stack;
void push(Stack *s, double value) {
if (s->top == STACK_SIZE - 1) {
printf("Stack overflow!\n");
exit(EXIT_FAILURE);
}
s->items[++(s->top)] = value;
}
double pop(Stack *s) {
if (s->top == -1) {
printf("Stack underflow!\n");
exit(EXIT_FAILURE);
}
return s->items[(s->top)--];
}
double evaluate(char *expr) {
Stack values, ops;
values.top = ops.top = -1;
char *p = expr;
while (*p != '\0') {
if (*p == '(') {
push(&ops, *p);
} else if (isdigit(*p) || *p == '.') {
double value = 0.0;
while (isdigit(*p)) {
value = value * 10.0 + (*p - '0');
p++;
}
if (*p == '.') {
p++;
double fraction = 1.0;
while (isdigit(*p)) {
fraction /= 10.0;
value += (*p - '0') * fraction;
p++;
}
}
push(&values, value);
continue;
} else if (*p == '+' || *p == '-' || *p == '*' || *p == '/') {
while (ops.top != -1 && ops.items[ops.top] != '(' &&
((*p != '+' && *p != '-') || (ops.items[ops.top] != '*' && ops.items[ops.top] != '/'))) {
double b = pop(&values);
double a = pop(&values);
char op = pop(&ops);
double result = 0.0;
switch (op) {
case '+':
result = a + b;
break;
case '-':
result = a - b;
break;
case '*':
result = a * b;
break;
case '/':
result = a / b;
break;
}
push(&values, result);
}
push(&ops, *p);
} else if (*p == ')') {
while (ops.top != -1 && ops.items[ops.top] != '(') {
double b = pop(&values);
double a = pop(&values);
char op = pop(&ops);
double result = 0.0;
switch (op) {
case '+':
result = a + b;
break;
case '-':
result = a - b;
break;
case '*':
result = a * b;
break;
case '/':
result = a / b;
break;
}
push(&values, result);
}
if (ops.top == -1) {
printf("Mismatched parentheses!\n");
exit(EXIT_FAILURE);
}
pop(&ops);
} else {
printf("Invalid character: %c\n", *p);
exit(EXIT_FAILURE);
}
p++;
}
while (ops.top != -1) {
if (ops.items[ops.top] == '(') {
printf("Mismatched parentheses!\n");
exit(EXIT_FAILURE);
}
double b = pop(&values);
double a = pop(&values);
char op = pop(&ops);
double result = 0.0;
switch (op) {
case '+':
result = a + b;
break;
case '-':
result = a - b;
break;
case '*':
result = a * b;
break;
case '/':
result = a / b;
break;
}
push(&values, result);
}
if (values.top != 0) {
printf("Invalid expression!\n");
exit(EXIT_FAILURE);
}
return pop(&values);
}
int main() {
char expr[STACK_SIZE];
printf("Enter an arithmetic expression: ");
fgets(expr, STACK_SIZE, stdin);
double result = evaluate(expr);
printf("Result: %g\n", result);
return 0;
}
该程序使用了两个栈来实现运算符优先级的解析,其中一个栈用于存储运算符,另一个栈用于存储操作数。
在处理数字时,程序使用了一个双精度浮点数来存储数值,并对小数点进行了特殊处理。
在处理运算符时,程序使用了一个循环来处理优先级较高的运算符,直到遇到优先级较低的或遇到括号为止。
在处理括号时,程序使用了一个栈来存储左括号,并在遇到右括号时弹出栈中的左括号,直到遇到匹配的左括号为止。
在处理错误情况时,程序使用了exit函数强制退出程序,并输出相应的错误信息。
该程序可以通过命令行输入算术表达式,并输出计算结果。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#define MAX_STACK_SIZE 100
#define MAX_EXPRESSION_SIZE 200
typedef struct {
double data[MAX_STACK_SIZE];
int top;
} Stack;
void initStack(Stack *stack) {
stack->top = -1;
}
int isStackEmpty(Stack *stack) {
return stack->top == -1;
}
int isStackFull(Stack *stack) {
return stack->top == MAX_STACK_SIZE - 1;
}
void push(Stack *stack, double value) {
if (isStackFull(stack)) {
printf("Stack overflow!\n");
exit(1);
}
stack->data[++stack->top] = value;
}
double pop(Stack *stack) {
if (isStackEmpty(stack)) {
printf("Stack underflow!\n");
exit(1);
}
return stack->data[stack->top--];
}
int isOperator(char c) {
return (c == '+' || c == '-' || c == '*' || c == '/');
}
int priority(char c) {
if (c == '+' || c == '-') return 1;
else if (c == '*' || c == '/') return 2;
else return 0;
}
void infixToPostfix(char infix[], char postfix[]) {
Stack stack;
initStack(&stack);
int i = 0, j = 0;
while (infix[i] != '\0') {
if (isdigit(infix[i]) || infix[i] == '.') {
postfix[j++] = infix[i++];
while (isdigit(infix[i]) || infix[i] == '.') {
postfix[j++] = infix[i++];
}
postfix[j++] = ' ';
}
else if (infix[i] == '(') {
push(&stack, '(');
i++;
}
else if (infix[i] == ')') {
while (!isStackEmpty(&stack) && stack.data[stack.top] != '(') {
postfix[j++] = pop(&stack);
postfix[j++] = ' ';
}
if (!isStackEmpty(&stack) && stack.data[stack.top] == '(') {
pop(&stack);
}
i++;
}
else if (isOperator(infix[i])) {
while (!isStackEmpty(&stack) && stack.data[stack.top] != '(' && priority(stack.data[stack.top]) >= priority(infix[i])) {
postfix[j++] = pop(&stack);
postfix[j++] = ' ';
}
push(&stack, infix[i]);
i++;
}
else {
printf("Invalid character: %c\n", infix[i]);
exit(1);
}
}
while (!isStackEmpty(&stack)) {
postfix[j++] = pop(&stack);
postfix[j++] = ' ';
}
postfix[j] = '\0';
}
double evaluate(char postfix[]) {
Stack stack;
initStack(&stack);
int i = 0;
double operand1, operand2, result;
while (postfix[i] != '\0') {
if (isdigit(postfix[i]) || postfix[i] == '.') {
char str[20];
int j = 0;
while (isdigit(postfix[i]) || postfix[i] == '.') {
str[j++] = postfix[i++];
}
str[j] = '\0';
push(&stack, atof(str));
}
else if (postfix[i] == '+') {
operand2 = pop(&stack);
operand1 = pop(&stack);
result = operand1 + operand2;
push(&stack, result);
i++;
}
else if (postfix[i] == '-') {
operand2 = pop(&stack);
operand1 = pop(&stack);
result = operand1 - operand2;
push(&stack, result);
i++;
}
else if (postfix[i] == '*') {
operand2 = pop(&stack);
operand1 = pop(&stack);
result = operand1 * operand2;
push(&stack, result);
i++;
}
else if (postfix[i] == '/') {
operand2 = pop(&stack);
operand1 = pop(&stack);
if (operand2 == 0) {
printf("Divide by zero!\n");
exit(1);
}
result = operand1 / operand2;
push(&stack, result);
i++;
}
else if (postfix[i] == ' ') {
i++;
}
else if (postfix[i] == '-') {
i++;
char str[20];
int j = 0;
while (isdigit(postfix[i]) || postfix[i] == '.') {
str[j++] = postfix[i++];
}
str[j] = '\0';
push(&stack, -atof(str));
}
}
return pop(&stack);
}
int main() {
char infix[MAX_EXPRESSION_SIZE];
char postfix[MAX_EXPRESSION_SIZE];
printf("Enter an infix expression: ");
fgets(infix, MAX_EXPRESSION_SIZE, stdin);
infix[strlen(infix) - 1] = '\0';
infixToPostfix(infix, postfix);
printf("Postfix expression: %s\n", postfix);
double result = evaluate(postfix);
printf("Result: %g\n", result);
return 0;
}