未知"删除"我的C代码中的错误

时间:2018-02-22 02:06:08

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

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

  

"错误:预期';'之前' 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; 
}

3 个答案:

答案 0 :(得分:2)

错误本身就是一个语法错误 - C中没有太多代码,看起来像是删除p'。由于'删除'不是C中的预定义函数(不像' return'。返回1工作正常,虽然它看起来有点像删除p'),它被认为是一个分号是在删除'

之后需要

但是,即使你包含半冒号,它仍然不会因为之前的评论给出的原因而起作用。

替换'删除'与' free()'删除编译时错误,但仍需要更改

q->next;
p->next;

q->next = p->next;

即使删除后链接列表也要正确连接。

链接列表最初可能会让人感到困惑,因此建议您始终在计算机旁边的纸上绘制您要实现的内容。

祝你好运:)

答案 1 :(得分:0)

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

q->next;     
p->next; 

为:

q->next = p->next;

另外,正如其他人指出的那样,delete不在C中,它在C ++中。所以,接下来做出这样的改变:

delete p;

为:

free(p);

答案 2 :(得分:0)

  

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

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

以下程序的评论说明了这一点:

delete

/* $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; } standard处理C涉及您的特定情况。

Expression and null statements的逻辑需要大量的工作。 当前的响应都没有解决int delete(struct node *start, int data)内的所有逻辑问题。 delete时,所有解决方案都会崩溃。

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

  • free(...)是一个初始化的整数。您很可能打算使用dataAfter

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

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

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

  • 如果head是您要查找的节点,这是列表中唯一比删除后节点必须标记为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;
}