warning: passing argument 1 of 'HashInsertar' from incompatible pointer type

0

I have this program that should implement a hasheo function. But throw the following warning that is above:

warning: passing argument 1 of 'HashInsertar' from incompatible pointer type

When you try to pass the number entered by the user to the function HashInsertar the warning above goes up and I do not know how to correct it. What can I do?

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define HASHMAX 10

typedef struct nodoL {
    int info;
    struct nodoL * sig;
} * lista;

//Definición de las Funciones
// DEFINICIÓN DE LAS FUNCIONES
//************* HASH **********

typedef lista Hash[HASHMAX];
int HashClave(int n);
void HashInsertar(Hash *H, int e);
void HashMostrar(Hash H);
void HashBuscar(Hash H, int n);

//********  LISTA   *******
void enlistar (lista *L, int n);
int mostrar (lista L); /* muestra por pantalla los valores de L, en forma recursiva */
void borrar(lista *L, int n);

int HashClave ( int n)
{
    return n%HASHMAX;
}

void HashInsertar (Hash *H, int e){
    enlistar ((H)[HashClave(e)],e);
}

void HashMostrar(Hash H){
    int i, n;
    for (n=0;n<HASHMAX;n++){
        printf("Hash [%d]: ",n);
        i=mostrar(H);
        if(i==0)printf("Lista  vacia \n\n");
        else printf("# \n\n");
    }
}

void enlistar (lista *L, int n){
    lista aux = (lista)malloc(sizeof(struct nodoL));
    if(L==NULL){
        aux -> info = n;
        aux -> sig = *L;
        *L=aux;
    }
    else{
        if((*L)->info>n){
            aux -> info = n;
            aux -> sig = *L;
            *L=aux;
        }
        else{
            enlistar(&(*L)->sig,n);
        }
    }
}

int mostrar (lista L)
{
    int i=0;
    if(L!=NULL)
    {
        i=1;
        printf("[%d]->",L->info);
        mostrar(L->sig);
    }
    return i;
}


void borrar(lista *L, int n)
{
    lista aux = *L;
    lista ant = NULL;
    if(aux==NULL)
    {
        printf("Error: Lista vacia");
    }
    else
    {
        while (aux->info!=n&&aux->sig!=NULL)
        {
            ant=aux;
            aux=aux->sig;
        }
        if(aux->sig==NULL&&aux->info!=n)
               printf("Error, caracter no se encuentra en la lista");
        else
        {
            ant->sig=aux->sig;
            free (aux);
        }
    }
}

int main()
{
    int op=-1;
    int i;
    lista milista=NULL;
    while(op)
    {
        system("cls");
        printf("\t\tEjemplo de Hash\n\n\tSeleccione una opcion\n\n\t-1. Agregar elemento al frente\n\t-2. Mostrar lista\n\t-3. Borrar un elemento\n\t-0. Salir\n");
        scanf("%d",&op);
        switch(op)
        {
        case 1:
        {
            int numNuevo;
            system("cls");
            printf("Ingrese el numero para agregar a la lista:\n");
            scanf("%d",&numNuevo);
            system("cls");
            HashInsertar(&milista,numNuevo); //<------- warning: passing argument 1 of HashInsertar from incompatible point type
            getch();
            break;
        }
        case 2:
        {
            system("cls");
            printf("Los numeros cargados en la lista:\n\n");
            i = mostrar(milista);
            if(i==0)printf("La lista esta vacia \n\n");
            else printf("# \n\n");
            getch();
        }
        break;
        case 3:
        {
            int n;
            system("cls");
            printf("Ingrese el numero para borrar de la lista:\n");
            scanf("%d",&n);
            system("cls");
            borrar(&milista,n);
            if(i==0)printf("Elemento borrado de la lista. Pulse cualquier tecla para regresar");
            getch();
            break;
        }
        }
    }
    getch();
    return 0;
}
    
asked by Alejandro Caro 28.08.2018 в 23:25
source

2 answers

1

You have encountered a recurring error in StackOverflow in Spanish motivated by the misuse of type aliases and the mixing of concepts.

The nodes are not lists.

In the code you have given, you define the struct nodoL object, then name the pointer to this object as lista . And that is as wrong as saying that a step is a ladder, sincerely Do you think the same ?:

This erroneous nomenclature makes it difficult to reason about the code and that it is difficult to follow and debug, since the alias not only hides the underlying type but also gives it a semantic meaning that it lacks.

