Ir ao conteúdo

C++ Laço DO WHILE + SWITCH não funciona corretamente


Ir à solução Resolvido por arfneto,

Posts recomendados

Postado

O programa compila sem mostrar erro mas, dentro do laço as funções da classe não funcionam corretamente.

Comentando o laço e fazendo as seguintes declarações fora dele, o programa faz tudo certinho.

int num = 5;

lista_encadeada->inserir_inicio(num);
lista_encadeada->mostrar();

 

mas por que com o laço que o programa simplesmente retorna Process returned -1073741819 (0xC0000005)

do{
        cout << "1. Inserir numero no inicio da lista." << endl;
        cout << "2. Inserir numero no fim da lista." << endl;
        cout << "3. Imprimir lista completa." << endl;
        cout << "0. Sair." << endl;
        cout << "Opcao: ";
        cin >> opcao;

        switch (opcao)
        {
        case 1:
            cout << "Digite um numero: ";
            cin >> num;
            lista_encadeada->inserir_inicio(num);
            cout << "Numero inserido no inicio da lista" << endl;
            break;
        case 2:
            cout << "Digite um numero: ";
            cin >> num;
            lista_encadeada->inserir_final(num);
            cout << "Numero inserido no fim da lista" << endl;
            break;
        case 3:
            lista_encadeada->mostrar();
            break;
        case 0:
            cout << "Saindo..." << endl;
            break;
        default:
            cout << "Digito Invalido!" << endl;
        }
    } while (opcao != 0);

 

Nos dois modos, o codeblocks avisa:

Citação

warning: 'lista_encadeada' may be used uninitialized in this function [-Wmaybe-uninitialized]

 

codigo completo:

#include <iostream>

using namespace std;

// classe No
class No
{
private:
	int v;
	No* prox;
public:
	No(int v) // construtor
	{
		this->v = v;
		this->prox = NULL;
	}

	int obterValor() // obtém o valor
	{
		return v;
	}

	No* obterProx() // obtém o próximo No
	{
		return prox;
	}

	void setProx(No* p) // seta o próximo No
	{
		prox = p;
	}
};

// classe Lista
class Lista
{
private:
	No* cabeca; // primeiro elemento
	No* cauda; // último elemento

public:
	Lista()
	{
		// se não passar elemento, então cabeca e cauda são NULL
		cabeca = NULL;
		cauda = NULL;
	}

	Lista(int v)
	{
		// se passar elemento, então cria novo No
		cabeca = new No(v);
		cauda = cabeca;
	}

	virtual ~Lista() // destrutor
	{
		delete cabeca;
	}

	void mostrar() // mostra todos os elementos da lista
	{
		cout << "\nImprimindo todos os elementos...\n";
		No* c = cabeca;

		if(vazia())
			cout << "A lista não possui elementos!!\n";
		else
		{
			while(c) // percorre a lista
			{
				cout << c->obterValor() << endl;
				c = c->obterProx();
			}
			cout << endl;
		}
	}

	bool vazia() // verifica se a lista está vazia
	{
		return (cabeca == NULL);
	}

	// insere no início (semelhante a push_front da list)
	void inserir_inicio(int v)
	{
		No* novo_no = new No(v);

		if(vazia())
		{
			cabeca = novo_no;
			cauda = novo_no;
		}
		else
		{
			novo_no->setProx(cabeca);
			cabeca = novo_no;
		}
	}

	// insere no final (semelhante a push_back da list)
	void inserir_final(int v)
	{
		No* novo_no = new No(v);

		if(vazia())
		{
			cabeca = novo_no;
			cauda = novo_no;
		}
		else
		{
			cauda->setProx(novo_no);
			cauda = novo_no;
		}
	}

	// retorna o tamanho da lista
	int tamanho()
	{
		if(vazia()) // se for vazia, entã retorna 0
			return 0;

		No* c = cabeca;
		int tam = 0;

		// percorre a lista
		do
		{
			c = c->obterProx();
			tam++;
		}
		while(c);

		return tam;
	}

	// verifica se um elemento existe na lista
	bool existe(int v)
	{
		No* c = cabeca;

		while(c)
		{
			if(c->obterValor() == v)
				return true;
			c = c->obterProx();
		}
		return false;
	}

