Ir ao conteúdo
  • Cadastre-se

C Listas em C que utilize estrutura de dados


Vagabond1001

Posts recomendados

Olá,

Alguém poderia me ajudar a ter um caminho aqui, no dia em que foi dados o conteúdo minha avó faleceu e não pude aprender esse conteudo de "Listas" e estou bem perdido.

Mesmo assistindo video aulas esta difícil absorver, se alguem puder me orientar ficaria grato.

As imagens são somente exemplos do conteudo apresentado.

 

Dado a estrutura básica para a construção de uma lista estática, pede-se que seja criada uma função responsável por inserir um elemento no final da lista.

Essa função precisará receber como parâmetro a lista (ponteiro) e o elemento a ser inserido.
Dentro da função main, será necessário chamar a função para inserir elemento ao final e, logo em seguida, mostrar o resultado da função que recupera o tamanho da lista.

 

Este foi o codigo:

#include <stdlib.h>
#include <stdio.h>

int main(){
	
	struct aluno{
		int matricula;
		char nome[100];
		float n1,n2,n3;
	};
	

	struct lista{
		int qtde;
		struct aluno a[3];
	};
	
	
	struct lista* cria_lista()
	{
		struct lista *li;
		li = (struct lista *)malloc(sizeof(struct lista));
		if(li != NULL){
			li->qtde = 0;
		}
		
		return li;
	}
	
	
	// verificar se a lista é vazia
	int lista_vazia(struct lista *li){
	if(li != NULL){
		return (li->qtde == 0);
	}
	else{
	return -1;
	}


	}
	
	
	// verificar se a lista esta cheia 
	int lista_cheia(struct lista *li){
		if(li != NULL){
			return (li -> qtde == 3);
		}
		else 
		{
		
		
		return - 1;
}
	}
	
	struct li *li;
	li = cria_lista();
	
	
	
	
	printf("\n lista vazia? %d", lista_vazia(li));
	printf("\n lista cheia? %d", lista_cheia(li));
	
	
	
}
//criar função de elemento que adiciona elemento ao final da lista

es1.JPG

es2.JPG

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//Definindo a estrutura da lista 
struct no {
  int dado;
  struct no * proximo;
};

//Definindo variáveis 
typedef no * ptr_no;
ptr_no lista;
int op;

//Prototipação 
void menu_mostrar();
void menu_selecionar(int op);
void lista_inserir(ptr_no lista);
void lista_remover(ptr_no lista);
void lista_mostrar(ptr_no lista);

//Função Principal 
int main() {

  //Inicializando máquina de números aleatórios   
  srand(time(NULL));
  op = 1;

  //Criando o primeiro nó da lista  
  lista = (ptr_no) malloc(sizeof(no));
  lista -> dado = 0;
  lista -> proximo = NULL;

  //Laço principal  
  while (op != 0) {
    system("cls");
    menu_mostrar();
    scanf("%d", & op);
    menu_selecionar(op);
  }
  system("Pause");
  return (0);
}

//Mostra o menu de opções 
void menu_mostrar() {
  lista_mostrar(lista);
  printf("\n\nEscolha uma das opções:\n");
  printf("1 - Inserir no final da Lista\n");
  printf("2 - Remover um item da Lista\n");
  printf("0 - Sair\n\n");
}

//Executa a opção escolhida no menu 
void menu_selecionar(int op) {
  switch (op) {
  case 1:
    lista_inserir(lista);
    break;
  case 2:
    lista_remover(lista);
    break;
  }
}

//Insere um elemento no final da Lista 
void lista_inserir(ptr_no lista) {
  while (lista -> proximo != NULL) {
    lista = lista -> proximo;
  }
  lista -> proximo = (ptr_no) malloc(sizeof(no));
  lista = lista -> proximo;
  lista -> dado = rand() % 100;
  lista -> proximo = NULL;
}

//Remove um elemento da Lista 
void lista_remover(ptr_no lista) {
  int dado;
  ptr_no atual;
  atual = (ptr_no) malloc(sizeof(no));
  printf("\n\nEscolha uma dos itens:\n");
  scanf("%d", & dado);
  while ((lista -> dado != dado)) {
    if (lista -> proximo == NULL) {
      break;
    }
    atual = lista;
    lista = lista -> proximo;
  }
  if (lista -> dado == dado) {
    atual -> proximo = lista -> proximo;
  }
}

//Desenha o conteúdo da Lista na tela 
void lista_mostrar(ptr_no lista) {
  system("cls");
  while (1) {
    printf("%d, ", lista -> dado);
    if (lista -> proximo == NULL) {
      break;
    }
    lista = lista -> proximo;
  }
}

//Desenha o conteúdo da Lista na tela 
void lista_mostrar_2(ptr_no lista) {
  system("cls");
  while (lista -> proximo != NULL) {
    printf("%d, ", lista -> dado);
    lista = lista -> proximo;
  }
  printf("%d, ", lista -> dado);
}

 

Link para o comentário
Compartilhar em outros sites

Em 26/04/2020 às 20:41, herbertbahia disse:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//Definindo a estrutura da lista 
struct no {
  int dado;
  struct no * proximo;
};

//Definindo variáveis 
typedef no * ptr_no;
ptr_no lista;
int op;

//Prototipação 
void menu_mostrar();
void menu_selecionar(int op);
void lista_inserir(ptr_no lista);
void lista_remover(ptr_no lista);
void lista_mostrar(ptr_no lista);

//Função Principal 
int main() {

  //Inicializando máquina de números aleatórios   
  srand(time(NULL));
  op = 1;

  //Criando o primeiro nó da lista  
  lista = (ptr_no) malloc(sizeof(no));
  lista -> dado = 0;
  lista -> proximo = NULL;

  //Laço principal  
  while (op != 0) {
    system("cls");
    menu_mostrar();
    scanf("%d", & op);
    menu_selecionar(op);
  }
  system("Pause");
  return (0);
}

