Use "-" or "." in a linked list?

1

Good afternoon, doing a hash table without collisions, I created the struct list, however when compiling the code it does not accept that I use the -> prox from my struct, it asks me to use .prox. But if prox is a pointer I should not 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;
}
    
asked by anonymous 11.07.2018 / 20:42

1 answer

1

By 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;
//       ---^
Which is certainly not right. You are confusing the concepts.

Realizing . vs ->

I start by saying something important that is -> is a syntactic abbreviation. Let's look at a simple case first.

struct pessoa {
    int idade;
};

struct pessoa p1;
struct pessoa *ptr1 = malloc sizeof(struct pessoa);

In this scenario we have a p1 object of type struct pessoa and a ptr1 pointer for the type person. To set the idade of p1 I do . because I have the object directly:

p1.idade = 25;

In the case of the ptr1 pointer 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 to the field that interests:

(*ptr1).idade = 25;

As this is annoying to do we have a syntactic abbreviation that we can use -> , which corresponds to the same:

ptr1->idade = 25;

Note that -> is not related to the type of the field but to the type of the variable. If I use the pointer I use -> , but if I use the object I use .

The field type affects the value we place. Now imagine that 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 the question code

Returning to your example, you have a Lista** , a two-dimensional array. So when doing [i][0] it accesses an element of type Lista , so you have to use . and not -> , because Lista is not a pointer.

If it had a Lista*** it would have an array of two dimensions of pointers, so when doing [i][0] would get something like Lista* which is a pointer, and could then use -> (not that it made sense in your code).

    
12.07.2018 / 00:41