Use "->" or "." in a chained list?

Asked

Viewed 120 times

1

Good afternoon, making a hash table without bumps, I created the list struct, 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 should not use structlist->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;
}
  • Actually "struct->" is a more readable way of writing "(*struct)." , which in the end has the same intention of accessing an attribute of the pointer for struct, but you have already referenced your pointer as an array "struct[][]" this makes it an error to use "->" to access the attributes of the struct.

1 answer

1

From the description of your question it seems to me that you are referring to this:

Lista* *tabela = (Lista**) malloc (hash.tam*sizeof(Lista*));
...

tabela[i][0].info = NULL;
//       ---^
tabela[i][0]->prox = NULL;
//       ---^

That’s certainly not right. You’re confusing the concepts.

Realizing . vs ->

I start by saying something important that is -> is a syntactic abbreviation. Let’s look first 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 the kind struct pessoa and a pointer ptr1 for the person type. To define the idade of p1 doing . because I have the object directly:

p1.idade = 25;

In the case of the pointer ptr1 I can’t 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 matters:

(*ptr1).idade = 25;

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

ptr1->idade = 25;

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

The type of the field affects the value we place. Imagine now that one has a friend, who 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 code of the question

Returning to your example, you have a Lista**, a two-dimensional array. So when doing [i][0] access an element of the type Lista, logo must use . and not ->, for Lista is not a pointer.

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.