//Mostra o menu de opções 
void menu_mostrar() {
  lista_mostrar(lista);
  printf("\n\nEscolha uma das opções:\n");
  printf("1 - Inserir no final da Lista\n");
  printf("2 - Remover um item da Lista\n");
  printf("0 - Sair\n\n");
}

//Executa a opção escolhida no menu 
void menu_selecionar(int op) {
  switch (op) {
  case 1:
    lista_inserir(lista);
    break;
  case 2:
    lista_remover(lista);
    break;
  }
}

//Insere um elemento no final da Lista 
void lista_inserir(ptr_no lista) {
  while (lista -> proximo != NULL) {
    lista = lista -> proximo;
  }
  lista -> proximo = (ptr_no) malloc(sizeof(no));
  lista = lista -> proximo;
  lista -> dado = rand() % 100;
  lista -> proximo = NULL;
}

//Remove um elemento da Lista 
void lista_remover(ptr_no lista) {
  int dado;
  ptr_no atual;
  atual = (ptr_no) malloc(sizeof(no));
  printf("\n\nEscolha uma dos itens:\n");
  scanf("%d", & dado);
  while ((lista -> dado != dado)) {
    if (lista -> proximo == NULL) {
      break;
    }
    atual = lista;
    lista = lista -> proximo;
  }
  if (lista -> dado == dado) {
    atual -> proximo = lista -> proximo;
  }
}

//Desenha o conteúdo da Lista na tela 
void lista_mostrar(ptr_no lista) {
  system("cls");
  while (1) {
    printf("%d, ", lista -> dado);
    if (lista -> proximo == NULL) {
      break;
    }
    lista = lista -> proximo;
  }
}

//Desenha o conteúdo da Lista na tela 
void lista_mostrar_2(ptr_no lista) {
  system("cls");
  while (lista -> proximo != NULL) {
    printf("%d, ", lista -> dado);
    lista = lista -> proximo;
  }
  printf("%d, ", lista -> dado);
}

 

Obrigado amigo, sabe me dizer se essa função recebe como parâmetro a lista (ponteiro) e o elemento a ser inserido?

 

Obrigado!

adicionado 22 minutos depois
Em 27/04/2020 às 10:34, Rafael Melo disse:

 

Obrigado amigo, sabe me dizer se essa função recebe como parâmetro a lista (ponteiro) e o elemento a ser inserido?

 

Obrigado!

Outra coisa amigo, por que este código não executa na extensão em C?

Pois esta como CPP

Link para o comentário
Compartilhar em outros sites

estamos fazendo a mesma matéria no mesmo periodo em faculdades diferentes, eu ainda nao tentei compilar esse exercico em c.

eu ja vi ponteiros a estruturas e estruturas que contem ponteiros mas nunca vi um algoritmo com os dois juntos.

sei que dizer 

lista-> dado = rand() % 100;
eu estou dizendo 
lista.dado = rand() % 100;

 

16 horas atrás, Rafael Melo disse:

Essa função precisará receber como parâmetro a lista (ponteiro) e o elemento a ser inserido.

podemos ver que na funcao inserir tem os parametros da lista do ponteiro dentro dos parenteses e o elemento no caso é a aleatorio.

void lista_inserir(ptr_no lista)

 

Link para o comentário
Compartilhar em outros sites

lista-> dado = rand() % 100;

// eu estou dizendo 

lista.dado = rand() % 100;

 

Esses operadores  -> e . são similares. Apenas você usa -> quando o que está à esquerda é um endereço e usa . quando é algo estático. Considere essa declaração

Lista	a_propria;
Lista*  lista = &a_propria;

você pode escrever
 

a_propria.dado = rand() % 100; 

// ou

lista->dado = rand()%100;

// ou ainda

(*lista).dado = rand() % 100;

E no último caso precisa dos parenteses.

 

 

 

 

  • Obrigado 2
Link para o comentário
Compartilhar em outros sites

33 minutos atrás, arfneto disse:

lista-> dado = rand() % 100;

// eu estou dizendo 

lista.dado = rand() % 100;

 

Esses operadores  -> e . são similares. Apenas você usa -> quando o que está à esquerda é um endereço e usa . quando é algo estático. Considere essa declaração


Lista	a_propria;
Lista*  lista = &a_propria;

você pode escrever
 


a_propria.dado = rand() % 100; 

// ou

lista->dado = rand()%100;

// ou ainda

(*lista).dado = rand() % 100;

E no último caso precisa dos parenteses.

 

 

 

 

 

Obrigado, ele esta pedindo para dar continuidade no codigo com a LISTA naquele codigo que postei.

Vou ver o que consigo fazer

Link para o comentário
Compartilhar em outros sites

2 minutos atrás, herbertbahia disse:

🙃 o nó maior é na nossa cabeça

 

No caso de inserir numa lista tem duas soluções seguras e comuns:

Lista* inserir(void* elemento, Lista* a_lista_mesmo);
void inserir(void* elemento, Lista** a_lista_mesmo);

E tem uma outra decisão: você vai inserir um elemento que vai ser um nó na lista então sempre passa pela cabeça se o parâmetro vai ser um Node mesmo ou um elemento...

 

Entenda que listas são absurdamente comuns e úteis em programas. Então você não quer programar isso toda hora. Por isso você escreve um troço caprichado e genérico e usa sempre o mesmo. 
 

Não vai querer mexer em um programa de lista ligada porque está usando uma lista de cadastro ao invés de uma lista de int. Na próxima semana vai ser uma struct de música, depois um livro...

 

O que você faz é compilar isso uma vez só. Gera um arquivo .lib ou .dll e nos seus 325 programas que usam lista você só volta a mexer nisso se achar um erro. Nem vai querer ver o fonte mais. Assim é.

 

Veja a estrutura abaixo e pense nas consequências:

 

#pragma once
#define _CRT_SECURE_NO_WARNINGS

