【问题标题】:Incompatible types error from pointer to pointer从指针到指针的不兼容类型错误
【发布时间】:2020-12-07 15:32:45
【问题描述】:
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);
    }
}

错误:从类型'struct Node *'分配给类型'struct Node'时不兼容的类型| 虽然这已经编译成功了

 struct Node *temp = list; 

此行类似,但没有显示错误。

【问题讨论】:

  • *list = temp->next -> list = temp->next
  • 如果你想从一个列表中移除一个节点,你需要改变前一个元素的next指针。更改 list 没有帮助。

标签: c struct linked-list singly-linked-list function-definition


【解决方案1】:
struct Node *temp = list;

相同
struct Node *temp;
temp = list;

所以把错误的行改成

list = temp->next;

请注意,* 的含义会因上下文而略有不同。在声明中,它表示您要声明指针而不是常规变量。在表达式中使用时,它意味着您要取消引用指针。在声明期间无法取消引用它,这不会导致任何问题,因为无论如何这都是未定义的行为。

【讨论】:

    【解决方案2】:

    首先你得到错误的原因是......

    *list = temp->next; //not *list it should be list
    

    这样做你的代码会编译,但我认为你会得到意想不到的结果。因为:

    list=temp->next // This will make the pointer to constantly point to the head
    

    但我认为您正在尝试进行线性搜索。 因此,您还需要将上述行更改为

    temp = temp->next;
    

    让您的代码按预期工作。

    【讨论】:

      【解决方案3】:

      由于参数list被声明为

      struct Node *list
      

      然后是这个语句中使用的表达式*list

      *list = temp->next;
      

      具有struct Node 类型,而右侧操作数具有struct Node * 类型。

      你必须写

      list = temp->next;
      

      但无论如何要注意,当传递的列表为空时,函数可以调用未定义的行为。它应该在一个节点中搜索目标值,而不是只检查头节点是否包含目标值。

      最糟糕的是函数甚至不改变指向头节点的指针,因为指针是按值传递给函数的。所以这个说法

          list = temp->next; // error here
      

      更改指向头节点的原始指针的副本,而不是在 main 中声明的原始指针本身。

      函数的定义至少应该是这样的

      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;
      }
      

      如果在 main 你有一个声明

      struct Node *list = NULL;
      //...
      

      那么函数必须像这样调用

      remove_element( &list );
      

      或类似的东西

      if ( remove_element( &list ) )
      {
          puts( "A node was removed." );
      }
      

      如果函数只做一件事会更好:删除一个节点。必须删除的值的提示应该放在函数之外。在这种情况下,函数可以通过以下方式定义

      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;
      }
      

      这是一个演示程序。

      #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;
      }
      

      它的输出是

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多