0

I almost figured out this code, but there are two details I can't figure out. I found this code on YouTube. source: https://www.youtube.com/watch?v=VOpjAHCee7c

#include <stdio.h>
#include <stdlib.h>

typedef struct node{
    int vaule;
    struct node *next;
}node_t;

void printlist(node_t *head)
{
    node_t *temp = head;

    while(temp != NULL)
    {
        printf("%d - ", temp->vaule);
        temp = temp->next;
    }
    printf("\n");
}

node_t *create_node(int var)
{
    node_t *res = malloc(sizeof(node_t));
    res->vaule = var;
    res->next = NULL;

    return res;
}

node_t *insert_at_head(node_t **head, node_t *node_to_insert)
{
    node_to_insert->next = *head;
    *head = node_to_insert;

    return node_to_insert;          
}

void find_node()

int main()
{
    node_t *tmp;
    node_t *head = NULL;

    for(int i = 0; i < 15; i++)
    {
        tmp = create_node(i);
        head = insert_at_head(&head, tmp);
    }

    printlist(head);

    return 0;
}

1) Why do we use the nested struct?

typedef struct node{
    int vaule;
    struct node *next;
}node_t;

I know about nested structures but I didn't understand why we use it here.

2) Why do we use double pointer?

node_t *insert_at_head(node_t **head, node_t *node_to_insert)
{
    node_to_insert->next = *head;
    *head = node_to_insert;

    return node_to_insert;          
}

if I change this code like this:

node_t *insert_at_head(node_t *head, node_t *node_to_insert)
{
    node_to_insert->next = head;


    return node_to_insert;          
}

then nothing will change

Sesion S
  • 5
  • 3
  • Q1: because the compiler does not yet know what the type `node_t` is, but knows that `struct node` is self referential. It is not a nested `struct`, but a pointer element (to another `struct`). – Weather Vane Apr 03 '20 at 13:08
  • _if I change this code like this:....then nothing will change_: what makes you think that? – Jabberwocky Apr 03 '20 at 13:13
  • Oh yes sorry. I confused the nested and the pointer. – Sesion S Apr 03 '20 at 13:13
  • Usually, you either use a double pointer or return the new pointer, but the original `insert_at_head` does both for some reason. The statement `head = insert_at_head(&head, tmp);` is modifying `head` twice between sequence points and is therefore invoking _undefined behavior_. (There is a sequence point before a standard library function returns, but this function is not a standard library function.) – Ian Abbott Apr 03 '20 at 13:17

2 Answers2

0
  1. Why do we use the nested struct?
    It's not a nested struct. struct node *next is a pointer, and as its name indidcates, it points to the next element.

  2. Why do we use double pointer?
    Read this: How do I modify a pointer that has been passed into a function in C?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
0

1)Why do we use the nested struct?

It is not a nested struct, but a linked list. Each node has a pointer to the next node (or to NULL for the last node of a list

2)Why do we use double pointer?

C only passes parameters by value. The idiomatic ways to change a variable from the caller are:

  1. assign the return value to that variable. It is the best way, but you can only return one single value that way
  2. pass a pointer to the variable and use the pointer to change the value. As we want to change the value of head which is already a pointer, we have to pass a pointer to pointer.

Here the write of the code has decided to change the passed header to clearly show that it is an input/output parameter, and also returns it because it had no better value to return.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252