struct no
{
    void*      item;
    struct no* proxima;
    struct no* anterior;
};  // no
typedef struct no Node;

struct a_propria_lista
{
    char*     nome;
    unsigned  quantos;
    unsigned  maximo;
    Node*     inicio;
    Node*     fim;
};
typedef struct a_propria_lista Lista;

Lista*      apagar(Lista*);
Lista*      criar(const char*);
int         define_maximo(Lista* l, const unsigned);
Lista*      inserir_na_ordem(void*, Lista*, int(*)(void*, void*));
Lista*      inserir_no_inicio(void*, Lista*);
Lista*      inserir_no_final(void*, Lista*);
int         listar(Lista*);
int         listar_do_seu_jeito(Lista*, int(*)(void*));
int         maximo(Lista*);
Node*       primeiro(Lista*);
Lista*      remover(void*, Lista*);
int         tamanho(Lista*);
Node*       ultimo(Lista*);
int         vazia(Lista*);

Você pode programar só o que usa, claro. Mas percebe que esses dados são genéricos? Cuidam de listas de qualquer coisa. E você pode ter várias listas no mesmo programa, cada uma com um conteúdo distinto. E elas tem até um nominho! Meigas.

 

E preste especial atenção a essas duas rotinas:

 

Lista*      inserir_na_ordem(void*, Lista*, int(*)(void*, void*));

int         listar_do_seu_jeito(Lista*, int(*)(void*));

Elas permitem que você por exemplo se tiver uma estrutura de livro insira na lista por ordem de autor, título, ISBN, data de publicação, qualquer coisa, sem mexer no código da lista. Ou liste os caras de uma maneira resumida, ou algo elaborado indo consultar seu estoque para ver quantos exemplares tem na loja, Sem mexer em uma linha sequer

 

Você escreve uma função que compara os caras no primeiro caso, uma que formata a listagem de um item no segundo, e a rotina faz o resto. 

 

Recomendo que se certifique de entender essa parada. É um conceito muito importante, como deve imaginar.

 

 

Sobre decidir entre as duas opções:

 

Em geral o ponteiro para a lista foi criado pela rotina que cria a lista, e está disponível em main(). Se você passar o ponteiro apenas para dentro de insere() por exemplo, e mudar o endereço de início, ele precisa voltar alterado para main(). Então ou você escreve

 

Lista* lista = insere(Item* dado, Lista* lista);

ou

insere(Item* dado, Lista** lista);

para ter o ponteiro lista  atualizado na volta, ou ele vai sumir lá dentro de insere()

 

Em geral é melhor usar a primeira opção porque assim você cria um hábito, é mais difícil de esquer um asterisco, e ainda pode usar o valor de retorno em expressões...

 

 

 

 

adicionado 0 minutos depois
4 minutos atrás, Rafael Melo disse:

 

Obrigado, ele esta pedindo para dar continuidade no codigo com a LISTA naquele codigo que postei.

Vou ver o que consigo fazer

 

Boa sorte. Veja o que expliquei sobre a passagem de parâmetros. É importante

Link para o comentário
Compartilhar em outros sites

18 minutos atrás, arfneto disse:

 

No caso de inserir numa lista tem duas soluções seguras e comuns:


Lista* inserir(void* elemento, Lista* a_lista_mesmo);
void inserir(void* elemento, Lista** a_lista_mesmo);

E tem uma outra decisão: você vai inserir um elemento que vai ser um nó na lista então sempre passa pela cabeça se o parâmetro vai ser um Node mesmo ou um elemento...

 

Entenda que listas são absurdamente comuns e úteis em programas. Então você não quer programar isso toda hora. Por isso você escreve um troço caprichado e genérico e usa sempre o mesmo. 
 

Não vai querer mexer em um programa de lista ligada porque está usando uma lista de cadastro ao invés de uma lista de int. Na próxima semana vai ser uma struct de música, depois um livro...

 

O que você faz é compilar isso uma vez só. Gera um arquivo .lib ou .dll e nos seus 325 programas que usam lista você só volta a mexer nisso se achar um erro. Nem vai querer ver o fonte mais. Assim é.

 

Veja a estrutura abaixo e pense nas consequências:

 


#pragma once
#define _CRT_SECURE_NO_WARNINGS

struct no
{
    void*      item;
    struct no* proxima;
    struct no* anterior;
};  // no
typedef struct no Node;

struct a_propria_lista
{
    char*     nome;
    unsigned  quantos;
    unsigned  maximo;
    Node*     inicio;
    Node*     fim;
};
typedef struct a_propria_lista Lista;

Lista*      apagar(Lista*);
Lista*      criar(const char*);
int         define_maximo(Lista* l, const unsigned);
Lista*      inserir_na_ordem(void*, Lista*, int(*)(void*, void*));
Lista*      inserir_no_inicio(void*, Lista*);
Lista*      inserir_no_final(void*, Lista*);
int         listar(Lista*);
int         listar_do_seu_jeito(Lista*, int(*)(void*));
int         maximo(Lista*);
Node*       primeiro(Lista*);
Lista*      remover(void*, Lista*);
int         tamanho(Lista*);
Node*       ultimo(Lista*);
int         vazia(Lista*);

Você pode programar só o que usa, claro. Mas percebe que esses dados são genéricos? Cuidam de listas de qualquer coisa. E você pode ter várias listas no mesmo programa, cada uma com um conteúdo distinto. E elas tem até um nominho! Meigas.

 

E preste especial atenção a essas duas rotinas:

 


Lista*      inserir_na_ordem(void*, Lista*, int(*)(void*, void*));

int         listar_do_seu_jeito(Lista*, int(*)(void*));

Elas permitem que você por exemplo se tiver uma estrutura de livro insira na lista por ordem de autor, título, ISBN, data de publicação, qualquer coisa, sem mexer no código da lista. Ou liste os caras de uma maneira resumida, ou algo elaborado indo consultar seu estoque para ver quantos exemplares tem na loja, Sem mexer em uma linha sequer

 

