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;
}
Author: Joao Paulo, 2018-07-11

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

 1
Author: Isac, 2018-07-11 22:41:25