Ir ao conteúdo
  • Cadastre-se

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


Velorys
Ir à solução Resolvido por arfneto,

Posts recomendados

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
Link para o comentário
Compartilhar em outros sites

  • Solução
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
Link para o comentário
Compartilhar em outros sites

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...