Você escreve uma função que compara os caras no primeiro caso, uma que formata a listagem de um item no segundo, e a rotina faz o resto. 

 

Recomendo que se certifique de entender essa parada. É um conceito muito importante, como deve imaginar.

 

 

Sobre decidir entre as duas opções:

 

Em geral o ponteiro para a lista foi criado pela rotina que cria a lista, e está disponível em main(). Se você passar o ponteiro apenas para dentro de insere() por exemplo, e mudar o endereço de início, ele precisa voltar alterado para main(). Então ou você escreve

 


Lista* lista = insere(Item* dado, Lista* lista);

ou


insere(Item* dado, Lista** lista);

para ter o ponteiro lista  atualizado na volta, ou ele vai sumir lá dentro de insere()

 

Em geral é melhor usar a primeira opção porque assim você cria um hábito, é mais difícil de esquer um asterisco, e ainda pode usar o valor de retorno em expressões...

 

 

 

 

adicionado 0 minutos depois

 

Boa sorte. Veja o que expliquei sobre a passagem de parâmetros. É importante

Esse professor quebra as pernas pois o codigo dele parece ser diferente e dar continuidade nisso é complicado, ainda mais que não pude assistir a aula. Mas vou meter as caras aqui e tentar fazer, obrigado pela explicação.

adicionado 1 minuto depois
1 hora atrás, herbertbahia disse:

estamos fazendo a mesma matéria no mesmo periodo em faculdades diferentes, eu ainda nao tentei compilar esse exercico em c.

eu ja vi ponteiros a estruturas e estruturas que contem ponteiros mas nunca vi um algoritmo com os dois juntos.

sei que dizer 


lista-> dado = rand() % 100;
eu estou dizendo 
lista.dado = rand() % 100;

 

podemos ver que na funcao inserir tem os parametros da lista do ponteiro dentro dos parenteses e o elemento no caso é a aleatorio.


void lista_inserir(ptr_no lista)

 

Pois é, eu preciso dar continuidade nesse codigo que postei, o seu que me passou esta perfeito, mas como não pude assistir o conteudo estou perdido. Mas vamos lá kkk

Link para o comentário
Compartilhar em outros sites

6 minutos atrás, Rafael Melo disse:

Pois é, eu preciso dar continuidade nesse codigo que postei, o seu que me passou esta perfeito, mas como não pude assistir o conteudo estou perdido. Mas vamos lá kkk

 

Pergunte algo objetivo para que alguém possa te ajudar. 

 

Recomendo escrever primeiro a função que lista, depois a que cria e depois a que insere e partir daí. Poste o código.

Link para o comentário
Compartilhar em outros sites

1 minuto atrás, arfneto disse:

 

Pergunte algo objetivo para que alguém possa te ajudar. 

 

Recomendo escrever primeiro a função que lista, depois a que cria e depois a que insere e partir daí. Poste o código.

#include <stdlib.h>
#include <stdio.h>

int main(){
	
	struct aluno{
		int matricula;
		char nome[100];
		float n1,n2,n3;
	};
	

	struct lista{
		int qtde;
		struct aluno a[3];
	};
	
	
	struct lista* cria_lista()
	{
		struct lista *li;
		li = (struct lista *)malloc(sizeof(struct lista));
		if(li != NULL){
			li->qtde = 0;
		}
		
		return li;
	}
	
	
	// verificar se a lista é vazia
	int lista_vazia(struct lista *li){
	if(li != NULL){
		return (li->qtde == 0);
	}
	else{
	return -1;
	}


	}
	
	
	// verificar se a lista esta cheia 
	int lista_cheia(struct lista *li){
		if(li != NULL){
			return (li -> qtde == 3);
		}
		else 
		{
		
		
		return - 1;
}
	}
	
	struct li *li;
	li = cria_lista();
	
	
	
	
	printf("\n lista vazia? %d", lista_vazia(li));
	printf("\n lista cheia? %d", lista_cheia(li));
	
	
	
}
//criar função de elemento que adiciona elemento ao final da lista

Ja tinha postado o codigo, mas é esse ai de cima.

O  enunciado da questão é:

 

Dado a estrutura básica para a construção de uma lista estática, pede-se que seja criada uma função responsável por inserir um elemento no final da lista.

Essa função precisará receber como parâmetro a lista (ponteiro) e o elemento a ser inserido.
Dentro da função main, será necessário chamar a função para inserir elemento ao final e, logo em seguida, mostrar o resultado da função que recupera o tamanho da lista.

 

Ai tenho que dá continuidade nesse codigo como se pede a questão a cima.

Preciso de uma luz pois estou perdido.

 

Link para o comentário
Compartilhar em outros sites

?

 

Mas então você não fez nadinha certo?

 

Qual a sua dúvida inicial? Leu o que o pessoal está sugerindo?

 

Sabe o que é uma lista? tem noção de como alocar memória, liberar memória? criar uma struct?

 

Você tem um livro-texto? Sua escola não adota um? 

 

A lista que postou 

    struct aluno
    {
		int matricula;
		char nome[100];
		float n1,n2,n3;
	};
	
    struct lista
    {
		int qtde;
		struct aluno a[3];
	};
	
	

Tem uma struct lista que sequer tem um ponteiro. e dentro dela 3 singelos alunos. Porque só 3? Como vai percorrer os alunos de uma lista que sequer tem um ponteiro? Vai usar o índice da struct? OK. Mas só tem 3...

 

 

Veja uma declaração de lista de um programa comum:
 


struct no
{
    void*      item;
    struct no* proxima;
    struct no* anterior;
};  // no
typedef struct no Node;

struct a_propria_lista
{
    char*     nome;
    unsigned  quantos;
    unsigned  maximo;
    Node*     inicio;
    Node*     fim;
};
typedef struct a_propria_lista Lista;

