Я встречал так много кодов в полиноме, который создает полином с использованием двойных указателей в качестве аргументов, и в следующем коде у меня есть вопрос, почему новый узел создается для следующего указателя типа Node. Если возможно, кто-нибудь может объяснить мне, как работает этот код.

struct Node 
{ 
    int coeff; 
    int pow; 
    struct Node *next; 
}; 

// Function to create new node 
void create_node(int x, int y, struct Node **temp) 
{ 
    struct Node *r, *z; 
    z = *temp; 
    if(z == NULL) 
    { 
        r =(struct Node*)malloc(sizeof(struct Node)); 
        r->coeff = x; 
        r->pow = y; 
        *temp = r; 
        r->next = (struct Node*)malloc(sizeof(struct Node)); 
        r = r->next; 
        r->next = NULL; 
    } 
    else
    { 
        r->coeff = x; 
        r->pow = y; 
        r->next = (struct Node*)malloc(sizeof(struct Node)); 
        r = r->next; 
        r->next = NULL; 
    } 
} 

Вызов функции осуществляется из main:

    struct Node *poly1 = NULL, *poly2 = NULL, *poly = NULL; 

        // Create first list of 5x^2 + 4x^1 + 2x^0 
        create_node(5,2,&poly1); 
        create_node(4,1,&poly1); 
        create_node(2,0,&poly1); 
// Create second list of 5x^1 + 5x^0 
    create_node(5,1,&poly2); 
    create_node(5,0,&poly2); 
-1
Ayush Mishra 22 Сен 2018 в 11:41

2 ответа

Лучший ответ

Нет необходимости в особых случаях; вместо этого просто используйте указатель на указатель:


void create_node(int x, int y, struct Node **temp) 
{ 
    struct Node *this;
    this = malloc(sizeof *this);
    this->next = *temp;    // steal the parent's pointer.
    this->coeff = x;    
    this->pow = y;    
    *temp = this;          // and put ourself in front of it
} 

Обратите внимание, что если исходный список пуст, * temp будет NULL, а this-> next также будет установлено в NULL. (это то, что мы хотим)

0
wildplasser 22 Сен 2018 в 13:29

почему для следующего указателя типа Node создается новый узел.

Просто потому, что автору захотелось это сделать. Код тоже можно было написать так. Но показанный код имеет неопределенное поведение, поскольку r разыменовывается в else - части без предварительной инициализации и, скорее всего, является недопустимым значением указателя.

Придется пройти от *temp (z - нарисуйте лучшие имена) через все существующие узлы, а затем добавить новый узел:

void create_node(int x, int y, struct Node **temp)
{
    struct Node *r, *z;
    z = *temp;
    if (!z)
    {
        r = malloc(sizeof(struct Node)); // do not cast the result of malloc()!
        r->coeff = x;
        r->pow = y;
        r->next = 0;
        *temp = r;
    }
    else
    {
        r = z;
        while (r->next)
            r = r->next;

        r->next = malloc(sizeof(struct Node));
        r = r->next;
        r->coeff = x;
        r->pow = y;
        r->next = 0;
    }
}
2
Swordfish 22 Сен 2018 в 09:03