	// remove da lista, remoção do final (semelhante a pop_back da list)
	void remover()
	{
		if(!vazia())
		{
			// se houver só 1 elemento
			if(cabeca->obterProx() == NULL)
				cabeca = NULL;
			else if(cabeca->obterProx()->obterProx() == NULL) // 2 elementos
				cabeca->setProx(NULL);
			else // > 2 elementos
			{
				No* ant_ant = cabeca;
				No* ant = cabeca->obterProx();
				No* corrente = cabeca->obterProx()->obterProx();

				while(corrente)
				{
					No* aux = ant;
					ant = corrente;
					ant_ant = aux;
					corrente = corrente->obterProx();
				}
				delete ant_ant->obterProx(); // libera memória
				ant_ant->setProx(NULL); // seta o prox como NULL
				cauda = ant_ant; // atualiza a cauda
			}
		}
	}
};

int main()
{
    Lista* lista_encadeada;
    int opcao;
    int num;

    ///lista_encadeada->inserir_inicio(num);
    ///lista_encadeada->mostrar();

    do{
        cout << "1. Inserir numero no inicio da lista." << endl;
        cout << "2. Inserir numero no fim da lista." << endl;
        cout << "3. Imprimir lista completa." << endl;
        cout << "0. Sair." << endl;
        cout << "Opcao: ";
        cin >> opcao;

        switch (opcao)
        {
        case 1:
            cout << "Digite um numero: ";
            cin >> num;
            lista_encadeada->inserir_inicio(num);
            cout << "Numero inserido no inicio da lista" << endl;
            break;
        case 2:
            cout << "Digite um numero: ";
            cin >> num;
            lista_encadeada->inserir_final(num);
            cout << "Numero inserido no fim da lista" << endl;
            break;
        case 3:
            lista_encadeada->mostrar();
            break;
        case 0:
            cout << "Saindo..." << endl;
            break;
        default:
            cout << "Digito Invalido!" << endl;
        }
    } while (opcao != 0);

    return 0;
}

 

  • Curtir 1
  • Solução
Postado
1 hora atrás, Velorys disse:

Nos dois modos, o codeblocks avisa:

 

E não é que é verdade? 
 

 

Acabou de declarar um ponteiro para Lista. Não tem nada lá. Veja:

 

    Lista* lista_encadeada;
    int    opcao;
    int    num;

    /// lista_encadeada->inserir_inicio(num);
    /// lista_encadeada->mostrar();

    do {
        cout << "1. Inserir numero no inicio da lista." << endl;
        cout << "2. Inserir numero no fim da lista." << endl;
        cout << "3. Imprimir lista completa." << endl;
        cout << "0. Sair." << endl;
        cout << "Opcao: ";
        cin >> opcao;

        switch (opcao)
        {
            case 1:
                cout << "Digite um numero: ";
                cin >> num;
                lista_encadeada->inserir_inicio(num);
                cout << "Numero inserido no inicio da lista" << endl;
                break;

 

Porque está usando ponteiros e essas funções todas? Está programando em C++. Não deve usar isso. Usaria em C, talvez. C++ tem listas que pode usar direto, basta declarar. Talvez pudesse dar uma olhada nos métodos de list e copiar.

 

De todo modo, está muito errado escrever desse modo.

 

O mais importante:

 

  • é raro precisar de ponteiros assim em C++.
     
  • TODAS essas funções que escreveu são relativas à Lista. São métodos da classe. Esse é todo o sentido de usar uma linguagem dessas: tudo fica MUITO mais fácil. Use como tal.
     
  • Use arquivos separados para as classes/ Há uma razão para todo mundo usar isso e o próprio IDE criar assim. Se fizer como fez só vai ter mais trabalho
     
  • Sua lista não tem um campo de tamanho? Porque?

 

Entenda que se tem tantas funções devia ter uma também para o menu, que retornasse a opção...

 

 

 

 

       int obterValor()  // obtém o valor
        {
            return v;
        }

        No* obterProx()  // obtém o próximo No

 

Não use comentários com acentos. Recomendo evitar esse tipo de comentário óbvio: dá pra imaginar o que faz obterValor(). Comente sobe o que está fazendo e como está fazendo.

obterProx() e SetProx() não são funções do nó e sim da lista... 

  • Curtir 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!