【问题标题】:Unknown "delete" error in my C code [closed]我的 C 代码中出现未知的“删除”错误 [关闭]
【发布时间】:2018-08-01 18:39:03
【问题描述】:

对于这段代码,我必须从老师给我们的函数原型中填充函数。对于这个特定的功能,我不断收到以下错误。

“错误:预期';'在‘p’之前” 删除 p;

int delete(struct node *start, int data){
     struct node *q, *p;
     int dataAfter;
     p = find(start, dataAfter);
     if (p != NULL){
         q = start;
         while (q->next != p){
             q = q->next;
         }
         q->next;     

         p->next;   

         delete p;    

         return 1;                 
     }
     return 0; 
}

【问题讨论】:

  • C 中不存在delete 关键字。
  • C 没有operator delete。在 C 中使用 free ()
  • q->next;p->next; 应该做什么?
  • 如何调整这部分代码以排除删除。我不确定如何修复此错误,因为这实际上是我第一次在 c 中遇到此错误。谢谢。
  • 如果您的意思是free(p),请注意不需要p->next

标签: c pointers memory-management linked-list free


【解决方案1】:

错误本身是一个语法错误 - C 中没有多少看起来像“删除 p”的代码。由于'delete'不是C中的预定义函数(与'return'不同。return 1工作得很好,虽然它看起来有点像'delete p'),所以认为在'delete'之后需要一个分号.

但是,即使您确实包含分号,由于早期 cmets 给出的原因,它仍然不起作用。

将 'delete' 替换为 'free()' 以消除编译时错误,但您仍需要更改

q->next;
p->next;

q->next = p->next;

即使在删除之后,链​​表也能正确连接。

链表一开始可能会让人感到困惑,因此建议您始终在计算机旁边的一张纸上画出您想要实现的内容。

祝你好运:)

【讨论】:

  • 感谢您指出这一点。 'delete' 不是预定义的任何东西,而 return 是预定义的“语句”。很抱歉。
【解决方案2】:

您正试图从链表中删除一个节点。所以,首先找到正确的节点,它被 p 指向。然后,使前一个节点的下一个指针跳过p。为此,请更改:

q->next;     
p->next; 

到:

q->next = p->next;

另外,正如其他人指出的那样,delete 不在 C 中,而是在 C++ 中。因此,接下来进行此更改:

delete p;

到:

free(p);

