assignement from incompatible pointer type in C

Viewed 75

I have a linked list of a struct, here is my struct:

typedef struct avion
{
    int code;
    int capacite;
    char etat[1];
    int date;
    int nvols;
} avion;

typedef struct element *list;
typedef struct element
{
    avion A;
    struct element *svt;
} element;

I want to sort the linked list in ascending order according to the element of the struct "capacite". here is the code of the function tri:

list *tri(list *L)
{
   list *i,*j,*min;
   avion  x;
   for (i=L; (*i)->svt != NULL; i=(*i)->svt)
   {
      min=i;
      for (j=(*i)->svt; j != NULL; j=(*j)->svt)
      {
        if ((*j)->A.capacite < (*min)->A.capacite)
           min=j;
      }
       if (min != i)
      {
       x=(*min)->A;
       (*min)->A = (*i)->A;
       (*i)->A = x;
    }
}
return(L);
}

But i have the warning: assignement from incompatible pointer (in the two lines of the for loop: and i dont know how to fix it.

Is there any better way to sort my linked list according to this criterion?

2 Answers

For example in this for loop

for (i=L; (*i)->svt != NULL; i=(*i)->svt)

the variable i declared like

list *i

has the type struct element **. On the other hand the data member svt has the type struct element *. Thus this assignment

i=(*i)->svt

contains operands of different types and there is no implicit conversion from the type struct element * to the type struct element **.

Pay attention to that the function can invoke undefined behavior if it will be called for an empty list due to this expression

(*i)->svt != NULL;

Also this declaration of an array with one element

char etat[1];

does not make a great sense.

And introducing such an alias for a pointer like this

typedef struct element *list;

in general is not a good idea. It can only confuse readers of the code.

There is no need to pass to the function tri (that implements the selection sort) the pointer to the head node by reference through a pointer to it because the pointer itself is not being changed within the function.

The function can be declared and defined the following way as it is shown in the demonstrative program below.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct avion
{
    int capacite;
} avion;

typedef struct element list;
typedef struct element
{
    avion A;
    struct element *svt;
} element;

int push_front( list **head, int capacite )
{
    element *new_element = malloc( sizeof( element ) );
    int success = new_element != NULL;
    
    if ( success )
    {
        new_element->A.capacite = capacite;
        new_element->svt = *head;
        
        *head = new_element;
    }
    
    return success;
}

void display( const list *head )
{
    for ( ; head != NULL; head = head->svt )
    {
        printf( "%d -> ", head->A.capacite );
    }
    
    puts( "null" );
}

void tri( list *head )
{
    for ( ; head != NULL; head = head->svt )
    {
        element *min = head;
        
        for ( element *current = head->svt; current != NULL; current = current->svt )
        {
            if ( current->A.capacite < min->A.capacite )
            {
                min = current;
            }
        }
        
        if ( min != head )
        {
            avion tmp = min->A;
            min->A = head->A;
            head->A = tmp;
        }
    }
}

int main(void) 
{
    enum { N = 10 };
    list *head = NULL;
    
    srand( ( unsigned int )time( NULL ) );

    for ( int i = 0; i < N; i++ )
    {
        push_front( &head, rand() % N );
    }
    
    display( head );
    
    tri( head );
    
    display( head );

    return 0;
}

The program output might look for example the following way.

7 -> 1 -> 2 -> 6 -> 0 -> 9 -> 0 -> 9 -> 6 -> 0 -> null
0 -> 0 -> 0 -> 1 -> 2 -> 6 -> 6 -> 7 -> 9 -> 9 -> null

If to use your alias definition of the name list then the function can look as it is shown in this demonstrative program.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct avion
{
    int capacite;
} avion;

typedef struct element *list;
typedef struct element
{
    avion A;
    struct element *svt;
} element;

int push_front( list *head, int capacite )
{
    element *new_element = malloc( sizeof( element ) );
    int success = new_element != NULL;
    
    if ( success )
    {
        new_element->A.capacite = capacite;
        new_element->svt = *head;
        
        *head = new_element;
    }
    
    return success;
}

void display( list head )
{
    for ( ; head != NULL; head = head->svt )
    {
        printf( "%d -> ", head->A.capacite );
    }
    
    puts( "null" );
}

void tri( list head )
{
    for ( ; head != NULL; head = head->svt )
    {
        element *min = head;
        
        for ( element *current = head->svt; current != NULL; current = current->svt )
        {
            if ( current->A.capacite < min->A.capacite )
            {
                min = current;
            }
        }
        
        if ( min != head )
        {
            avion tmp = min->A;
            min->A = head->A;
            head->A = tmp;
        }
    }
}

int main(void) 
{
    enum { N = 10 };
    list head = NULL;
    
    srand( ( unsigned int )time( NULL ) );

    for ( int i = 0; i < N; i++ )
    {
        push_front( &head, rand() % N );
    }
    
    display( head );
    
    tri( head );
    
    display( head );

    return 0;
}

Because of this typedef struct element *list; When you write list *i i isn't a pointer on an element but a pointer on a pointer of an element

Related