E pense nisso...


No segundo caso você pode de um item, um Aluno digamos, ir para o anterior ou o próximo...

Na lista tem a quantidade, o limite e endereço de início e fim...

 

 

 

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

Em 27/04/2020 às 15:14, arfneto disse:

?

 

Mas então você não fez nadinha certo?

 

Qual a sua dúvida inicial? Leu o que o pessoal está sugerindo?

 

Sabe o que é uma lista? tem noção de como alocar memória, liberar memória? criar uma struct?

 

Você tem um livro-texto? Sua escola não adota um? 

 

A lista que postou 


    struct aluno
    {
		int matricula;
		char nome[100];
		float n1,n2,n3;
	};
	
    struct lista
    {
		int qtde;
		struct aluno a[3];
	};
	
	

Tem uma struct lista que sequer tem um ponteiro. e dentro dela 3 singelos alunos. Porque só 3? Como vai percorrer os alunos de uma lista que sequer tem um ponteiro? Vai usar o índice da struct? OK. Mas só tem 3...

 

 

Veja uma declaração de lista de um programa comum:
 



struct no
{
    void*      item;
    struct no* proxima;
    struct no* anterior;
};  // no
typedef struct no Node;

struct a_propria_lista
{
    char*     nome;
    unsigned  quantos;
    unsigned  maximo;
    Node*     inicio;
    Node*     fim;
};
typedef struct a_propria_lista Lista;

E pense nisso...


No segundo caso você pode de um item, um Aluno digamos, ir para o anterior ou o próximo...

Na lista tem a quantidade, o limite e endereço de início e fim...

 

 

 

Cara quem passou isso foi o professor, eu estou postando aqui para saber como dar continuidade.

Estou fazendo com outra pessoa que sabe programar um pouco mas nem ele sabe por onde ir, eu não sou programador e estou com dificuldades nessa materia devido a quarentena, pois não esta sendo ensinado praticamente nada.

Mesmo pesquisando esta difícil, por isso estou pedindo um luz de como dar continuidade nesse codigo. 

Eu li o que postou mas algumas coisas não sei como fazer.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

5 horas atrás, isrnick disse:

Esse outro tópico lida com o mesmo exercício:

 

 

Amigo me tira uma duvida, esse meu codigo esta de acordo com o solicitado?

Eu li o post que você mencionou mas ainda assim estou na duvida se esta certo.

#include <stdio.h>
#include <stdlib.h>



struct aluno{
	int matricula;
	char nome[100];
	float n1, n2, n3;
};

typedef struct no No;
struct no {
	int num;
	struct no *prox;
} ;


No* criar_no(){
	No* no = (No*)malloc	(sizeof(No));
	return no;
}


inserir_fim(No* Lista, int dado){
	No *no = criar_no(0);
	no->num = dado;
	
	if(Lista == NULL){
		no->prox= NULL;
		Lista =no;
	}
	else{
		No* aux =Lista;
		while(aux->prox != NULL){
		
		aux=aux->prox;
		
	}
	
	no->prox= NULL;
	aux->prox = no;
	}
	
	
}



void imprimir(No* Lista){
	No* aux = Lista;
	while(aux != NULL){
		printf("%d", aux->num);
		aux=aux ->prox;
		
	}
	
}


int main(){
	No* lista = NULL;
	lista=inserir_fim(lista, 5 );
	lista=inserir_fim(lista, 8 );
	imprimir(lista);
	return 0;
}

 

  • Confuso 1
Link para o comentário
Compartilhar em outros sites

14 horas atrás, Rafael Melo disse:

Amigo me tira uma duvida, esse meu codigo esta de acordo com o solicitado?

 

Se entendi corretamente, era para usar a estrutura inclusa no código já fornecido, e apenas fazer uma função para inserir um elemento no fim da lista.

 

Então se é isso mesmo, eu diria que esse código não atende o que foi solicitado, pois você alterou o código original, e transformou a lista, que era sequencial estática, em uma lista ligada, e então você fez uma função para inserir no fim da lista ligada. Note também que o programa como está nem se quer usa a struct aluno.

Link para o comentário
Compartilhar em outros sites

19 minutos atrás, isrnick disse:

 

Se entendi corretamente, era para usar a estrutura inclusa no código já fornecido, e apenas fazer uma função para inserir um elemento no fim da lista.

 

Então se é isso mesmo, eu diria que esse código não atende o que foi solicitado, pois você alterou o código original, e transformou a lista, que era sequencial estática, em uma lista ligada, e então você fez uma função para inserir no fim da lista ligada. Note também que o programa como está nem se quer usa a struct aluno.

Exato eu li o post que me mencionou e peguei um conteudo postado pelo professor.

Vi que você tinha postado uma parte de inserir, mas olha como ficou:

Inserir as funções que fica difícil, pode me ajudar?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>



struct aluno {

    int matricula;
    char nome[100];
    float n1, n2,n3;
};

struct lista {

    int qtde;
    struct aluno a[3];
};
//cria a lista
struct lista* cria_lista(){

    struct lista *li;
    li=(struct lista *)malloc(sizeof(struct lista));

    if(li != NULL)
        li->qtde = 0;

    return li;
};
// verifica se a lista é vazia
int lista_vazia(struct lista *li)
{
    if(li != NULL)
        return (li->qtde ==0);
    else
        return -1;
};

// verifica se a lista esta cheia 
int lista_cheia(struct lista *li)
{
  if(li !=NULL)
        return (li->qtde == 3);
  else
        return -1;
};

//verifica o tamanho da lista
int recupera_tamanho_lista(struct lista *li)
{
  if(li != NULL)
        return li->qtde;
  else
        return -1;
  };
  
int insere_no_fim_da_lista(struct lista *li, int matricula, char *nome){
    if (!lista_cheia(li)){
        li->a[li->qtde].matricula = matricula;
        strcpy(li->a[li->qtde].nome, nome);
		       
        li->qtde++;
        return -1;
    } else {
        return 0;
    }
}

