Most of your compile errors are that sometimes you use Pilha
and sometimes use Pilha *
. Always use Pilha *
.
See your battery-building function:
Pilha create() {
Pilha p;
p->topo = -1;
p->elementos[MAX];
}
The use of ->
is used to access pointers, so p
should be a pointer. In addition, you should return a pointer (as stated in item 1). If p
is not a pointer, it will be allocated on the stack and deallocated when the function finishes, so you have to allocate it in the heap with malloc
. You should then do this:
Pilha *create() {
Pilha *p = (Pilha *) malloc(sizeof(Pilha));
p->topo = -1;
p->elementos[MAX];
return p;
}
However, this p->elementos[MAX];
does nothing. What you wanted in your place was this:
for (int i = 0; i < MAX; i++) {
p->elementos[i] = 0;
}
Its function push
is void
, but it has return 0;
and return 1;
inside. Let's return int
.
In your function push
we have this:
char p->elementos[p->topo] = c;
This char
up front is useless. Take it out.
With the above changes, in the file lisp.c
, these lines:
Pilha lisp = create();
push(&lisp, Fr[i]);
pop(&lisp);
They start to look like this:
Pilha *lisp = create();
push(lisp, Fr[i]);
pop(lisp);
With these changes, your code should already compile. But there are still other errors:
See your size
function:
int size(Pilha p) {
int tam;
tam = p->topo; + 1;
return tam;
}
About *
before p
, I've spoken before. But look at the tam = p->topo; + 1;
line - there's an extra semicolon in there! Also, you do not need this variable if you're already going to return immediately. So you can simplify it all like this:
int size(Pilha *p) {
return p->topo + 1;
}
Let's see its isEmpty
function:
int isEmpty(Pilha p){
if (p->topo == -1)
return 1;
else
return 0;
}
The result of a comparison with ==
is always 1 when it is true and 0 when it is not. So, if the result of the comparison is 1, one should return 1, if it is 0, one should return 0. Therefore, it is simpler just to return the comparison result directly:
int isEmpty(Pilha *p) {
return p->topo == -1;
}
The same can be done in your isFull
function.
If you have a if
that always ends with a return
, else
is unnecessary. For example:
if (condição) {
return alguma_coisa;
} else {
blablabla
}
It's equivalent to this:
if (condição) {
return alguma_coisa;
}
blablabla
With this in mind, you can simplify your push
function by deleting else
from it.
The case of the charlvl
variable is curious. This is a 10-position array, but you only use position 1. Therefore, it is best to declare this as a char
. In addition, there is a printf
where you print charlvl[1]
using %s
. You should use %c
. Also, unless the list empties before it reaches the position of the searched character, we will have charlvl[1]
will Fr[idx - 1]
. Therefore, it is best to change this variable to type char
and assign Fr[idx - 1]
to it before for
.
You are decreasing idx
until when it is 1, you run lvl = size(lisp);
. The idx
will have the value 1 only when i == lvl - 1
. Therefore, it is easier for you to put this condition in if
, not change the variable lvl
never and get rid of else
.
You are asked to check characters at a certain level. In fact, what you look at is in a certain position in the sentence. Therefore, the corresponding message in printf
must be changed. The variable idx
is the position of the character in the sentence.
A very important thing in programming is to give appropriate names to variables. Especially if you're in college, why sometimes from time to time some teachers get on their feet and even score points if the program has variables with inappropriate or unmanned names. So I suggest you rename Fr
to frase
, QtCar
to quantidade
, idx
to posicao
, lvl
to nivel
and charlvl
to procurado
.
The printf("A lista nao esta balanceada");
within for
of main
should not be there. It already tells you whether or not the list is balanced at the end. However, the point here is to interrupt the whole analysis. So an auxiliary variable that indicates whether or not the analysis was aborted at this point becomes necessary.
You do not need stdio.h
within pilha.c
nor pilha.h
. It also does not need stdlib.h
within lisp.c
.
Here's how your program looks:
pilha.h
:
#ifndef PILHA_H_
#define PILHA_H_
#define MAX 100
typedef struct pilha {
char elementos[MAX];
int topo;
} Pilha;
Pilha *create(); //cria pilha
char pop(Pilha *p); //desempilha
int push(Pilha *p, char c); //empilha
int isEmpty(Pilha *p); //verifica pilha vazia
int isFull(Pilha *p); //verifica pilha cheia
int size(Pilha *p); //verifica tamanho da pilha
#endif
pilha.c
:
#include "pilha.h"
#include <stdlib.h>
Pilha *create() {
Pilha *p = (Pilha *) malloc(sizeof(Pilha));
p->topo = -1;
for (int i = 0; i < MAX; i++) {
p->elementos[i] = 0;
}
return p;
}
int isFull(Pilha *p) {
return p->topo == MAX - 1;
}
char pop(Pilha *p) {
char c = p->elementos[p->topo];
p->topo--;
return c;
}
int push(Pilha *p, char c) {
if (isFull(p)) {
return 0;
}
p->topo++;
p->elementos[p->topo] = c;
return 1;
}
int isEmpty(Pilha *p) {
return p->topo == -1;
}
int size(Pilha *p) {
return p->topo + 1;
}
lisp.c
:
#include <stdio.h>
#include "pilha.h"
int main() {
int quantidade, posicao, nivel;
printf("Quantidade de caracteres:\n");
scanf("%d", &quantidade);
char frase[quantidade];
printf("Frase:\n");
scanf("%s", frase);
printf("Verificar caracter na posicao?\n");
scanf("%d", &posicao);
char procurado = frase[posicao - 1];
int abortado = 0;
Pilha *lisp = create();
for (int i = 0; i < quantidade; i++) {
if (frase[i] == '(') {
push(lisp, frase[i]);
}
if (frase[i] == ')') {
if (isEmpty(lisp)) {
abortado = 1;
break;
} else {
pop(lisp);
}
}
if (i == posicao - 1) {
nivel = size(lisp);
}
}
if (!abortado && isEmpty(lisp)) {
printf("A lista esta balanceada! %c está no nivel %d", procurado, nivel);
} else {
printf("A lista nao esta balanceada");
}
}
Your program should then work like this.
However, there is still a little secret: Since the only thing you stack up is parenthesis, you can then delete the stack and swap it for a counter. This shows that this exercise does not really need to use a stack to check if the parentheses are balanced and a simpler solution exists. This also means that your teacher should brainstorm another exercise for piles that could not be solved without using them. Here's what your program looks like without batteries:
#include <stdio.h>
int main() {
int quantidade, posicao, nivel;
printf("Quantidade de caracteres:\n");
scanf("%d", &quantidade);
char frase[quantidade];
printf("Frase:\n");
scanf("%s", frase);
printf("Verificar caracter na posicao?\n");
scanf("%d", &posicao);
char procurado = frase[posicao - 1];
int abortado = 0;
int abertos = 0;
for (int i = 0; i < quantidade; i++) {
if (frase[i] == '(') {
abertos++;
}
if (frase[i] == ')') {
if (abertos == 0) {
abortado = 1;
break;
} else {
abertos--;
}
}
if (i == posicao - 1) {
nivel = abertos;
}
}
if (!abortado && abertos == 0) {
printf("A lista esta balanceada! %c está no nivel %d", procurado, nivel);
} else {
printf("A lista nao esta balanceada");
}
}