Use "->" or "."on a chained list?
Good afternoon, making a hash table without collisions, I created the struct list, but when compiling the code it does not accept that I use the ->prox of my struct, it asks me to use .prox. But if prox is a pointer I shouldn't use structlista- > prox ?
#include <stdio.h>
#include <stdlib.h>
#define N 7
/* Lista para o tratamento das colisões (encadeamento separado) */
struct lista
{
int info;
/* dado */
struct lista* prox; /* ponteiro para o próximo elemento */
};
typedef struct lista Lista;
/* Estrutura da tabela hash */
struct hash
{
Lista **tab; /* vetor com as listas da tabela hash */
int tam;
/* tamanho da tabela hash */
};
typedef struct hash Hash;
int codigo_hash(int chave)
{
return chave % N;
}
void imprime_menu(){
printf("\n(1) Para inserir elemento\n");
printf("(2) Para buscar elemento\n");
printf("(3) Para imprimir a tabela\n");
printf("(4) Para encerrar\n");
}
/*Encontra_linha:
A função vai na coluna do inteiro posicao e retorna qual deve ser o local que o
novo elemento deve ser adicionado para evitar conflitos
*/
int encontra_linha(Lista* *tabela, int posicao){
int i;
for(i = 0; tabela[posicao][i]->prox != NULL; i++){
}
return i;
}
int main()
{
Hash hash;//cria struct do hash
hash.tam = N;//tamanho do hash = 7
Lista* *tabela = (Lista**) malloc (hash.tam*sizeof(Lista*));//alocando memoria da coluna da matriz
int i,j;
for(i=0 ; i < hash.tam; i++){//criando a linha 1 da matriz, composta apenas com NULL. Esta é a tabela hash
tabela[i] = (Lista*) malloc(sizeof(Lista));
tabela[i][0].info = NULL;
tabela[i][0]->prox = NULL;
}
int opcao, dado, posicao, linha;
for(;;){
imprime_menu();
scanf("%d", &opcao);
switch(opcao){
case 1:
printf("Escreva o elemento a ser adicionado:\n");
scanf("%d", &dado);
posicao = codigo_hash(dado);
linha = encontra_linha( tabela, posicao);
tabela[posicao][linha].info = dado;
tabela[posicao][linha]->prox = NULL;
tabela[posicao][linha-1]->prox = tabela[posicao][linha];
break;
case 2:
break;
case 3:
for(i=0 ;i < hash.tam; i++){
printf("\n");
for(j = 0; tabela[posicao][j]->prox != NULL; j++)
printf("%d ", tabela[i][j].info);
}
break;
case 4:
return 0;
}
}
return 0;
}
1 answers
From the description of your question it seems to me that it refers to this:
Lista* *tabela = (Lista**) malloc (hash.tam*sizeof(Lista*));
...
tabela[i][0].info = NULL;
// ---^
tabela[i][0]->prox = NULL;
// ---^
That is certainly not right. You're confusing the concepts.
Perceiving .
vs ->
I start by saying something important that is ->
is a syntactic abbreviation. Let's first look at a simple case.
struct pessoa {
int idade;
};
struct pessoa p1;
struct pessoa *ptr1 = malloc sizeof(struct pessoa);
In this scenario we have an object p1
of type struct pessoa
and a pointer ptr1
to type person. To define the idade
of p1
I do .
because I have the object directly:
p1.idade = 25;
In the case of the pointer ptr1
I can not do the same because I have a pointer to the object. So I have to First Access where the pointer points with *
and then the field that interests:
(*ptr1).idade = 25;
As this is boring to do we have a syntactic abbreviation that we can use ->
, which corresponds to the same:
ptr1->idade = 25;
Note that a ->
it is not related to the type of the field but to the type of the variable. If I leave from use pointer ->
, but if I start from the use object .
The type of the field affects the value we put. Imagine now which person has a friend, which is a pointer:
struct pessoa {
int idade;
struct pessoa *amigo;
};
Now to assign the friend with both object and pointer:
struct pessoa p1;
struct pessoa p2;
struct pessoa *ptr1 = malloc sizeof(struct pessoa);
p1.amigo = &p2;
ptr1->amigo = &p2;
Returning to question code
Going back to your example, you have a Lista**
, a two-dimensional array. So when doing [i][0]
access an element of type Lista
, then you have to use .
and not ->
, because Lista
is not a pointer.
If you had a Lista***
you would have a two-dimensional array of pointers, so when you do [i][0]
you would get something like Lista*
which is a pointer, and you could then use ->
(not that it makes sense in your code).