Thus: lista is not a list of elements, it is a pointer to a struct nodoL . Taking into account the correct concepts, this other alias:

typedef lista Hash[HASHMAX];

It does not make Hash a training 1 of HASHMAX lists, but it is a formation of HASHMAX pointers to struct nodoL .

Things by name.

If we now name things by their names, we will see why you are receiving the error you describe, the function HashInsertar :

void HashInsertar(Hash *H, int e);

It is not a function that receives a pointer to Hash and an integer ( int ) but a function that receives a pointer to a formation of HASHMAX pointers to struct nodoL , in the call that It produces error:

HashInsertar(&milista,numNuevo);

You feed the function with the memory address of milista , which has been defined as follows:

lista milista=NULL;

The variable milista is not a list of elements but it is a pointer to struct nodoL , applying the operator address we get a pointer to a pointer to struct nodoL while HashInsertar expects a pointer to a formation of HASHMAX pointers to struct nodoL : it is clearly receiving a different data than expected:

| SÍMBOLO  | DESCRIPCIÓN                                            | TIPO               |
+----------+--------------------------------------------------------+--------------------+
| &milista | puntero a puntero a struct nodoL                       | nodoL**            |
| Hash *   | puntero a formación de HASHMAX punteros a struct nodoL | (nodoL*[HASHMAX])* |

Proposal.

To avoid these confusions, call things by their names, creating additional types if necessary:

typedef struct nodoL {
    int info;
    struct nodoL * sig;
} nodoL;

typedef struct lista {
    nodoL * raiz;
} lista;

typedef struct Hash {
    lista tabla[HASHMAX];
} Hash;

With these types clearly differentiated, you must make changes to your code:

void enlistar (lista *L, int n) {
    nodoL *punto_de_insercion = L -> raiz;

    if (punto_de_insercion) {
        while (punto_de_insercion -> sig) {
            punto_de_insercion = punto_de_insercion -> sig;
        }
        punto_de_insercion -> sig = (nodoL *)malloc(sizeof(nodoL));
        punto_de_insercion = punto_de_insercion -> sig;
    } else {
        punto_de_insercion = (nodoL *)malloc(sizeof(nodoL));
    }

    punto_de_insercion -> info = n;
    punto_de_insercion -> sig = NULL;
}

void HashInsertar (Hash *H, int e){
    enlistar ((H -> tabla[HashClave(e)], e);
}

Note that I have not added any initialization or release routine (and I have written the routine enlistar without testing it), each of the types will need to be initialized and released, for example:

void crear_hash(Hash *H) {
    for (int i = 0; i < HASHMAX; ++i) {
        H -> tabla[i] = (lista *)malloc(sizeof(lista));
    }
}

void eliminar_hash(Hash *H) {
    for (int i = 0; i < HASHMAX; ++i) {
        eliminar_lista(H -> tabla[i]);
    }
}
  • Also known as array or in English array .
  • answered by 29.08.2018 / 14:12
    source
    2

    Frankly it makes me quite logical that I give you that warning, after The entire HashInsertar function has the following prototype:

    void HashInsertar(Hash *H, int e);
    

    As a first argument, it receives a pointer to Hash. Meanwhile you in the main declares the milista variable as follows:

    lista milista = NULL;
    

    And try to pass it to the hash function:

    HashInsertar(&milista, numNuevo);
    

    How you antedate the & to "milista", you are passing a pointer to list to the function, while this keeps asking you for a pointer to Hash.

    We are going to expand the definitions of both to see the difference:

    A list is defined as:

    typedef struct nodoL * lista;
    

    that is:

    (lista) ≡ (struct nodoL *)
    

    Therefore a pointer to list would be a double pointer to struct nodeL:

    (lista *) ≡ (struct nodoL **)
    

    Meanwhile a hash is defined as:

    typedef lista hash[HASHMAX];
    

    In other words, the following is true:

    (HASH) ≡ (lista [HASHMAX]) ≡ (struct nodoL * [HASHMAX])
    

    So a hash pointer would be:

    (HASH *) ≡ (lista * (*) [HASHMAX]) ≡ (struct nodoL * (*) [HASHMAX])
    

    Then the pointer to list compared to the pointer to Hash:

    (struct nodoL **) ≠ (struct nodoL * (*) [HASHMAX])
            (lista *) ≠ (lista (*)[HASHMAX])
            (lista *) ≠ (Hash *)
    
        
    answered by 29.08.2018 в 05:58