sk2 du - kalkulacka

This commit is contained in:
mr314ot 2026-01-24 14:02:17 +01:00
parent a67b036fc1
commit 0f396051b8
5 changed files with 183 additions and 0 deletions

16
sk2/Makefile Normal file
View File

@ -0,0 +1,16 @@
CC=gcc
CFLAGS=-Wall -lm
all: calculator
calculator: main.o calculator.o
$(CC) main.o calculator.o -o calculator $(CFLAGS)
main.o: main.c calculator.h
$(CC) -c main.c
calculator.o: calculator.c calculator.h
$(CC) -c calculator.c
clean:
rm -f *.o calculator

25
sk2/README.md Normal file
View File

@ -0,0 +1,25 @@
# Vedecká kalkulačka v jazyku C
## Zadanie
Naprogramovať vedeckú kalkulačku, ktorá vyhodnocuje matematické výrazy
v infixnej notácii so zátvorkami a vedeckými funkciami.
## Funkčnosť
Program podporuje:
- reálne čísla s presnosťou double
- sčítanie (+), odčítanie (-), násobenie (*), delenie (/), zátvorky
- sin, cos, odmocninu (sqrt), druhú mocninu (pow), log
## Riešenie
Výraz je najprv prekonvertovaný z infixnej do postfixovej notácie
(Shunting-yard algoritmus).
Postfixový výraz je následne vyhodnotený pomocou zásobníka.
## Podmienky fungovania
- prekladač GCC
- knižnica math.h
## Použité zdroje
- Shunting Yard Algorithm - Edsger Dijkstra
- Dokumentácia jazyka C
- math.h

122
sk2/calculator.c Normal file
View File

@ -0,0 +1,122 @@
#include "calculator.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#define MAX 256
#define DEG_TO_RAD(x) ((x) * M_PI / 180.0)
typedef struct {
double data[MAX];
int top;
} DoubleStack;
typedef struct {
char data[MAX][10];
int top;
} StringStack;
//funckie stacku
void push_double(DoubleStack *s, double v) { s->data[++s->top] = v; }
double pop_double(DoubleStack *s) { return s->data[s->top--]; }
void push_string(StringStack *s, const char *v) { strcpy(s->data[++s->top], v); }
char *pop_string(StringStack *s) { return s->data[s->top--]; }
char *peek_string(StringStack *s) { return s->data[s->top]; }
//priority operatorov
int priority(const char *op) {
if (!strcmp(op, "+") || !strcmp(op, "-")) return 1;
if (!strcmp(op, "*") || !strcmp(op, "/")) return 2;
if (!strcmp(op, "sin") || !strcmp(op, "cos") ||
!strcmp(op, "sqrt") || !strcmp(op, "log") ||
!strcmp(op, "pow")) return 3;
return 0;
}
//infix na postfix
int infix_to_postfix(const char *infix, char postfix[][10]) {
StringStack ops = {.top = -1};
int k = 0;
for (int i = 0; infix[i]; ) {
if (isspace(infix[i])) { i++; continue; }
if (isdigit(infix[i]) || infix[i] == '.') {
char num[10];
int j = 0;
while (isdigit(infix[i]) || infix[i] == '.')
num[j++] = infix[i++];
num[j] = '\0';
strcpy(postfix[k++], num);
}
else if (isalpha(infix[i])) {
char func[10];
int j = 0;
while (isalpha(infix[i]))
func[j++] = infix[i++];
func[j] = '\0';
push_string(&ops, func);
}
else if (infix[i] == '(') {
char t[2] = "(";
push_string(&ops, t);
i++;
}
else if (infix[i] == ')') {
while (ops.top != -1 && strcmp(peek_string(&ops), "("))
strcpy(postfix[k++], pop_string(&ops));
pop_string(&ops);
i++;
}
else {
char op[2] = {infix[i++], '\0'};
while (ops.top != -1 &&
priority(peek_string(&ops)) >= priority(op))
strcpy(postfix[k++], pop_string(&ops));
push_string(&ops, op);
}
}
while (ops.top != -1)
strcpy(postfix[k++], pop_string(&ops));
return k;
}
//vypocet postfixu
double evaluate_postfix(char postfix[][10], int n) {
DoubleStack s = {.top = -1};
for (int i = 0; i < n; i++) {
if (isdigit(postfix[i][0]) || postfix[i][0] == '.') {
push_double(&s, atof(postfix[i]));
}
else {
double b = pop_double(&s);
double a = (!strcmp(postfix[i], "sin") ||
!strcmp(postfix[i], "cos") ||
!strcmp(postfix[i], "sqrt") ||
!strcmp(postfix[i], "log")) ? 0 : pop_double(&s);
if (!strcmp(postfix[i], "+")) push_double(&s, a + b);
else if (!strcmp(postfix[i], "-")) push_double(&s, a - b);
else if (!strcmp(postfix[i], "*")) push_double(&s, a * b);
else if (!strcmp(postfix[i], "/")) push_double(&s, a / b);
else if (!strcmp(postfix[i], "sin")) push_double(&s, sin(DEG_TO_RAD(b)));
else if (!strcmp(postfix[i], "cos")) push_double(&s, cos(DEG_TO_RAD(b)));
else if (!strcmp(postfix[i], "sqrt")) push_double(&s, sqrt(b));
else if (!strcmp(postfix[i], "log")) push_double(&s, log10(b));
else if (!strcmp(postfix[i], "pow")) push_double(&s, pow(a, b));
}
}
return pop_double(&s);
}
double evaluate_expression(const char *expression) {
char postfix[MAX][10];
int n = infix_to_postfix(expression, postfix);
return evaluate_postfix(postfix, n);
}

6
sk2/calculator.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef CALCULATOR_H
#define CALCULATOR_H
double evaluate_expression(const char *expression);
#endif

14
sk2/main.c Normal file
View File

@ -0,0 +1,14 @@
#include <stdio.h>
#include "calculator.h"
int main() {
char expr[256];
printf("Zadaj vyraz: ");
fgets(expr, sizeof(expr), stdin);
double result = evaluate_expression(expr);
printf("Vysledok: %.2f\n", result);
return 0;
}