This commit is contained in:
Oleksandr Vyshniakov 2026-01-25 23:20:37 +01:00
parent 29076c8d00
commit 02b2f1146c
8 changed files with 228 additions and 0 deletions

View File

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

56
sk2/README.md Normal file
View File

@ -0,0 +1,56 @@
# Vedecká kalkulačka (Scientific Calculator)
## Popis projektu
Tento projekt implementuje jednoduchú vedeckú kalkulačku v jazyku C.
Kalkulačka spracováva matematické výrazy zapísané v **infixnej notácii** a vyhodnocuje ich pomocou **rekurzívneho syntaktického analyzátora**.
Program podporuje základné aritmetické operácie, zátvorky a vybrané matematické funkcie zo štandardnej knižnice jazyka C.
## Podporované operácie
- práca s reálnymi číslami (`double`) s presnosťou minimálne **2 desatinné miesta**
- sčítanie (`+`)
- odčítanie (`-`)
- násobenie (`*`)
- delenie (`/`)
- zátvorky (`(`, `)`)
- goniometrické funkcie:
- `sin(x)`
- `cos(x)`
- odmocnina:
- `sqrt(x)`
- druhá mocnina (a všeobecná mocnina):
- `pow(x, y)`
(druhá mocnina sa vypočíta ako `pow(x, 2)`)
- logaritmus:
- `log(x)` (prirodzený logaritmus)
## Spôsob riešenia
Vyhodnocovanie výrazov je realizované **bez použitia zásobníkov**.
Použitý je **rekurzívny zostupný parser**, ktorý rešpektuje prioritu operátorov:
- výrazy (`+`, `-`)
- termy (`*`, `/`)
- faktory (čísla, zátvorky, funkcie)
Tento prístup umožňuje prirodzené spracovanie infixnej notácie a zátvoriek.
## Kompilácia
Projekt sa kompiluje pomocou nástroja `make`.
V adresári projektu spusti:
make.
## Priklady použitia
1) Zadaj vyraz:
(2 + 3) * 2
10.00;
2) Zadaj vyraz:
(10 * 2) + (6 / 2)
23.00;
3) Zadaj vyraz:
pow(2, 3) + sqrt(16)
12.00;

View File

@ -0,0 +1,129 @@
#include "calculator.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
static const char *ptr;
static void skip_spaces(void) {
while (*ptr && isspace(*ptr)) {
ptr++;
}
}
static int match(const char *s) {
int len = strlen(s);
if (strncmp(ptr, s, len) == 0) {
ptr += len;
return 1;
}
return 0;
}
static double parse_expression(void);
static double parse_number(void) {
skip_spaces();
char *end;
double val = strtod(ptr, &end);
ptr = end;
return val;
}
static double parse_factor(void) {
skip_spaces();
if (*ptr == '(') {
ptr++;
double val = parse_expression();
skip_spaces();
if (*ptr == ')') {
ptr++;
}
return val;
}
if (match("sin")) {
skip_spaces();
return sin(parse_factor());
}
if (match("cos")) {
skip_spaces();
return cos(parse_factor());
}
if (match("sqrt")) {
skip_spaces();
return sqrt(parse_factor());
}
if (match("log")) {
skip_spaces();
return log(parse_factor());
}
if (match("pow")) {
skip_spaces();
if (*ptr == '(') ptr++;
double a = parse_expression();
skip_spaces();
if (*ptr == ',') ptr++;
double b = parse_expression();
skip_spaces();
if (*ptr == ')') ptr++;
return pow(a, b);
}
return parse_number();
}
static double parse_term(void) {
double val = parse_factor();
while (1) {
skip_spaces();
if (*ptr == '*') {
ptr++;
val *= parse_factor();
} else if (*ptr == '/') {
ptr++;
val /= parse_factor();
} else {
break;
}
}
return val;
}
static double parse_expression(void) {
double val = parse_term();
while (1) {
skip_spaces();
if (*ptr == '+') {
ptr++;
val += parse_term();
} else if (*ptr == '-') {
ptr++;
val -= parse_term();
} else {
break;
}
}
return val;
}
double evaluate_expression(const char *expr) {
ptr = expr;
return parse_expression();
}

BIN
sk2/calculator.exe Normal file

Binary file not shown.

View File

@ -0,0 +1,9 @@
#ifndef CALCULATOR_H
#define CALCULATOR_H
#define MAX_EXPR 512
#define MAX_STACK 256
double evaluate_expression(const char *expr);
#endif

BIN
sk2/calculator.o Normal file

Binary file not shown.

View File

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

BIN
sk2/main.o Normal file

Binary file not shown.