There are no stupid questions1. Here's some pseudo-code to get you started:

def printAll (node):
    while node is not null:
        print node->payload
        node = node->next

printAll (head)

That's it really, just start at the head node, printing out the payload and moving to the next node in the list.

Once that next node is the end of the list, stop.


1 Well, actually, there probably are, but this isn't one of them :-)

Answer from paxdiablo on Stack Overflow
🌐
Reddit
reddit.com › r/c_programming › how to create a function for printing a linked list with multiple data? ( c language)
r/C_Programming on Reddit: How to create a function for printing a linked list with multiple data? ( C language)
August 2, 2022 -

I have written a code to enter the name, age, department id, company name, and salary respectively, of employees from a text file into a linked list. Here are the details of the file, it is called employee.txt:

Peter 30 1001 Apple 8000

Joseph 50 1002 Oracle 4000

Mary 40 1003 Samsung 6000

Lilly 40 1203 Samsung 7000

Tony 50 1002 Oracle 3000

Jake 30 1005 Apple 3000

Sam 40 1007 Samsung 4000

Lisa 30 1300 Oracle 5000

Kate 50 1200 Apple 6000

Rick 50 1313 Apple 4000

However, I'm not sure how to print the linked list because there are data that belong to two structures. I'm fairly new to C programming so I only know how to print like single data (current->data). So I will be really grateful if someone can show me how it's done :)

My Code:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

struct personTag{

char name\[20\];

int age;

};

struct officialTag{

int deptId;

char cmpName\[20\];

double salary;

};

struct employeeTag{

struct personTag personalInfo;

struct officialTag officialInfo;

struct employeeTag \*next;

};

typedef struct employeeTag EmpTag;

typedef EmpTag *EmpTagPtr;

void insert(EmpTagPtr *s, char E_name[], int E_age, int E_deptid, char E_cmpname[], double E_salary);

int main()

{

EmpTagPtr start = NULL;



char E\_name\[20\];

int E\_age;

int E\_deptid;

char E\_cmpname\[20\];

double E\_salary;



//reading employee.txt file

FILE \*fp;

fp = fopen("employee.txt" , "r");



fscanf(fp, "%s,%d,%d,%s,%d" ,E\_name, &E\_age, &E\_deptid, E\_cmpname, &E\_salary);



while(!feof(fp))

{

	insert(&start, E\_name, E\_age, E\_deptid, E\_cmpname, E\_salary); //inserting data to the new node

	fscanf(fp, "%s,%d,%d,%s,%d" ,E\_name, &E\_age, &E\_deptid, E\_cmpname, &E\_salary);

}



fclose(fp);







return 0;

}

void insert(EmpTagPtr *s, char E_name[], int E_age, int E_deptid, char E_cmpname[], double E_salary)