int main(void)
{
    struct lista *li;

    li = cria_lista();

    printf("\nLista vazia? %d ", lista_vazia(li));
    printf("\nLista cheia? %d ", lista_cheia(li));
    printf("\nTamanho da lista? %d ", recupera_tamanho_lista(li));
}

 

Link para o comentário
Compartilhar em outros sites

16 minutos atrás, herbertbahia disse:

fui mostrar um exemplo de lista mas depois percebi que nao atendia seu enunciado.

mas encontrei seu exercicio resolvido https://github.com/AdrielFreud/Listas-Estaticas

Valeu amigo,  rapaz que codigo grande kkk

E ele esta puxando outro arquivo, mas já pra ter uma boa base, valeu

adicionado 31 minutos depois
47 minutos atrás, herbertbahia disse:

fui mostrar um exemplo de lista mas depois percebi que nao atendia seu enunciado.

mas encontrei seu exercicio resolvido https://github.com/AdrielFreud/Listas-Estaticas

 

2 horas atrás, isrnick disse:

 

Se entendi corretamente, era para usar a estrutura inclusa no código já fornecido, e apenas fazer uma função para inserir um elemento no fim da lista.

 

Então se é isso mesmo, eu diria que esse código não atende o que foi solicitado, pois você alterou o código original, e transformou a lista, que era sequencial estática, em uma lista ligada, e então você fez uma função para inserir no fim da lista ligada. Note também que o programa como está nem se quer usa a struct aluno.

Então, agora estou na duvida se esta ou não mostrando os resultados de Lista Vazia ou Cheia, pois os dois mostram 0

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100

struct aluno {
	int matricula;
	char nome[30];
	float n1, n2, n3;
};

typedef struct lista {
	int qtd;
	struct aluno dados[MAX];
} Lista;

Lista *cria_lista();

void libera_lista(Lista *li);
int tamanho_lista(Lista *li);

int lista_cheia(Lista *li);
int lista_vazia(Lista *li);

int insere_lista_final(Lista *li, struct aluno al);
int insere_lista_inicio(Lista *li, struct aluno al);
int insere_lista_ordenada(Lista *li, struct aluno al);

int remove_lista_inicio(Lista *li);
int remove_lista_final(Lista *li);
int remove_lista(Lista *li, int mat);



int main(void){
	Lista *li;
	struct aluno al;

	al.matricula = 3;
	strcpy(al.nome, "Marcos");
	al.n1 = 60;
	al.n2 = 50.0;
	al.n3 = 71.2;

	li = cria_lista();
	insere_lista_inicio(li, al);
	int x = tamanho_lista(li);

	printf("Tamanho Lista: %d\n", x);

	if(lista_cheia(li)){
		printf("Tamanho Lista: %d\n", lista_cheia(li));
	}

	if(lista_vazia(li)){
		printf("Lista Vazia!\n");
	}

	
	printf("\n lista vazia? %d", lista_vazia(li));
	printf("\n lista cheia? %d", lista_cheia(li));

	remove_lista(li, 3);
	libera_lista(li);
	
	return 0;
}

Lista *cria_lista(void){
	Lista *li;
	li = (Lista *)malloc(sizeof(Lista));
	if(li != NULL){
		li->qtd = 0;
	}
	return li;
}

void libera_lista(Lista *li){
	free(li);
}

int insere_lista_inicio(Lista *li, struct aluno al){
	if(li == NULL){
		return 0;
	}
	if(lista_cheia(li)){
		return 0;
	}

	for(int i = li->qtd-1; i>0; i--){
		li->dados[i+1] = li->dados[i];
	}

	li->dados[0] = al;
	li->qtd++;

	return 1;
}

int remove_lista(Lista *li, int mat){
	if(li == NULL){
		return 0;
	}
	if(li->qtd == 0){
		return 0;
	}

	int k, i = 0;

	while(i < li->qtd && li->dados[i].matricula != mat){
		i++;
	}

	if(i == li->qtd){
		return 0;
	}

	for(k = i; k < li->qtd-1; k++){
		li->dados[k] = li->dados[k+1];
	}
	
	li->qtd--;

	return 1;
}

int tamanho_lista(Lista *li){
	if(li == NULL){
		return -1;
	}else{
		return li->qtd;
	}
}

int lista_cheia(Lista *li){
	if(li == NULL){
		return -1;
	}else{
		return (li->qtd == MAX);
	}
}

int lista_vazia(Lista *li){
	if(li == NULL){
		return -1;
	}else{
		return (li->qtd == 0);
	}
}

 

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

1 hora atrás, herbertbahia disse:

fui mostrar um exemplo de lista mas depois percebi que nao atendia seu enunciado.

mas encontrei seu exercicio resolvido https://github.com/AdrielFreud/Listas-Estaticas

Sabe me dizer por que não aparece nenhum resultado?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define LISTAS 50


struct aluno {

    int matricula;
    char nome[100];
    float n1;
    float n2;
    float n3;
};

struct lista {

    int qtde;
    struct aluno a[LISTAS];
};

struct lista* cria_lista(){

    struct lista *li;
    li=(struct lista *)malloc(sizeof(struct lista));

    if(li != NULL)
        li->qtde = 0;

    return li;
};
int lista_vazia(struct lista *li)
{
    if(li != NULL)
        return (li->qtde ==0);
    else
        return -1;
};

int lista_cheia(struct lista *li)
{
  if(li !=NULL)
        return (li->qtde == LISTAS);
  else
        return -1;
};

int tamanho_lista(struct lista *li)
{
  if(li != NULL)
        return li->qtde;
  else
        return -1;
  };
  
int fim_lista(struct lista *li, struct aluno *al){
    if (!lista_cheia(li)){
        li->a[li->qtde] = *al;
        li->qtde++;
        return -1;
    } else {
        return 0;
    }
}