【讨论】:

    【解决方案3】:

    我不断收到以下错误。 “错误:预期';'在'p'之前

    出现此错误是因为编译器希望您使用分号 ; 完成 statement。 在您的情况下,您的表达式是函数 deletename !编译器知道delete 是什么。否则你会得到不同的错误。

    这在 cmets 中由以下程序说明:

    /* $gcc -o main *.c -Wall -pedantic  -ansi */
    
    #include <stdio.h>
    
    void foo(void)
    {
      int p;
    
      foo  p; /* error: expected ‘;’ before ‘p’ */
      foo; p; /* warning: statement with no effect [-Wunused-value] */
    
      fxx;    /* error: ‘fxx’ undeclared (first use in this function) */
      p;      /* warning: statement with no effect [-Wunused-value] */
    }
    
    int main()
    {
        return 0;
    }
    

    C standard 处理Expression and null statements 涵盖了您的特定场景。

    int delete(struct node *start, int data) 的逻辑需要大量的工作。 当前的回复都没有解决delete 中的所有逻辑问题。 当start == p 时,所有解决方案都会崩溃。

    • 请注意,delete 是 C++ 中使用的函数的名称。在 C 中我们使用free(...) 来释放分配的内存。

    • dataAfter 是一个初始化整数。很可能您打算使用data

    管理链表并不难,但需要注意细节。

    • 当您删除列表中的节点时,您有责任连接这些节点。

    • 如果您删除头部,您有责任移动头部。

    • 如果头是您要查找的节点,并且这是列表中唯一的节点,则在删除该节点后,该节点必须标记为NULL

    请用测试程序看一下完整的单链表simple implementation

    #include<stdio.h>
    #include<stdlib.h>
    
    // Basic simple single list implementation to illustrate 
    // proper deletion of the node 
    
    // Node in List
    typedef struct node {
        int data;
        struct node* next; // pointer to next node
    }node;
    
    // List structure
    typedef struct list {
        node* head;     // The entry point into a linked list.  If the list is empty then the head is a null reference. 
    } list;
    
    // Create list
    list* list_create()
    {
        list* new_list = malloc(sizeof(list));
    
        if(new_list == NULL)
            return NULL;        // protection
    
        new_list->head = NULL;  // If the list is empty then the head is a null reference.  no elements in the list 
    
        return new_list;        // return created new list
    }
    
    // returns newly created node
    node* node_new(int data)
    {
        node* new_node = malloc(sizeof(node)); // allocate memory for the node 
    
        if (new_node == NULL)
            return NULL;                             // protection 
    
        new_node->data = data;                       // remember the data 
        new_node->next = NULL;                       // no next node
    
        return new_node;                             // return new created node
    }
    
    // The method creates a node and prepends it at the beginning of the list.
    // 
    // Frequently used names for this method:
    // 
    // insert at head
    // add first
    // prepend
    //
    // returns new head or NULL on failer
    
    node* prepend_node(list* in_list, node* new_node)
    
    {
       // Add item to the front of the in_list, return pointer to the prepended node (head)    
    
        if(in_list == NULL)
            return NULL;
    
        if(new_node == NULL)                         // problem, not enough memory
           return NULL;                              // in_list->head has not changed 
    
    /* 
                     new_node      
                       |*| -->  NULL   
                       next        
    */       
        if(in_list->head == NULL)                    // if list is empty 
        {
            in_list->head = new_node;                // the new_node becomes a head   
        }
        else // list already have a head node
        {
    /*
                    |2|-->|1|-->NULL
                     ^ 
                     |
                     *
                    head (2) (list pointer)
    
    */
            new_node->next = in_list->head;     // now, the new node next pointer points to the node pointed by the list head, see below:       
    
    /* 
              new_node     
                |3|-->     |2|-->|1|-->NULL
                            ^  
                            |
                            *
                           head (list pointer)
    */          
            in_list->head = new_node;               // the list head has to move to new_node ( a new prepanded node)  
    
     /* 
              new_node       
                |3|-->  |2|-->|1|-->NULL
                 ^       
                 |           
                 *           
                head (3) (list pointer)
    */         
        }
    
        return in_list->head;                       // we are returning pinter to new_node
    }
    
    // Print out list
    void print_list(list* in_list)
    {
        node* node;
    
        if (in_list == NULL)
        {
            return;
        }
    
        if (in_list->head == NULL)
        {
            printf("List is empty!\n");
            return;
        }
    
       printf("List: ");
    
       node = in_list->head;
    
        while(node != NULL)
        {
            printf(" %d", node->data);
    
            node = node->next;
        }
    
        printf("\n");
    }
    
    struct node *find(struct node *start, int data)             // find p to be removed
    {
        node* node;
    
        if (start == NULL)
            return NULL;
    
        node = start;
    
        while(node != NULL)
        {
            if (node->data == data)
                return node; 
    
            node = node->next;
        }
    
        return NULL;
    }
    
    int delete(struct node *start, int data){
    // This function will crash if start == p 
    // Has other problems too  
    // For better implementation see sg7_delete.  
         struct node *q, *p;
    
         p = find(start, data);
         if (p != NULL){
             q = start;
             while (q->next != p){
                q = q->next;
             }
    
             q->next = p->next;   
             free(p);    
    
             return 1;     
         }
         return 0; 
    }
    
    int sg7_delete(struct node **start, int data)
    {
         struct node *p, *prev, *next, *to_free;
    
         if (start == NULL)                      // protection
            return 0;
    
         p = find(*start, data);                 // find p to be removed
    
         if (p == NULL)
            return 0;
    
         if (*start == NULL)
            return 0;                            // protection
    
         if(*start == p)                         // head == p
         {
            if((*start)->next !=NULL)
            {
                *start = (*start)->next;         // remember next 
                free(p);
                printf("Head removed\n");
                return 1;
            }
            else // the only node
            {
                free(p);
    
                printf("Last node removed\n");
                *start = NULL;
    
                return 1;
            }
         }
    
         // p != start:
    
         next = *start; 
    
         while (next != NULL)
         {
            prev = next;                       
            to_free = next->next;                // candidate to be freed   
    
           if( to_free == p )
            {
                prev->next = to_free->next;      // connect nodes before deletion 
    
                free(to_free);                   // now free the remembered `next`
                to_free = NULL;                  // so it does not point to the released memory
                return 1;
            }
    
            next = next->next;                   // this node was not a match 
         } //while
    
        return 0; 
    }
    
    int main() {
    
       list* new_list = list_create();
    
       node *n1 = node_new(1);
       node *n2 = node_new(2);
       node *n3 = node_new(3);
    
      // list is empty
       print_list(new_list);
    
       prepend_node(new_list, n1);
       prepend_node(new_list, n2);
       prepend_node(new_list, n3);
    
      // list has 3 elements
       print_list(new_list);
    
       sg7_delete(&new_list->head, 3);  
       print_list(new_list);
    
       sg7_delete(&new_list->head, 1);  
       print_list(new_list);
    
       sg7_delete(&new_list->head, 2);
       // list has 2 elements
       print_list(new_list);
    
       printf("head: %p\n",new_list->head);
    
       print_list(new_list);
    
    #if 0     
       // printf("TEST OF THE ORIGINAL FUNCTION\n");
       n1 = node_new(1);
       n2 = node_new(2);
       n3 = node_new(3);
    
       prepend_node(new_list, n1);
       prepend_node(new_list, n2);
       prepend_node(new_list, n3);
    
       print_list(new_list);
    
       delete(new_list->head, 1);   // REMOVE THE TAIL 
    
       print_list(new_list);
    
       //delete(new_list->head, 3); // WILL CRASH IF HEAD IS REMOVED - signal 11
       //delete(new_list->head, 2); // WILL CRASH IF HEAD IS REMOVED - signal 11
    #endif
    
      free (new_list); // after deleting all elements, delete the list itself
      return 0;
    }
    

    输出:

    List is empty!
    List:  3 2 1
    Head removed
    List:  2 1
    List:  2
    Last node removed
    List is empty!
    head: (nil)
    List is empty!
    

    【讨论】:

      猜你喜欢
      • 2013-12-21
      • 2018-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-28
      • 1970-01-01
      相关资源
      最近更新 更多