{

EmpTagPtr current = \*s;

EmpTagPtr prev = NULL;



//create an empty node

EmpTagPtr newNode;

newNode = (EmpTag\*)malloc(sizeof(EmpTag));



//filling in the values

strcpy(newNode->[personalInfo.name](https://personalInfo.name), E\_name);

newNode->personalInfo.age = E\_age;



newNode->officialInfo.deptId = E\_deptid;

strcpy(newNode->officialInfo.cmpName, E\_cmpname);

newNode->officialInfo.salary = E\_salary;



newNode->next = NULL;



while(current != NULL && strcmp(current->[personalInfo.name](https://personalInfo.name) , prev->[personalInfo.name](https://personalInfo.name)) >0 )

{

	prev = current;

	current = current->next;

}



if(prev == NULL)

{

	//add as the first node

	newNode->next = \*s;

	\*s = newNode;

}

else

{

	prev->next = newNode;

	newNode->next = current;

}

}

Discussions

pointers - Printing a linked list in C program - Stack Overflow
Connect and share knowledge within a single location that is structured and easy to search. Learn more about Teams ... I have see some other posts about how to print out a linked list, but none of them were helpful to me, so I decided to post my own code. More on stackoverflow.com
🌐 stackoverflow.com
How to print Linked List in C? - Stack Overflow
What do u want to print really? Exemplify. Dr. X – Dr. X · 2017-10-10 08:09:56 +00:00 Commented Oct 10, 2017 at 8:09 ... Your problem is that the linked list N is created inside CreateList, but that the changes aren't made to list in main. Look at the many linked-list examples here for how ... More on stackoverflow.com
🌐 stackoverflow.com
C program to create and print a linked list from the command line - Code Review Stack Exchange
Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... This program will create a linked list, set the values, and print the list by using command line options. More on codereview.stackexchange.com
🌐 codereview.stackexchange.com
April 22, 2017
pointers - Print a linked list in C - Stack Overflow
I am working to develop a linked ... I chose to write this part in C because writing it in assembly wouldn't be very fun. I can successfully make a linked list from a series of elements with the list function below. I have verified that it works, shown by the examples in main below. But why does my function print_list only ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Open Tech Guides
opentechguides.com › how-to › article › c › 141 › linkedlist-add-del-print-count.html
C program to add, remove, print, and traverse a linked list
September 15, 2017 - ****************************************** * Linked list operations: * * 1. Add * * 2. Remove * * 3. Count * * 4. Print * * 5. Quit * ****************************************** Choose an option [1-5] : 1 Enter a number to add : 25 Number 25 is now added to the list Press any key to continue...
🌐
TutorialsPoint
tutorialspoint.com › article › print-nodes-of-linked-list-at-given-indexes-in-c-language
Print nodes of linked list at given indexes in C language
August 22, 2019 - Unlike arrays, linked lists don't ... until we reach the desired index. void printAtIndex(struct node* head, int index); void printMultipleIndexes(struct node* head, int indexes[], int size); This example demonstrates how to print ...
Top answer
1 of 4
1

While you have defined head and end pointers, which would make a linked list, you are not actually using these to store your new information. After having created your new node and storing it in the ptr variable, you don't actually store it in the list.

I would suggest adding another method, addnode, which adds this newly-created node to the linked list defined by the head and end pointers.

void addnode(struct node *ptr) {
    if (end == NULL) {
        head = ptr;
        end = ptr;
    }
    else {
        end = end->next = ptr;
    }
}

Broadly, we check if we have any items already in the list; if not, both the start and the end of the list will be represented by the same node: the only one in the list! Otherwise, we let the node after the current end be the node to add, and then move our global end pointer to what is now the last node.

This allows us to maintain a chain of more than one node (entry in the list). We must then, when printing the entire list, follow this entire chain, from the first node (head) to the last. We can do this with a simple loop: instead of simply calling printnode() on the temporary ptr variable we maintain in main(), we write:

struct node *current = head;
while (current != end) {
    printnode(current);
    current = current->next;
}
2 of 4
1

Just a remamrk:

ptr = (struct node*) calloc(3, sizeof(struct node));

is wrong because you are allocating 3 * sizeof(struct node) and it should be

ptr = (struct node*) calloc(1, sizeof(struct node));

Your code is missing many things. you are not linking the node you create to any linked list. in the whole code you are not using next. You have to work more on this code.

The problem is not only coming from the print of the linked list. the problem come from how to create the linked list

I can suggest to you a template of linked list which can help in developing such program. this template contains functions and macro to treate linked list like

  • adding to linked list in the head
  • adding to linked list in the tail
  • removing from linked list...

you can get the linked list template (list.h) from this link

The following link contains an example of how use it

Please refer to this paragraph in the above link

With very little modifications (removing hardware prefetching of list items) we can also use this list in our applications. A usable version of this file is available here for download.

🌐
YouTube
youtube.com › watch
How to print a linked list in C Programming | Data Structures in C | C Programming for beginners - YouTube
How to print a linked list in C Programming | Data Structures in C | C Programming for beginnersWelcome to our beginner-friendly C programming tutorial! In t...
Published: May 15, 2025
🌐
log2base2
log2base2.com › data-structures › linked-list › linked-list-in-c.html
Linked List in C
3. last => next = NULL which indicates it is the last node in the linked list. 4. The simplified version of the heap memory section. To print each node's data, we have to traverse the linked list till the end. 1. Create a temporary node(temp) and assign the head node's address.
Find elsewhere
🌐
GeeksforGeeks
geeksforgeeks.org › dsa › print-linked-list
Print Linked List - GeeksforGeeks
August 6, 2025 - ... #include <iostream> using namespace ... new_data; this->next = nullptr; } }; // Function to print the singly linked list void printList(Node* head) { // A loop that runs till head is nullptr while (head != nullptr) { // Printing data ...
🌐
Sanfoundry
sanfoundry.com › c-program-display-linked-list-without-recursion
C Program to Print All Nodes of Linked List without Recursion - Sanfoundry
May 17, 2022 - This C program, using iteration, displays a linked list. A linked list is an ordered set of data elements, each containing a link to its successor. Here is the source code of the C program to display a linked list. The C program is successfully compiled and run on a Linux system.
Top answer
1 of 3
5

Your program largely accomplishes the core goal you set out to achieve: build and print linked lists from the command line. You seem to understand the singly-linked list data structure and related algorithms for adding nodes and traversing quite well. That said, there are several opportunities for improvement in your code related to the linked list implementation itself and for general programming practices.

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

unitstd.h is widely supported, but not a standard library. Consider replacing it for increased portability.

struct node{
    int value;
    struct node *next_ptr;
};

As @pacmaninbw mentioned, consider using a typedef here so you can later use just node instead of struct node. Exact naming is debatable.

struct node *head;

Try very hard to avoid global variables like this. Instead, it's almost always preferable to pass variables as function parameters. In this case, move head inside main and pass it as a new parameter to add_node and print_nodes.

Note that in order to change head as a local variable of main from either add_node or print_nodes you'll need to pass a struct node** instead of just a struct node. The reason for this is that parameters are local variables, so if add_node were to set its head parameter it would only be changing its copy and not the copy held by main. Instead, if the parameter is struct node** then main can pass a pointer to its local copy by passing &head and add_node can change the copy in main by indirection: *head = X.

void add_node(int data);
void print_nodes(void);

Forward-declaring functions is fine and in this small program a mostly stylistic choice that allows you to put main before add_node and print_nodes. Alternatively, you could put main last and avoid the forward declarations. One advantage of that approach is that you won't need to change two places when you change the signature of these functions, such as adding head as a parameter.

int main(int argc, char *argv[]){
    int c;
    long node_value;
    char *ptr;
    char *token;
    const char s[2] = " "; /*Split optarg based on this string*/

It's generally considered good practice to declare variables as close to their usage as possible to limit their scope and reduce the number of variables readers and maintainers need to keep in their heads. In this case, only c needs to be declared at this point. The rest of the variables can be declared within the while loop's block or, by adding curly braces to make blocks inside the case labels.

    while((c = getopt(argc, argv, "pa:")) != EOF){

Note that if you drop the #include <unistd.h> you'll need to come up with an alternative to getopt. That should be pretty easy, but may complicate the code slightly. You may want to literally implement your own version of getopt but you may also settle for replacing this loop with a loop over the argv array that reads pairs of arguments at index i and i+1.

        switch(c){
        case 'p':
            print_nodes();

It's fine, and commonplace, to break out code into its own function. You may also prefer the aesthetics of it. However, for completeness, I'll mention one drawback. In this case print_nodes is only ever called from one place. You could copy its body here and avoid the function call. Most optimizing compilers will do this for you, so this won't result in a performance gain. What it will help, arguably, is readability.

Readers of main currently need to suspend their progress through this function and jump to another location in the file. They need to remember mappings of parameters to the corresponding values in main. Then when they're done reading print_nodes they need to remember where they were in main and jump back to that location in the file. Some text editors and IDEs can help with the jumping, but there is an increase in cognitive load that's caused by splitting out this code into another function and you might want to consider removing it until such time as you have multiple callers.

            break;
        case 'a':
            token = strtok(optarg, s); /*Split the string*/
            while(token != NULL){
                node_value = strtol(token, &ptr, 10); /*Convert each string to integer*/

As mentioned in some other code reviews, there are a couple of issues here. First is that strtol returns a long int and you're assigning it to just an int. Depending on the integer sizes of your platform, long int and int may not have the same size. You can fix this in several ways, but you may want to consider simply changing the values held in the linked list from int to long int. Alternatively, you may need to do some conversion and/or raise an error if the given value fits in long int but not in the sometimes-smaller int.

                if((*ptr) != 10 && (*ptr) != 0){ /*If it's not a newline or a null then invalid input*/

The second issue the lack of error checking. This error checking doesn't cover all of the error cases. If the user puts in a non-integer string such as foo then strtol will return 0. This is unfortunately difficult to detect as an error as 0 is a valid integer value. If the value is out of range, you can check errno to see if it's been set to ERANGE. This is expensive and awkward error handling, especially for such a simple function. You might consider writing your own version such as the one mentioned in the review by @pacmaninbw.

                    fprintf(stderr, "Invalid number: %c", *ptr);
                    exit(EXIT_FAILURE);

Also as mentioned in other reviews, calling exit is fine in such a small program but generally not a very good way to handle errors. This is especially true when handling program inputs that are outside of the code's control. Instead, most programs aim to gracefully fail by reporting the error (which you did) but then continue on. If the error is truly fatal to the program, as in this case, then exit may be warranted.

                }
                add_node(node_value);

As with print_nodes there is only one call site to add_node so you could consider moving its body here and removing add_node.

                token = strtok(NULL, s);
            }
            break;
        default:
            fprintf(stderr, "Unknown option %c, available options are '-p' and 'a'", c);
            break;

This error is handled by (indirectly) returning 0 (success). In the case of an invalid node value the error is handled by returning (via exit) the failure value. Since this is just as fatal of an error as above, you should return the same error code to indicate to the OS that the program has terminated with an error, not successfully.

        }
    }
    argc -= optind;
    argv += optind;

Changing these local variables is unnecessary at this point because neither is used before returning.

    return 0;

Like with your use of EXIT_FAILURE above, you should use EXIT_SUCCESS here. Doing so doesn't require the reader to know that 0 indicates success, even though that is common knowledge.

}

void add_node(int data){
    struct node *temp = head;

    if(temp == NULL){

head is never initialized by your code, so its value will be undefined the first time this function runs. Sometimes the compiler will initialize it to NULL for you, especially when building in "debug" mode so you may not have noticed this bug yet. When the compiler has not initialized head for you then it's exceedingly unlikely that it will happen to initially be NULL. In that case this if will be skipped and the (essentially random) memory pointed to by head will be accessed. It's also exceedingly unlikely that such memory will be available to your program, so the OS will almost certainly terminate your program with a "crash". The same goes for other uses of head, such as in print_nodes.

        head = malloc(sizeof(struct node));
        head->value = data;
        head->next_ptr = NULL;
        return;

Some programmers frown on "early returns" or "multiple returns". It's mostly a stylistic choice, but one you should be aware of. Instead, you could add an else and put the rest of the function in it.

    }

    while(temp->next_ptr != NULL){
        temp = temp->next_ptr;
    }

If you were to keep track of the "tail" or "end" of the list, as you do with head then you could skip this loop. It's actually an extremely expensive loop as it will continually read from memory scattered all through RAM. It's highly likely that every iteration of this loop will cause a CPU cache miss and the entire cache will need to be purged in order to be refilled with the memory at the next node's location. Keeping a "tail" pointer will require a tiny (4 or 8 byte) additional usage of memory but your code will execute much more quickly.

    if((temp->next_ptr = malloc(sizeof(struct node))) == NULL){
        fprintf(stderr, "Out of memory");
        exit(EXIT_FAILURE);
    }

Checking for a NULL return from malloc is usually a good idea, but in this case it is arguably unnecessary. If you're allocating a gigabyte then it's possible that the allocation will fail. If you're allocating one struct node (approximately 8-16 bytes) and the OS is unable to return that amount of memory then the computer is likely going to crash anyhow. You probably won't be able to even print the error as the system has basically no memory left. So in this case it's probably better to skip the check for the sake of reduced amount of code which means there's less to type, less to read, and the executable is smaller.

    temp = temp->next_ptr;
    temp->value = data;
    temp->next_ptr = NULL;
}

void print_nodes(void){
    struct node *temp = head;
    if(temp == NULL){
            printf("Linked list is empty\n");
    }
    for(temp = head; temp != NULL; temp = temp->next_ptr){
        printf("%i\n", temp->value);
    }
}

This is a "textbook" implementation of a singly-linked list in its simplest form. If, however, you wanted to go further there is an optimization that would greatly increase its performance and memory utilization efficiency. As I mentioned in the comment about traversing the list being extremely slow, this is largely due to each node existing in essentially a random location in memory. The exact location is beyond your control as malloc makes this decision. Also, malloc is likely to allocate a "block" of memory much larger than the 8-16 bytes you requested, which decreases your memory utilization efficiency. You're also making one call to malloc per node, which is quite slow in itself as malloc is quite slow and will result in even more cache misses.

To combat these problems, you could change how you allocate the nodes of the linked list. Currently you're allocating them one-by-one as you parse the command line arguments. Instead, you could count the number of command line arguments and allocate an array of that many nodes. This would be trivial if you also adjust the format of the command line parameters so that the node values are passed individually rather than as a single string containing all of them.

Once you have allocated this array of nodes it should be a simple matter of assigning each node's next_ptr to the address of the next node in the array and the value to whatever you parsed from the corresponding command line argument. Of course the last node's next_ptr should be set to NULL.

The advantage of this scheme is that all of the nodes will be stored sequentially in memory. When you access the first one, the CPU will cache the next several nodes in much faster memory such as L1 or L2 cache. As you traverse the list, you'll be accessing that cache instead of fetching from main system memory which is usually an order of magnitude slower.

This is, of course, an optional optimization that will slightly complicate your code just like keeping a tail pointer around. There are tradeoffs in complexity, memory, and performance to consider as I mentioned above and it's up to you to weight these concerns. Overall, good job on this program and I hope this code review was helpful!

2 of 3
7

Nice formatting, good variable and function names. I learned more about getopt() from the program (I used to have to write my own command line parsers)! Good use of system macros such as EXIT_FAILURE.

Using Typedef

If the code used typedef for the definition of node, the code might be slightly shorter and more readable:

typedef struct node{
    int value;
    struct node *next_ptr;
} Node;

Node *head;

void add_node(int data){
    Node* temp = head;

    /* ... */
}

void print_nodes(void){
    Node* temp = head;

    /* ... */
}

By using typedef a new type is created. This also might decrease the possibility of future errors by forgetting to put the struct in at some point. This stackoverflow question discusses why it might be good to use typedef.

Global Variables

Generally the use of global variables are frowned upon. When creating, reading and debugging code global variables can be affected by side affects and it can be very difficult to find where the problem is actually occurring. This stackoverflow question talks about when it is proper to use global variables.

It might be better if the global variable NODE *head was declared in main() and then passed by reference into each function that modified it, and passed by value into each function that only used it and didn't change it.

Passing head into each of the functions would make the following changed necessary:

        case 'p':
    /*+>*/  print_nodes(head);      /* Pass by value */
            break;


            while(token != NULL){
                node_value = strtol(token, &ptr, 10); /*Convert each string to integer*/
                if((*ptr) != 10 && (*ptr) != 0){ /*If it's not a newline or a null then invalid input*/
                    fprintf(stderr, "Invalid number: %c", *ptr);
                    exit(EXIT_FAILURE);
                }
    /* ++> */   add_node(node_value, &head);        /* Pass by reference */
                token = strtok(NULL, s);
            }


void add_node(int data, Node **head){
    Node* temp;

    if(*head == NULL){
        *head = malloc(sizeof(struct node));
        (*head)->value = data;
        (*head)->next_ptr = NULL;
        return;
    }

    temp = *head;
    while(temp->next_ptr != NULL){
        temp = temp->next_ptr;
    }

    if((temp->next_ptr = malloc(sizeof(struct node))) == NULL){
        fprintf(stderr, "Out of memory");
        exit(EXIT_FAILURE);
    }

    temp = temp->next_ptr;
    temp->value = data;
    temp->next_ptr = NULL;
}

void print_nodes(Node* head){
    Node* temp = head;
    if(temp == NULL){
        printf("Linked list is empty\n");
    }
    for(temp = head; temp != NULL; temp = temp->next_ptr){
        printf("%i\n", temp->value);
    }
}

This example might make the program safer and easier to debug and read.

Implicit Type Conversion

My compiler flagged the following line as an implicit type conversion:

            add_node(node_value);

because node_value is declared as a long rather than int,

    long node_value;

void add_node(int data) { /* ... */

If node_value needs to be a long because that's what strtok() is returning, it might be better to either change the input type for add_node() or to explicitly cast node_value in the call:

            add_node((int) node_value);

The actual warning message I get is implicit conversion loses integer precision: 'long to int' (Xcode 8.2 on El Capitan).

Functions that might be helpful

To implement a full linked list program some functions that might be helpful are:

NodePointer new_node(int value);
NodePointer delete_node_by_value(int value, NodePointer head);
NodePointer delete_node_by_pointer(NodePointer delete_target, NodePointer head);
NodePointer find_node(int value, NodePointer head);
void print_node(int value, NodePointer head);       // called by print_nodes

Use of the exit() Function

The use of the exit() function can be problematic, in a large software system that one is writing only a piece of, it would be better to return an error code from the add_node() function rather than call exit. In some cases such as operating systems calling exit() can have dire consequences (shut down).

The C programming language was originally created to implement operating systems and in some cases is still used for that purpose. While C doesn't have the exception throwing capabilities of C++, Java, C# and other more modern languages errors can be handled, either by returning error codes or using setjmp() and longjmp().

🌐
GitHub
github.com › amritanand-py › cps02 › blob › main › O 01 - Printing a Linked List.c
cps02/O 01 - Printing a Linked List.c at main · amritanand-py/cps02
* Complete the function below. · */ · /* · For your reference: · LinkedListNode { · int val; · LinkedListNode *next; · }; · */ · void print(LinkedListNode* head) { · if(head==NULL) · return; · printf("%d\n",head->val); ·
Author: amritanand-py
🌐
Stack Overflow
stackoverflow.com › questions › 64264869 › print-a-linked-list-in-c
pointers - Print a linked list in C - Stack Overflow
#include <stdio.h> #include <stdarg.h> typedef struct Node Node; struct Node { int head; // make to a union later Node* tail; }; ////////// Node cons(int curr, Node* next) {Node cell = {curr, next}; return cell;} int car(Node node) {return node.head;} Node* cdr(Node node) {return node.tail;} ////////// void print_elems(Node node) { printf("%d", node.head); if (node.tail == NULL) return; printf(" "); print_elems(*node.tail); } void print_list(Node node) { printf("("); print_elems(node); printf(")\n"); } ////////// Node make_pairs(va_list args, int argc) { Node linked_list; linked_list.head = va
🌐
Aleksandar Haber
aleksandarhaber.com › linked-lists-in-the-c-programming-language-define-print-and-erase-elements-of-linked-lists
Linked Lists in the C Programming Language – Define, Print, and Erase Elements of Linked Lists – Fusion of Engineering, Control, Coding, Machine Learning, and Science
In every iteration of the while loop, we print the entry stored in the current node (that is pointed by the current value of p_current_node). Then, we simply move through the list by using this statement: ... Before we can compile and execute the program, it is very important to erase all the nodes in the linked list.
🌐
w3resource
w3resource.com › c-programming-exercises › linked_list › c-linked_list-exercise-1.php
C Program: To create and display Singly Linked List - w3resource
#include <stdio.h> #include <stdlib.h> ... of the program printf("\n\n Linked List : To create and display Singly Linked List :\n"); printf("-------------------------------------------------------------\n"); // Input...
🌐
GitHub
gist.github.com › 94f465a338f58dc48944
Print the Elements of a Linked List · GitHub
Print the Elements of a Linked List. GitHub Gist: instantly share code, notes, and snippets.
Top answer
1 of 6
1

I assume you're talking about the C implementation in "Language support".

It doesn't print in reverse order. It's because elements are inserted in the head of the list, so inserting 1, 2, 3 would result in a list that contains 3, 2, 1.

This is because the list is represented by its head, so it's faster inserting at the head than the tail. To insert at the tail you would have to go through the entire list. This makes insertion O(n) instead of O(1).

Seeing as this is a singly-linked list, you cannot print it in the other order because you can only step forward.

2 of 6
0

Looking at the following example:

/****************************************************************/
/*  Function: Add an element to our list                        */
/*                                                              */
/*   Parameters: **p is the node that we wish to insert at.     */
/*               if the node is the null insert it at the beginning    */
/*               Other wise put it in the next space                   */


LLIST *list_add(LLIST **p, int i)
{
    if (p == NULL)           /*checks to see if the pointer points somewhere in space*/
        return NULL;

    LLIST *n = malloc(sizeof(LLIST));   /* creates a new node of the correct data size */
    if (n == NULL)
        return NULL;

    n->next = *p; /* the previous element (*p) now becomes the "next" element */
    *p = n;       /* add new empty element to the front (head) of the list */
    n->data = i;

    return *p;
}

Elements are being added to the beginning of the linked list when you call list_add. This is for efficiency reasons; you don't have to transverse the entire linked list to insert an element (which you would have to do if you wanted to append).

To print in reverse, you can use recursion, build your own stack (which is the blind man's recursion), or recreate the list in reverse. A recursive version:

void list_print_reverse(LLIST *n)
{
    if (n == NULL)
    {
        printf("list is empty\n");
        return;
    }

    if (n->next != NULL)
    {
        list_print_reverse(n->next);
    }

    printf("print %p %p %d\n", n, n->next, n->data);
}
Top answer
1 of 6
5

It is obvious that function addNewPerson is wrong.

node* addNewPerson(node* head)
{
    node* person = new node;

    cout << "Name: ";
    cin >> person->name;

    person->next = NULL;

    if (head == NULL) //is empty
    {
        head = person;
    }

    else
    {
        person = person->next;
    }

    return head;
}

You allocated new node person.

    node* person = new node;

Set its field next to NULL

    person->next = NULL;

Then if head is not equal to NULL you set person to person->next

        person = person->next;

As person->next was set to NULL it means that now also person will be equal to NULL.

Moreover the function returns head that can be changed in the function. However you ignore returned value in main

addNewPerson(head);

At least there should be

head = addNewPerson(head);

The valid function addNewPerson could look the following way

node* addNewPerson(node* head)
{
    node* person = new node;

    cout << "Name: ";
    cin >> person->name;

    person->next = head;
    head = person;

    return head;
}

And in main you have to write

  for (unsigned short i = 1; i <= people; i++)
  {
    head = addNewPerson(head);

    cout << endl;
  }

Function printList does not output the whole list. It outputs only data member name of the first node that is of head.

void printList(node* head)
{
    node* temp = head;

    cout << temp->name << endl;
}

It should look the following way

void printList(node* head)
{
  for ( ; head; head = head->next )
  {
    cout << head->name << endl;
  }
}

And at last main should look as

int main()
{
    node* head = NULL;

    unsigned short people = 0;

    cout << "How many people do you want to invite to the party?" << endl;
    cout << "Answer: ";
    cin >> people;

    cout << endl;

    for ( unsigned short i = 0; i < people; i++ )
    {
        head = addNewPerson(head);

        cout << endl;
    }

    cout << "LIST: " << endl;
    cout << endl;

    printList( head );

    cin.get();
}
2 of 6
0

In your addNewPerson function person->next never gets set, because head is always NULL.