int main()
{
    struct lista *li;
	struct aluno al;
    al = (struct aluno){.matricula=65464, .nome="Maria Silva"};
    
    fim_lista(li, &al);

    li = cria_lista();

    printf("\nLista vazia: %d ", lista_vazia(li));
    printf("\nLista cheia: %d ", lista_cheia(li));
    printf("\nTamanho da lista: %d ", tamanho_lista(li));
}

@isrnick Sabe me dizer tambem?

Ta complicado isso

Link para o comentário
Compartilhar em outros sites

    fim_lista(li, &al);
    li = cria_lista();

 

Você não deve chamar fim_lista() antes de criar_lista(), certo?

 

Que compilador você usa? Ele não avisou sobre isso?

 

Se não alocou a lista ainda não vai fazer muito tentando acessar.

 

Claro que é uma decisão de implementação mas chamar a rotina que "insere no fim" de fim_lista() é uma escolha curiosa.

int fim_lista(struct lista *li, struct aluno *al)
{
    if (!lista_cheia(li)){
        li->a[li->qtde] = *al;
        li->qtde++;
        return -1;
    } else {
        return 0;
    }
}

E se quando a lista está cheia retorna zero não seria muito mais claro escrever

int fim_lista(struct lista *li, struct aluno *al)
{
    if (lista_cheia(li)) return 0;

    li->a[li->qtde] = *al;
    li->qtde++;
    return -1;
}

E sobre essa linha:

    li->a[li->qtde] = *al;

Isso não funciona.

 

Se 'a' fosse um ponteiro para struct aluno você pode escrever

a = al;

Mas ...

    struct aluno a[LISTAS];

a[] é uma estrutura. Você não pode resumir as coisas assim nessas linguagens.


Ou você copia campo a campo ou usa memcpy() para transferir, como está no exemplo que eu postei...

 

Sobre as structs:
 

Para evitar o tédio de digitar struct toda hora, considere o simples e comum:

struct aluno
{
    int matricula;
    char nome[100];
    float n1;
    float n2;
    float n3;
};
typedef struct aluno Aluno;

struct lista
{

    int   qtde;
    Aluno alunos[LISTAS];
};
typedef struct lista Lista;

Que permitiria escrever

