1
\$\begingroup\$

I'm working through a practice problem that is having me build and modify a linked list over a series of steps. I am particularly interested in knowing if there's a more elegant way of prompting the user to input a data value for a new element in a linked list (see step 5 below).

I'd also like to know if there's a better way of counting and returning the number of elements in a linked list.

Practice Problem:

  • Step 4: Add a function trav_and_print to your program that will traverse the linked list and print the values of all of the data members.
  • Step 5: Add code to your program that will add another element to the end of the linked list. Prompt the user for the data value. Call your trav_and_print function, and also from main print the value of last -> data to make sure that the element was added correctly.
  • Step 6: Add another function count_elems that will traverse the linked list, count how many elements there are, and return that count. Test this function by calling it in various places in main, including before there are any elements in the linked list.

My code thus far:

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

typedef struct linked_list
{
   int data;
   struct linked_list *next;
}   element;

typedef element * elementptr;

void trav_and_print(elementptr);

int count_elems(elementptr);

int main()
{
   elementptr first = NULL;
   elementptr last = NULL;
   int var = 0;
   int NumElems = 0;

   /* Create a linked list with one element            */
   /* NOTE: the first element is always a special case */

   first = (elementptr) malloc(sizeof(element));
   last = first;
   last -> data = 5;
   last -> next = NULL;

   /* Add another element to the end of the list */

   last -> next = (elementptr) malloc(sizeof(element));
   last = last -> next;
   last -> data = 12;
   last -> next = NULL;

   /*Add another element to the end of the list;
   user generated number*/

   last -> next = (elementptr) malloc(sizeof(element));
   last = last -> next;
   printf("Enter the data value to add to the linked list: ");
   scanf("%d",&var);
   last -> data = var;
   last -> next = NULL;

   trav_and_print(first); //prints the linked list

   NumElems = count_elems(first); //traverses and counts the elements in the linked list

   printf("Number of elements in the linked list: %d",NumElems);

   free(first);
   free(last);

   return 0;
}
void trav_and_print(elementptr f)
{
    elementptr current;

    current = f;
    if(current == NULL)
        printf("There is no linked list!\n");
    else
        while (current != NULL)
    {
        printf("The data value is %d\n",current->data);
        current = current -> next;
    }
}
int count_elems(elementptr f)
{
    int count = 0;
    elementptr current;
    current = f;
    while(current != NULL)
    {
        current = current->next;
        count++;
    }
    return count;
}
\$\endgroup\$
  • 1
    \$\begingroup\$ OT: regarding: typedef element * elementptr; it is a poor programming practice to hide a pointer in a typedef. \$\endgroup\$ – user3629249 Apr 23 at 22:39
  • 2
    \$\begingroup\$ OT: regarding: first = (elementptr) malloc(sizeof(element)); 1) the returned type (in c) is void* which can be assigned to any pointer. Casting just clutters the code, making it more difficult to understand, debug, etc 2) when calling any of the heap allocation functions: malloc() calloc() realloc() always check (!=NULL) the returned value to assure the operation was successful \$\endgroup\$ – user3629249 Apr 23 at 22:42
  • 1
    \$\begingroup\$ The current implementation of the program has a possible memory leak because it only deletes the head and the tail of the linked list. If an entire linked list needs to be deallocated or deleted, there should be a function that traverses the linked list and deletes each node. \$\endgroup\$ – pacmaninbw Apr 24 at 15:14
  • 1
    \$\begingroup\$ Always test the return value of malloc(size_t size) to make sure it isn't NULL. The function malloc() returns NULL if it fails and it can fail for a variety of reasons such as not enough memory to allocate. In object oriented languages the new operator or the constructor will throw an exception in this case. \$\endgroup\$ – pacmaninbw Apr 24 at 15:14
  • 1
    \$\begingroup\$ For procedural languages there is a design methodology called Top Down Design (also known as Step-wise Refinement) that breaks the problem into smaller and smaller parts until all the parts are atomic. With linked lists some basic operations are insert node, append node, delete node and perhaps find node. There might also be new node that creates the node from user input. en.wikipedia.org/wiki/Top-down_and_bottom-up_design \$\endgroup\$ – pacmaninbw Apr 24 at 15:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.