Reputation:
void remove_element(struct Node *list)
{
struct Node *temp = list;
printf("Enter the element value you want to remove");
int value;
scanf("%d",&value);
if(temp->data == value){ //first node is to be deleted
*list = temp->next; // error here
free(temp);
}
}
Error :incompatible types when assigning to type 'struct Node' from type 'struct Node *'| Though this has been successfully compiled
struct Node *temp = list;
This line is similar but shows no error.
Upvotes: 1
Views: 143
Reputation: 84
First of all the reason why you are getting error is...
*list = temp->next; //not *list it should be list
By doing so your code will compile but you will get unexpected results i think. Because:
list=temp->next // This will make the pointer to constantly point to the head
But i think you are trying to do a linear search. Thus you also need to change the above line to
temp = temp->next;
For your code to work as you expected.
Upvotes: 1
Reputation: 310930
As the parameter list
is declared like
struct Node *list
then the expression *list
used in this statement
*list = temp->next;
has the type struct Node
while the right side hand operand has the type struct Node *
.
You have to write
list = temp->next;
But in any case pay attention to that the function can invoke undefined behavior when the passed list is empty. And it should search a node for the target value instead of checking only the head node whether it contains the target value.
And the worst is the function even does not change the pointer to the head node because the pointer is passed to the function by value. So this statement
list = temp->next; // error here
changes a copy of the original pointer to the head node not the original pointer itself declared in main.
The function should be defined at least like
int remove_element( struct Node **list )
{
printf( "Enter the element value you want to remove: " );
int value;
int success = scanf( "%d", &value ) == 1;
if ( success )
{
while ( *list != NULL && ( *list )->data != value )
{
list = &( *list )->next;
}
success = *list != NULL;
if ( success )
{
struct Node *tmp = *list;
*list = ( *list )->next;
free( tmp );
}
}
return success;
}
If in main you have a declaration
struct Node *list = NULL;
//...
then the function must be called like
remove_element( &list );
or something like
if ( remove_element( &list ) )
{
puts( "A node was removed." );
}
Also it would be better if the function would do only one thing: deleting a node. The prompt for a value that must be deleted should be placed outside the function. In this case the function can be defined the following way
int remove_element( struct Node **list, int value )
{
while ( *list != NULL && ( *list )->data != value )
{
list = &( *list )->next;
}
int success = *list != NULL;
if ( success )
{
struct Node *tmp = *list;
*list = ( *list )->next;
free( tmp );
}
return success;
}
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *next;
};
int push_front( struct Node **list, int data )
{
struct Node *temp = malloc( sizeof( struct Node ) );
int success = temp != NULL;
if ( success )
{
temp->data = data;
temp->next = *list;
*list = temp;
}
return success;
}
void clear( struct Node **list )
{
while ( *list != NULL )
{
struct Node *temp = *list;
*list = ( *list )->next;
free( temp );
}
}
void display( const struct Node *list )
{
for ( const struct Node *current = list; current != NULL; current = current->next )
{
printf( "%d -> ", current->data );
}
puts( "null" );
}
int remove_element( struct Node **list, int value )
{
while ( *list != NULL && ( *list )->data != value )
{
list = &( *list )->next;
}
int success = *list != NULL;
if ( success )
{
struct Node *tmp = *list;
*list = ( *list )->next;
free( tmp );
}
return success;
}
int main(void)
{
struct Node *list = NULL;
const int N = 10;
for ( int i = N; i != 0; i-- )
{
push_front( &list, i );
}
display( list );
int value = 1;
if ( remove_element( &list, value ) )
{
printf( "The element with the value %d was removed.\n", value );
}
display( list );
value = 10;
if ( remove_element( &list, value ) )
{
printf( "The element with the value %d was removed.\n", value );
}
display( list );
value = 5;
if ( remove_element( &list, value ) )
{
printf( "The element with the value %d was removed.\n", value );
}
display( list );
clear( &list );
display( list );
return 0;
}
Its output is
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> null
The element with the value 1 was removed.
2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> null
The element with the value 10 was removed.
2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
The element with the value 5 was removed.
2 -> 3 -> 4 -> 6 -> 7 -> 8 -> 9 -> null
null
Upvotes: 0
Reputation: 31296
struct Node *temp = list;
is the same as
struct Node *temp;
temp = list;
So change the erroneous line to
list = temp->next;
Note that *
means slightly different things depending on context. In declarations, it indicates that you want to declare a pointer instead of a regular variable. When used in an expression, it instead means that you want to dereference the pointer. There is no way to dereference it during declaration, which does not cause any problems since that would be undefined behavior anyway.
Upvotes: 5