int main()
{
    Lista* li;
    Aluno al;
    al = (Aluno){ .matricula = 65464, .nome = "Maria Silva" };
    li = cria_lista();
    fim_lista(li, &al);

...

Não acha mais legível? typedef só declara um alias, um sinônimo, um outro nome...

 

Essa "estrutura" é só um vetor e um contador. Não era pra ter trabalho

 

Link para o comentário
Compartilhar em outros sites

9 minutos atrás, arfneto disse:

    fim_lista(li, &al);
    li = cria_lista();

 

Você não deve chamar fim_lista() antes de criar_lista(), certo?

 

Que compilador você usa? Ele não avisou sobre isso?

 

Se não alocou a lista ainda não vai fazer muito tentando acessar.

 

Claro que é uma decisão de implementação mas chamar a rotina que "insere no fim" de fim_lista() é uma escolha curiosa.


int fim_lista(struct lista *li, struct aluno *al)
{
    if (!lista_cheia(li)){
        li->a[li->qtde] = *al;
        li->qtde++;
        return -1;
    } else {
        return 0;
    }
}

E se quando a lista está cheia retorna zero não seria muito mais claro escrever


int fim_lista(struct lista *li, struct aluno *al)
{
    if (lista_cheia(li)) return 0;

    li->a[li->qtde] = *al;
    li->qtde++;
    return -1;
}

E sobre essa linha:


    li->a[li->qtde] = *al;

Isso não funciona.

 

Se 'a' fosse um ponteiro para struct aluno você pode escrever


a = al;

Mas ...


    struct aluno a[LISTAS];

a[] é uma estrutura. Você não pode resumir as coisas assim nessas linguagens.


Ou você copia campo a campo ou usa memcpy() para transferir, como está no exemplo que eu postei...

 

Sobre as structs:
 

Para evitar o tédio de digitar struct toda hora, considere o simples e comum:


struct aluno
{
    int matricula;
    char nome[100];
    float n1;
    float n2;
    float n3;
};
typedef struct aluno Aluno;

struct lista
{

    int   qtde;
    Aluno alunos[LISTAS];
};
typedef struct lista Lista;

Que permitiria escrever


int main()
{
    Lista* li;
    Aluno al;
    al = (Aluno){ .matricula = 65464, .nome = "Maria Silva" };
    li = cria_lista();
    fim_lista(li, &al);

...

Não acha mais legível? typedef só declara um alias, um sinônimo, um outro nome...

 

Essa "estrutura" é só um vetor e um contador. Não era pra ter trabalho

 

Perfeito, consegui executar fazendo as alterações, veja:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define LISTAS 50


struct aluno {

    int matricula;
    char nome[100];
    float n1;
    float n2;
    float n3;
};
typedef struct aluno Aluno;

struct lista {

    int qtde;
    Aluno alunos[LISTAS];
};

typedef struct lista Lista;

struct lista* cria_lista(){

    struct lista *li;
    li=(struct lista *)malloc(sizeof(struct lista));

    if(li != NULL)
        li->qtde = 0;

    return li;
};
int lista_vazia(struct lista *li)
{
    if(li != NULL)
        return (li->qtde ==0);
    else
        return -1;
};

int lista_cheia(struct lista *li)
{
  if(li !=NULL)
        return (li->qtde == LISTAS);
  else
        return -1;
};

int tamanho_lista(struct lista *li)
{
  if(li != NULL)
        return li->qtde;
  else
        return -1;
  };
  
int fim_lista(struct lista *li, struct aluno *al){
    if (!lista_cheia(li)){
        li->alunos[li->qtde] = *al;
        li->qtde++;
        return -1;
    } else {
        return 0;
    }
}

int main()
{
    Lista* li;
    Aluno al;
    al = (Aluno){ .matricula = 65464, .nome = "Maria Silva" };
    li = cria_lista();
    fim_lista(li, &al);

    li = cria_lista();

    printf("\nLista vazia: %d ", lista_vazia(li));
    printf("\nLista cheia: %d ", lista_cheia(li));
    printf("\nTamanho da lista: %d ", tamanho_lista(li));
}

Uma pergunta, o resulta impresso sai:

 

Lista Vazia: 1

Lista cheia: 0

Tamanho da lista: 0

 

Para poder tornar como uma lista cheia, posso inserir mais função e declarações como esta?

al = (Aluno){ .matricula = 65464, .nome = "Maria Silva" };

Para poder inserir mais usuários?

Link para o comentário
Compartilhar em outros sites

 

int tamanho_lista(struct lista *li)

Podia ser também

int tamanho_lista(Lista* li)

Assim fica mais claro que o parâmetro 'li' é um ponteiro para Lista...
 

Citação

Em todo o programa Aluno é struct aluno e Lista é struct lista. Esse é o efeito do typedef



É uma convenção comum em java, mas acho que tem sentido no geral.
 

21 minutos atrás, Rafael Melo disse:

Uma pergunta, o resulta impresso sai:

 

Lista Vazia: 1

Lista cheia: 0

Tamanho da lista: 0

 

Para poder tornar como uma lista cheia, posso inserir mais função e declarações como esta?


al = (Aluno){ .matricula = 65464, .nome = "Maria Silva" };

Para poder inserir mais usuários?


Sim. que tal um loop? Escreva o simples

 


    int matricula = 65464;
    al = (Aluno){ .matricula = matricula, .nome = "Maria Silva" };
    do
    {  
        fim_lista(li, &al);
        al.matricula += 1;
    } while (!lista_cheia(li));

Sobre esse tema eu postei uma rotina fabrica() 


Aluno* fabrica()
{
	static int matricula = 10000;
	Aluno* a = (Aluno*)malloc(sizeof(Aluno));
	sprintf(a->nome, "Jhonny Cash %04d", matricula);
	a->matricula = matricula;
	a->n1 = rand() % 100 + rand() % 100 / 100.f;
	a->n2 = rand() % 100 + rand() % 100 / 100.f;
	a->n3 = rand() % 100 + rand() % 100 / 100.f;
	matricula += 1;
	return a;
};

Que tal? Cada vez que chama ela retorna um nome e matricula novos, com notas e tudo...
 

 

Link para o comentário
Compartilhar em outros sites

10 minutos atrás, arfneto disse:

 


int tamanho_lista(struct lista *li)

Podia ser também


int tamanho_lista(Lista* li)

Assim fica mais claro que o parâmetro 'li' é um ponteiro para Lista...
 



É uma convenção comum em java, mas acho que tem sentido no geral.
 


Sim. que tal um loop? Escreva o simples

 



    int matricula = 65464;
    al = (Aluno){ .matricula = matricula, .nome = "Maria Silva" };
    do
    {  
        fim_lista(li, &al);
        al.matricula += 1;
    } while (!lista_cheia(li));

Sobre esse tema eu postei uma rotina fabrica() 



Aluno* fabrica()
{
	static int matricula = 10000;
	Aluno* a = (Aluno*)malloc(sizeof(Aluno));
	sprintf(a->nome, "Jhonny Cash %04d", matricula);
	a->matricula = matricula;
	a->n1 = rand() % 100 + rand() % 100 / 100.f;
	a->n2 = rand() % 100 + rand() % 100 / 100.f;
	a->n3 = rand() % 100 + rand() % 100 / 100.f;
	matricula += 1;
	return a;
};

Que tal? Cada vez que chama ela retorna um nome e matricula novos, com notas e tudo...
 

 

Realmente, gostei mais:

int tamanho_lista(Lista* li)

int tamanho_lista(Lista* li)

O problema esta sendo que não contabiliza a quantidade de usuários e aparece o resultado como lista cheia ou vazia:

int main()
{
    Lista* li;
    Aluno al;
    al = (Aluno){ .matricula = 65464, .nome = "Maria" };
    al = (Aluno){ .matricula = 65567, .nome = "Marcos" };
    al = (Aluno){ .matricula = 68865, .nome = "Renan" };
    al = (Aluno){ .matricula = 78890, .nome = "Filipe" };
    al = (Aluno){ .matricula = 78900, .nome = "Rafael" };
    li = cria_lista();
    fim_lista(li, &al);

    li = cria_lista();

    printf("\nLista vazia: %d ", lista_vazia(li));
    printf("\nLista cheia: %d ", lista_cheia(li));
    printf("\nTamanho da lista: %d ", tamanho_lista(li));
}

O resultado impresso sempre esta sendo:

Lista Vazia: 1

Lista cheia: 0

Tamanho da lista: 0

Link para o comentário
Compartilhar em outros sites

7 minutos atrás, Rafael Melo disse:

O resultado impresso sempre esta sendo:

Lista Vazia: 1

Lista cheia: 0

Tamanho da lista: 0

 

Vou ver seu programa.

 

Você pode usar apenas "mencionar" e escolher o nome do usuário ou escolher o trecho que achar importante do que eu digitei. É melhor que repetir tudo toda vez.

 

Porque não usou o loop como eu expliquei? era muito mais simples...

 

Link para o comentário
Compartilhar em outros sites

2 minutos atrás, arfneto disse:

 

Vou ver seu programa.

 

Você pode usar apenas "mencionar" e escolher o nome do usuário ou escolher o trecho que achar importante do que eu digitei. É melhor que repetir tudo toda vez.

 

Porque não usou o loop como eu expliquei? era muito mais simples...

 

Eu usei, porém ficava dando conflito.

Não aparecia nada na tela, mas quando tirei o loop, voltou a funcionar.

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

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!