Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
prog-1
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Pedro Folloni Pesserl
prog-1
Commits
0b742219
Commit
0b742219
authored
Dec 11, 2022
by
Pedro Folloni Pesserl
Browse files
Options
Downloads
Patches
Plain Diff
add exponentiation, memory storage and multiple line calculations
parent
003a0edc
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
calculadora/calc
+0
-0
0 additions, 0 deletions
calculadora/calc
calculadora/calculadora.c
+166
-112
166 additions, 112 deletions
calculadora/calculadora.c
calculadora/makefile
+3
-3
3 additions, 3 deletions
calculadora/makefile
with
169 additions
and
115 deletions
calculadora/calc
deleted
100755 → 0
+
0
−
0
View file @
003a0edc
File deleted
This diff is collapsed.
Click to expand it.
calculadora/calculadora.c
+
166
−
112
View file @
0b742219
#include
<stdlib.h>
#include
<stdlib.h>
#include
<stdio.h>
#include
<stdio.h>
#include
<ctype.h>
#include
<ctype.h>
#include
<math.h>
#include
"libpilha.h"
#include
"libpilha.h"
typedef
double
t_operador
;
/* Definindo o valor do operador como um inteiro, prevenimos
erros de aritmética com ponto flutuante. */
typedef
int
t_operador
;
#define TAM_ENTRADA 256
#define TAM_ENTRADA 256
#define TAM_PILHA 1024
#define TAM_PILHA 1024
/* Constantes com valores para identificar os operadores. O valor
/* Constantes com valores para identificar os operadores. O valor
antes d
o ponto flutuant
e d
i
fine a precedencia entre os operadores,
antes d
a casa da unidad
e d
e
fine a precedencia entre os operadores,
valores maiores tem maior precedencia. */
valores maiores tem maior precedencia. */
#define SOM 10.1
#define SOM 101
#define SUB 10.2
#define SUB 102
#define MUL 20.1
#define MUL 201
#define DIV 20.2
#define DIV 202
#define EXP 300
/* Identificador de '(' para ser empilhado na pilha de operadores */
/* Identificador de '(' para ser empilhado na pilha de operadores */
#define PAR 99
.
0
#define PAR 990
/* Converte os caracteres que representam os operadores na entrada
/* Converte os caracteres que representam os operadores na entrada
...
@@ -32,6 +36,7 @@ int converte_operador(t_operador *op, char c) {
...
@@ -32,6 +36,7 @@ int converte_operador(t_operador *op, char c) {
case
'-'
:
*
op
=
SUB
;
break
;
case
'-'
:
*
op
=
SUB
;
break
;
case
'*'
:
*
op
=
MUL
;
break
;
case
'*'
:
*
op
=
MUL
;
break
;
case
'/'
:
*
op
=
DIV
;
break
;
case
'/'
:
*
op
=
DIV
;
break
;
case
'^'
:
*
op
=
EXP
;
break
;
default
:
return
0
;
default
:
return
0
;
}
}
return
1
;
return
1
;
...
@@ -41,7 +46,7 @@ int converte_operador(t_operador *op, char c) {
...
@@ -41,7 +46,7 @@ int converte_operador(t_operador *op, char c) {
/* Retorna 1 se o operador op1 tem precedencia sobre o operador op2.
/* Retorna 1 se o operador op1 tem precedencia sobre o operador op2.
Retorna 0 caso contrario. */
Retorna 0 caso contrario. */
int
precede
(
t_operador
op1
,
t_operador
op2
)
{
int
precede
(
t_operador
op1
,
t_operador
op2
)
{
if
((
op1
-
op2
)
>
=
1
.
0
)
if
((
op1
-
op2
)
>
1
)
return
1
;
return
1
;
return
0
;
return
0
;
}
}
...
@@ -65,15 +70,18 @@ int opera(t_operador op, t_pilha *valores) {
...
@@ -65,15 +70,18 @@ int opera(t_operador op, t_pilha *valores) {
return
empilha
(
val_esq
*
val_dir
,
valores
);
return
empilha
(
val_esq
*
val_dir
,
valores
);
if
(
op
==
DIV
&&
val_dir
!=
0
.
0
)
if
(
op
==
DIV
&&
val_dir
!=
0
.
0
)
return
empilha
(
val_esq
/
val_dir
,
valores
);
return
empilha
(
val_esq
/
val_dir
,
valores
);
if
(
op
==
EXP
)
return
empilha
(
pow
(
val_esq
,
val_dir
),
valores
);
return
0
;
return
0
;
}
}
/* Imprime na saida de erro (stderr) a mensagem de erro e a linha e
/* Imprime na saida de erro (stderr) a mensagem de erro e a linha e
a coluna da entrada onde o erro foi detectado. */
a coluna da entrada onde o erro foi detectado. */
void
erro
_aborta
(
char
*
msg
,
int
col
)
{
void
erro
(
char
*
msg
,
int
col
,
int
*
flag_erro
)
{
fprintf
(
stderr
,
"ERRO: %s (coluna %d)
\n
"
,
msg
,
col
);
fprintf
(
stderr
,
"ERRO: %s (coluna %d)
\n
"
,
msg
,
col
);
exit
(
1
)
;
*
flag_erro
=
1
;
}
}
...
@@ -135,32 +143,42 @@ char* le_entrada() {
...
@@ -135,32 +143,42 @@ char* le_entrada() {
return
ent
;
return
ent
;
}
}
int
main
()
{
int
main
()
{
t_pilha
*
pilha_valores
,
*
pilha_operadores
;
t_pilha
*
pilha_valores
,
*
pilha_operadores
;
t_operador
operador
,
op_topo
;
t_operador
operador
,
op_topo
;
double
operando
,
resultado
;
double
operando
,
resultado
,
memoria
=
0
.
0
;
char
*
entrada
,
*
c
,
*
prox
;
char
*
entrada
,
*
c
,
*
prox
;
int
flag_erro
=
0
;
entrada
=
le_entrada
();
if
(
!
entrada
)
{
erro
(
"erro de leitura"
,
0
,
&
flag_erro
);
return
1
;
}
c
=
entrada
;
/* Loop principal, le valores e realiza operacoes ate ler uma linha
que contém "q" na primeira posição */
while
(
*
c
!=
'q'
)
{
pilha_valores
=
cria_pilha
(
TAM_PILHA
);
pilha_valores
=
cria_pilha
(
TAM_PILHA
);
if
(
!
pilha_valores
)
if
(
!
pilha_valores
)
{
erro_aborta
(
"erro ao criar pilha de valores"
,
0
);
erro
(
"erro ao criar pilha de valores"
,
0
,
&
flag_erro
);
return
1
;
}
pilha_operadores
=
cria_pilha
(
TAM_PILHA
);
pilha_operadores
=
cria_pilha
(
TAM_PILHA
);
if
(
!
pilha_operadores
)
if
(
!
pilha_operadores
)
{
erro_aborta
(
"erro ao criar pilha de operadores"
,
0
);
erro
(
"erro ao criar pilha de operadores"
,
0
,
&
flag_erro
);
return
1
;
}
entrada
=
le_entrada
();
while
(
*
c
!=
'q'
&&
*
c
!=
'\n'
&&
!
flag_erro
)
{
if
(
!
entrada
)
/* Percorre o ponteiro c pela entrada até achar um q, o final da linha ou um erro. */
erro_aborta
(
"erro de leitura"
,
0
);
c
=
entrada
;
while
(
*
c
!=
'\n'
)
{
/* Percorre o ponteiro c pela entrada ate o final de linha. */
/* Caso 1: separadores */
/* Caso 1: separadores */
if
(
*
c
==
' '
||
*
c
==
'\t'
)
if
(
*
c
==
' '
||
*
c
==
'\t'
)
/* Se for sepador, passa para o proximo caracter. */
/* Se for sepa
ra
dor, passa para o proximo caracter. */
c
++
;
c
++
;
/* Caso 2: operando */
/* Caso 2: operando */
...
@@ -168,9 +186,10 @@ int main() {
...
@@ -168,9 +186,10 @@ int main() {
/* Se for [1..9] le um valor e empilha na pilha de valores. */
/* Se for [1..9] le um valor e empilha na pilha de valores. */
operando
=
strtod
(
c
,
&
prox
);
operando
=
strtod
(
c
,
&
prox
);
if
(
c
==
prox
)
if
(
c
==
prox
)
erro_aborta
(
"operando incorreto"
,
c
-
entrada
+
1
);
erro
(
"operando incorreto"
,
c
-
entrada
+
1
,
&
flag_erro
);
if
(
!
empilha
(
operando
,
pilha_valores
))
else
if
(
!
empilha
(
operando
,
pilha_valores
))
erro_aborta
(
"pilha de valores cheia"
,
c
-
entrada
+
1
);
erro
(
"pilha de valores cheia"
,
c
-
entrada
+
1
,
&
flag_erro
);
else
c
=
prox
;
c
=
prox
;
}
}
...
@@ -178,7 +197,8 @@ int main() {
...
@@ -178,7 +197,8 @@ int main() {
else
if
(
*
c
==
'('
)
{
else
if
(
*
c
==
'('
)
{
/* Se for abre parenteses, empilha PAR na pilha de operadores. */
/* Se for abre parenteses, empilha PAR na pilha de operadores. */
if
(
!
empilha
(
PAR
,
pilha_operadores
))
if
(
!
empilha
(
PAR
,
pilha_operadores
))
erro_aborta
(
"pilha de operadores cheia"
,
c
-
entrada
+
1
);
erro
(
"pilha de operadores cheia"
,
c
-
entrada
+
1
,
&
flag_erro
);
else
c
++
;
c
++
;
}
}
...
@@ -186,14 +206,15 @@ int main() {
...
@@ -186,14 +206,15 @@ int main() {
else
if
(
*
c
==
')'
)
{
else
if
(
*
c
==
')'
)
{
/* Se for fecha parenteses, processa a pilha de operadores até
/* Se for fecha parenteses, processa a pilha de operadores até
encontar um PAR. */
encontar um PAR. */
while
(
topo
(
&
op_topo
,
pilha_operadores
)
&&
op_topo
!=
PAR
)
{
while
(
topo
(
&
op_topo
,
pilha_operadores
)
&&
op_topo
!=
PAR
&&
!
flag_erro
)
{
desempilha
(
&
op_topo
,
pilha_operadores
);
desempilha
(
&
op_topo
,
pilha_operadores
);
if
(
!
opera
(
op_topo
,
pilha_valores
))
if
(
!
opera
(
op_topo
,
pilha_valores
))
erro_aborta
(
"formato incorreto"
,
c
-
entrada
+
1
);
erro
(
"formato incorreto"
,
c
-
entrada
+
1
,
&
flag_erro
);
}
}
if
(
pilha_vazia
(
pilha_operadores
)
||
if
(
pilha_vazia
(
pilha_operadores
)
||
(
desempilha
(
&
op_topo
,
pilha_operadores
)
&&
op_topo
!=
PAR
))
(
desempilha
(
&
op_topo
,
pilha_operadores
)
&&
op_topo
!=
PAR
))
erro_aborta
(
"formato incorreto"
,
c
-
entrada
+
1
);
erro
(
"formato incorreto"
,
c
-
entrada
+
1
,
&
flag_erro
);
else
c
++
;
c
++
;
}
}
...
@@ -203,41 +224,74 @@ int main() {
...
@@ -203,41 +224,74 @@ int main() {
ao topo da pilha de operadores. */
ao topo da pilha de operadores. */
while
(
topo
(
&
op_topo
,
pilha_operadores
)
&&
while
(
topo
(
&
op_topo
,
pilha_operadores
)
&&
op_topo
!=
PAR
&&
op_topo
!=
PAR
&&
precede
(
op_topo
,
operador
))
{
precede
(
op_topo
,
operador
)
&&
!
flag_erro
)
{
/* Enquando o topo da pilha tiver precedencia, desempilha e
/* Enquando o topo da pilha tiver precedencia, desempilha e
processa o operador do topo da pilha. */
processa o operador do topo da pilha. */
desempilha
(
&
op_topo
,
pilha_operadores
);
desempilha
(
&
op_topo
,
pilha_operadores
);
if
(
!
opera
(
op_topo
,
pilha_valores
))
if
(
!
opera
(
op_topo
,
pilha_valores
))
erro_aborta
(
"formato incorreto"
,
c
-
entrada
+
1
);
erro
(
"formato incorreto"
,
c
-
entrada
+
1
,
&
flag_erro
);
}
}
if
(
!
empilha
(
operador
,
pilha_operadores
))
if
(
!
empilha
(
operador
,
pilha_operadores
))
/* Empilha o novo operador na pilha de operadores. */
/* Empilha o novo operador na pilha de operadores. */
erro_aborta
(
"pilha de operadores cheia"
,
c
-
entrada
+
1
);
erro
(
"pilha de operadores cheia"
,
c
-
entrada
+
1
,
&
flag_erro
);
else
c
++
;
}
/* Caso 6: memória */
else
if
(
*
c
==
'm'
)
{
/* Se for m, empilha o valor guardado na memória na pilha de valores */
if
(
!
empilha
(
memoria
,
pilha_valores
))
erro
(
"pilha de valores cheia"
,
c
-
entrada
+
1
,
&
flag_erro
);
else
c
++
;
c
++
;
}
}
/* Caso
6
: caracter invalido na entrada */
/* Caso
7
: caracter invalido na entrada */
else
else
erro_aborta
(
"caracter desconhecido"
,
c
-
entrada
+
1
);
erro
(
"caracter desconhecido"
,
c
-
entrada
+
1
,
&
flag_erro
);
}
}
/* Nesse ponto o processamento da entrada terminou e pode ser o caso da
/* Sai da leitura se encontrar um q em qualquer posição da entrada */
pilha de operadores nao estar vazia. */
if
(
*
c
==
'q'
)
break
;
while
(
desempilha
(
&
op_topo
,
pilha_operadores
))
{
if
(
!
flag_erro
)
{
/* Nesse ponto o processamento da entrada terminou (por enquanto sem erros)
e pode ser o caso da pilha de operadores nao estar vazia. */
while
(
desempilha
(
&
op_topo
,
pilha_operadores
)
&&
!
flag_erro
)
{
/* Processa os operadores que restaram na pilha. */
/* Processa os operadores que restaram na pilha. */
if
(
!
opera
(
op_topo
,
pilha_valores
))
if
(
!
opera
(
op_topo
,
pilha_valores
))
erro_aborta
(
"formato incorreto"
,
c
-
entrada
+
1
);
erro
(
"formato incorreto"
,
c
-
entrada
+
1
,
&
flag_erro
);
}
}
/* Após o processamento, o resultado final da expressao esta no topo da
/* Após o processamento, o resultado final da expressao esta no topo da
pilha de valores. */
pilha de valores. */
if
(
!
flag_erro
)
{
if
(
!
desempilha
(
&
resultado
,
pilha_valores
))
if
(
!
desempilha
(
&
resultado
,
pilha_valores
))
erro_aborta
(
"formato incorreto"
,
c
-
entrada
+
1
);
erro
(
"formato incorreto"
,
c
-
entrada
+
1
,
&
flag_erro
);
else
{
memoria
=
resultado
;
printf
(
"%.16g
\n
"
,
resultado
);
printf
(
"%.16g
\n
"
,
resultado
);
}
}
}
/* Libera a entrada e lê uma nova entrada. */
destroi_pilha
(
pilha_valores
);
destroi_pilha
(
pilha_valores
);
destroi_pilha
(
pilha_operadores
);
destroi_pilha
(
pilha_operadores
);
free
(
entrada
);
free
(
entrada
);
entrada
=
le_entrada
();
if
(
!
entrada
)
erro
(
"erro de leitura"
,
0
,
&
flag_erro
);
c
=
entrada
;
flag_erro
=
0
;
}
free
(
entrada
);
return
0
;
return
0
;
}
}
This diff is collapsed.
Click to expand it.
calculadora/makefile
+
3
−
3
View file @
0b742219
...
@@ -2,13 +2,13 @@ CC = gcc
...
@@ -2,13 +2,13 @@ CC = gcc
CFLAGS
=
-Wall
-g
-std
=
c90
CFLAGS
=
-Wall
-g
-std
=
c90
calc
:
calculadora.o libpilha.o
calc
:
calculadora.o libpilha.o
$(
CC
)
calculadora.o libpilha.o
-o
calc
$(
CC
)
calculadora.o libpilha.o
-o
calc
-lm
calculadora.o
:
libpilha.h calculadora.c
calculadora.o
:
libpilha.h calculadora.c
$(
CC
)
$(
CFLAGS
)
-c
calculadora.c
$(
CC
)
$(
CFLAGS
)
-c
calculadora.c
-lm
libpilha.o
:
libpilha.h libpilha.c
libpilha.o
:
libpilha.h libpilha.c
$(
CC
)
$(
CFLAGS
)
-c
libpilha.c
$(
CC
)
$(
CFLAGS
)
-c
libpilha.c
clean
:
clean
:
rm
-f
*
.o
rm
-f
*
.o
calc
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment