Introduction to Linked Lists
A linked list is a linear data structure where elements are stored in nodes, each containing a data field and a pointer to the next node. Unlike arrays, linked lists are dynamic and can grow or shrink during runtime without memory wastage.
Linked List Architecture
Singly Linked List Structure ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Data: 10 │ │ Data: 20 │ │ Data: 30 │ │ Next ────────>│ Next ────────>│ Next ────────> NULL └──────────┘ └──────────┘ └──────────┘ ^ ^ ^ | | | Head Tail (optional) Node Structure: ┌─────────────────┐ │ Data │ ├─────────────────┤ │ Next Pointer │ └─────────────────┘
Basic Node Structure
#include <stdio.h> #include <stdlib.h> // Node structure for singly linked list struct Node { int data; // Data stored in the node struct Node* next; // Pointer to the next node }; // Typedef for convenience typedef struct Node Node; Creating and Traversing Linked Lists
1. Creating a Simple Linked List
#include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node* next; } Node; int main() { // Create nodes Node* head = NULL; Node* second = NULL; Node* third = NULL; // Allocate memory for nodes in heap head = (Node*)malloc(sizeof(Node)); second = (Node*)malloc(sizeof(Node)); third = (Node*)malloc(sizeof(Node)); // Assign data and link nodes head->data = 10; head->next = second; second->data = 20; second->next = third; third->data = 30; third->next = NULL; // Last node points to NULL // Traverse and print the list printf("Linked List: "); Node* current = head; while (current != NULL) { printf("%d ", current->data); current = current->next; } printf("\n"); // Free allocated memory free(head); free(second); free(third); return 0; } Output:
Linked List: 10 20 30
2. Function to Create a New Node
#include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node* next; } Node; // Function to create a new node Node* createNode(int data) { Node* newNode = (Node*)malloc(sizeof(Node)); if (newNode == NULL) { printf("Memory allocation failed!\n"); return NULL; } newNode->data = data; newNode->next = NULL; return newNode; } int main() { // Create nodes using function Node* head = createNode(10); Node* second = createNode(20); Node* third = createNode(30); // Link nodes head->next = second; second->next = third; // Print list Node* current = head; printf("Linked List: "); while (current != NULL) { printf("%d ", current->data); current = current->next; } printf("\n"); // Free memory current = head; Node* next; while (current != NULL) { next = current->next; free(current); current = next; } return 0; } Basic Linked List Operations
1. Traversal
#include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node* next; } Node; // Function to print the linked list void printList(Node* head) { printf("Linked List: "); Node* current = head; while (current != NULL) { printf("%d ", current->data); current = current->next; } printf("\n"); } // Function to get length of linked list int getLength(Node* head) { int count = 0; Node* current = head; while (current != NULL) { count++; current = current->next; } return count; } // Recursive traversal void printListRecursive(Node* head) { if (head == NULL) { printf("\n"); return; } printf("%d ", head->data); printListRecursive(head->next); } int main() { // Create a simple list: 10 -> 20 -> 30 -> NULL Node* head = createNode(10); head->next = createNode(20); head->next->next = createNode(30); printList(head); printf("List length: %d\n", getLength(head)); printf("Recursive traversal: "); printListRecursive(head); // Free memory Node* current = head; while (current != NULL) { Node* temp = current; current = current->next; free(temp); } return 0; } 2. Insertion Operations
#include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node* next; } Node; // Insert at beginning Node* insertAtBeginning(Node* head, int data) { Node* newNode = createNode(data); newNode->next = head; return newNode; // New head } // Insert at end Node* insertAtEnd(Node* head, int data) { Node* newNode = createNode(data); if (head == NULL) { return newNode; } Node* current = head; while (current->next != NULL) { current = current->next; } current->next = newNode; return head; } // Insert at position (0-based index) Node* insertAtPosition(Node* head, int data, int position) { if (position < 0) { printf("Invalid position!\n"); return head; } if (position == 0) { return insertAtBeginning(head, data); } Node* newNode = createNode(data); Node* current = head; // Traverse to position-1 for (int i = 0; i < position - 1 && current != NULL; i++) { current = current->next; } if (current == NULL) { printf("Position out of range!\n"); free(newNode); return head; } newNode->next = current->next; current->next = newNode; return head; } // Insert after a given node void insertAfter(Node* prevNode, int data) { if (prevNode == NULL) { printf("Previous node cannot be NULL\n"); return; } Node* newNode = createNode(data); newNode->next = prevNode->next; prevNode->next = newNode; } int main() { Node* head = NULL; // Insert at beginning head = insertAtBeginning(head, 30); head = insertAtBeginning(head, 20); head = insertAtBeginning(head, 10); printf("After inserting at beginning: "); printList(head); // 10 20 30 // Insert at end head = insertAtEnd(head, 40); head = insertAtEnd(head, 50); printf("After inserting at end: "); printList(head); // 10 20 30 40 50 // Insert at position head = insertAtPosition(head, 25, 2); printf("After inserting 25 at position 2: "); printList(head); // 10 20 25 30 40 50 // Insert after a node insertAfter(head->next, 22); // After second node (20) printf("After inserting 22 after 20: "); printList(head); // 10 20 22 25 30 40 50 return 0; } 3. Deletion Operations
#include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node* next; } Node; // Delete first node Node* deleteFirst(Node* head) { if (head == NULL) { printf("List is empty\n"); return NULL; } Node* temp = head; head = head->next; free(temp); return head; } // Delete last node Node* deleteLast(Node* head) { if (head == NULL) { printf("List is empty\n"); return NULL; } if (head->next == NULL) { free(head); return NULL; } Node* current = head; while (current->next->next != NULL) { current = current->next; } free(current->next); current->next = NULL; return head; } // Delete node at position Node* deleteAtPosition(Node* head, int position) { if (head == NULL || position < 0) { return head; } if (position == 0) { return deleteFirst(head); } Node* current = head; for (int i = 0; i < position - 1 && current != NULL; i++) { current = current->next; } if (current == NULL || current->next == NULL) { printf("Position out of range\n"); return head; } Node* temp = current->next; current->next = temp->next; free(temp); return head; } // Delete by value (first occurrence) Node* deleteByValue(Node* head, int value) { if (head == NULL) { return NULL; } // If head node contains the value if (head->data == value) { Node* temp = head; head = head->next; free(temp); return head; } Node* current = head; while (current->next != NULL && current->next->data != value) { current = current->next; } if (current->next == NULL) { printf("Value %d not found in list\n", value); return head; } Node* temp = current->next; current->next = temp->next; free(temp); return head; } int main() { Node* head = NULL; // Create a list: 10 -> 20 -> 30 -> 40 -> 50 for (int i = 50; i >= 10; i -= 10) { head = insertAtBeginning(head, i); } printf("Original list: "); printList(head); // 10 20 30 40 50 // Delete first head = deleteFirst(head); printf("After deleting first: "); printList(head); // 20 30 40 50 // Delete last head = deleteLast(head); printf("After deleting last: "); printList(head); // 20 30 40 // Delete at position head = deleteAtPosition(head, 1); printf("After deleting at position 1: "); printList(head); // 20 40 // Delete by value head = deleteByValue(head, 20); printf("After deleting 20: "); printList(head); // 40 return 0; } 4. Search Operations
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> typedef struct Node { int data; struct Node* next; } Node; // Search for a value (iterative) bool searchIterative(Node* head, int key) { Node* current = head; while (current != NULL) { if (current->data == key) { return true; } current = current->next; } return false; } // Search for a value (recursive) bool searchRecursive(Node* head, int key) { if (head == NULL) { return false; } if (head->data == key) { return true; } return searchRecursive(head->next, key); } // Get node at position Node* getNodeAtPosition(Node* head, int position) { Node* current = head; int count = 0; while (current != NULL && count < position) { current = current->next; count++; } return current; } // Get middle node (Floyd's algorithm) Node* getMiddleNode(Node* head) { if (head == NULL) { return NULL; } Node* slow = head; Node* fast = head; while (fast != NULL && fast->next != NULL) { slow = slow->next; fast = fast->next->next; } return slow; } // Count occurrences of a value int countOccurrences(Node* head, int key) { int count = 0; Node* current = head; while (current != NULL) { if (current->data == key) { count++; } current = current->next; } return count; } int main() { Node* head = NULL; // Create list: 10 -> 20 -> 30 -> 20 -> 40 -> 20 -> 50 int values[] = {10, 20, 30, 20, 40, 20, 50}; for (int i = 6; i >= 0; i--) { head = insertAtBeginning(head, values[i]); } printList(head); // Search operations int searchValue = 20; printf("\n=== Search Operations ===\n"); printf("Searching for %d (iterative): %s\n", searchValue, searchIterative(head, searchValue) ? "Found" : "Not found"); printf("Searching for %d (recursive): %s\n", searchValue, searchRecursive(head, searchValue) ? "Found" : "Not found"); printf("Node at position 3: %d\n", getNodeAtPosition(head, 3)->data); Node* middle = getMiddleNode(head); printf("Middle node: %d\n", middle->data); printf("Occurrences of 20: %d\n", countOccurrences(head, 20)); return 0; } Advanced Operations
1. Reverse a Linked List
#include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node* next; } Node; // Reverse linked list (iterative) Node* reverseIterative(Node* head) { Node *prev = NULL; Node *current = head; Node *next = NULL; while (current != NULL) { next = current->next; // Store next node current->next = prev; // Reverse current node's pointer prev = current; // Move prev one step forward current = next; // Move current one step forward } return prev; // New head } // Reverse linked list (recursive) Node* reverseRecursive(Node* head) { if (head == NULL || head->next == NULL) { return head; } Node* rest = reverseRecursive(head->next); head->next->next = head; head->next = NULL; return rest; } int main() { Node* head = NULL; // Create list: 1 -> 2 -> 3 -> 4 -> 5 for (int i = 5; i >= 1; i--) { head = insertAtBeginning(head, i); } printf("Original list: "); printList(head); // Reverse iteratively head = reverseIterative(head); printf("After iterative reverse: "); printList(head); // Reverse back recursively head = reverseRecursive(head); printf("After recursive reverse: "); printList(head); return 0; } 2. Detect Loop in Linked List
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> typedef struct Node { int data; struct Node* next; } Node; // Detect loop using Floyd's Cycle Detection bool detectLoop(Node* head) { Node* slow = head; Node* fast = head; while (slow && fast && fast->next) { slow = slow->next; fast = fast->next->next; if (slow == fast) { return true; // Loop detected } } return false; } // Find start of loop Node* findLoopStart(Node* head) { Node* slow = head; Node* fast = head; bool loopExists = false; // Detect loop while (slow && fast && fast->next) { slow = slow->next; fast = fast->next->next; if (slow == fast) { loopExists = true; break; } } if (!loopExists) { return NULL; } // Find loop start slow = head; while (slow != fast) { slow = slow->next; fast = fast->next; } return slow; } // Remove loop void removeLoop(Node* head) { Node* loopStart = findLoopStart(head); if (loopStart == NULL) { return; } Node* current = loopStart; while (current->next != loopStart) { current = current->next; } current->next = NULL; // Break the loop } int main() { // Create a list with a loop Node* head = createNode(1); head->next = createNode(2); head->next->next = createNode(3); head->next->next->next = createNode(4); head->next->next->next->next = createNode(5); head->next->next->next->next->next = head->next; // Create loop (5 -> 2) printf("Loop detected: %s\n", detectLoop(head) ? "Yes" : "No"); Node* loopStart = findLoopStart(head); if (loopStart) { printf("Loop starts at node with value: %d\n", loopStart->data); } removeLoop(head); printf("After removing loop: %s\n", detectLoop(head) ? "Yes" : "No"); printList(head); // Should print: 1 2 3 4 5 return 0; } 3. Find Nth Node from End
#include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node* next; } Node; // Find nth node from end (using two pointers) Node* findNthFromEnd(Node* head, int n) { if (head == NULL || n <= 0) { return NULL; } Node* main_ptr = head; Node* ref_ptr = head; // Move ref_ptr n steps ahead for (int count = 1; count <= n; count++) { if (ref_ptr == NULL) { printf("List has fewer than %d nodes\n", n); return NULL; } ref_ptr = ref_ptr->next; } // Move both pointers until ref_ptr reaches end while (ref_ptr != NULL) { main_ptr = main_ptr->next; ref_ptr = ref_ptr->next; } return main_ptr; } // Find nth node from end (using length) Node* findNthFromEndLength(Node* head, int n) { int length = getLength(head); if (n > length || n <= 0) { return NULL; } int position = length - n; Node* current = head; for (int i = 0; i < position; i++) { current = current->next; } return current; } int main() { Node* head = NULL; // Create list: 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70 for (int i = 70; i >= 10; i -= 10) { head = insertAtBeginning(head, i); } printList(head); int n = 3; Node* nthFromEnd = findNthFromEnd(head, n); if (nthFromEnd) { printf("%dth node from end: %d\n", n, nthFromEnd->data); } n = 5; nthFromEnd = findNthFromEndLength(head, n); if (nthFromEnd) { printf("%dth node from end: %d\n", n, nthFromEnd->data); } return 0; } Complete Linked List Implementation
linkedlist.h
#ifndef LINKEDLIST_H #define LINKEDLIST_H #include <stdio.h> #include <stdlib.h> #include <stdbool.h> typedef struct Node { int data; struct Node* next; } Node; // Basic operations Node* createNode(int data); void printList(Node* head); int getLength(Node* head); bool isEmpty(Node* head); void freeList(Node* head); // Insertion operations Node* insertAtBeginning(Node* head, int data); Node* insertAtEnd(Node* head, int data); Node* insertAtPosition(Node* head, int data, int position); void insertAfter(Node* prevNode, int data); // Deletion operations Node* deleteFirst(Node* head); Node* deleteLast(Node* head); Node* deleteAtPosition(Node* head, int position); Node* deleteByValue(Node* head, int value); // Search operations bool searchIterative(Node* head, int key); bool searchRecursive(Node* head, int key); Node* getNodeAtPosition(Node* head, int position); int countOccurrences(Node* head, int key); // Advanced operations Node* reverseIterative(Node* head); Node* reverseRecursive(Node* head); bool detectLoop(Node* head); Node* findLoopStart(Node* head); void removeLoop(Node* head); Node* findNthFromEnd(Node* head, int n); Node* getMiddleNode(Node* head); Node* mergeSortedLists(Node* head1, Node* head2); #endif linkedlist.c
#include "linkedlist.h" // Create a new node Node* createNode(int data) { Node* newNode = (Node*)malloc(sizeof(Node)); if (newNode == NULL) { printf("Memory allocation failed!\n"); return NULL; } newNode->data = data; newNode->next = NULL; return newNode; } // Print the linked list void printList(Node* head) { printf("Linked List: "); Node* current = head; while (current != NULL) { printf("%d ", current->data); current = current->next; } printf("\n"); } // Get length of linked list int getLength(Node* head) { int count = 0; Node* current = head; while (current != NULL) { count++; current = current->next; } return count; } // Check if list is empty bool isEmpty(Node* head) { return head == NULL; } // Free entire list void freeList(Node* head) { Node* current = head; Node* next; while (current != NULL) { next = current->next; free(current); current = next; } } // Insert at beginning Node* insertAtBeginning(Node* head, int data) { Node* newNode = createNode(data); if (newNode == NULL) return head; newNode->next = head; return newNode; } // Insert at end Node* insertAtEnd(Node* head, int data) { Node* newNode = createNode(data); if (newNode == NULL) return head; if (head == NULL) { return newNode; } Node* current = head; while (current->next != NULL) { current = current->next; } current->next = newNode; return head; } // Insert at position Node* insertAtPosition(Node* head, int data, int position) { if (position < 0) { printf("Invalid position!\n"); return head; } if (position == 0) { return insertAtBeginning(head, data); } Node* newNode = createNode(data); if (newNode == NULL) return head; Node* current = head; for (int i = 0; i < position - 1 && current != NULL; i++) { current = current->next; } if (current == NULL) { printf("Position out of range!\n"); free(newNode); return head; } newNode->next = current->next; current->next = newNode; return head; } // Insert after a given node void insertAfter(Node* prevNode, int data) { if (prevNode == NULL) { printf("Previous node cannot be NULL\n"); return; } Node* newNode = createNode(data); if (newNode == NULL) return; newNode->next = prevNode->next; prevNode->next = newNode; } // Delete first node Node* deleteFirst(Node* head) { if (head == NULL) { printf("List is empty\n"); return NULL; } Node* temp = head; head = head->next; free(temp); return head; } // Delete last node Node* deleteLast(Node* head) { if (head == NULL) { printf("List is empty\n"); return NULL; } if (head->next == NULL) { free(head); return NULL; } Node* current = head; while (current->next->next != NULL) { current = current->next; } free(current->next); current->next = NULL; return head; } // Delete node at position Node* deleteAtPosition(Node* head, int position) { if (head == NULL || position < 0) { return head; } if (position == 0) { return deleteFirst(head); } Node* current = head; for (int i = 0; i < position - 1 && current != NULL; i++) { current = current->next; } if (current == NULL || current->next == NULL) { printf("Position out of range\n"); return head; } Node* temp = current->next; current->next = temp->next; free(temp); return head; } // Delete by value (first occurrence) Node* deleteByValue(Node* head, int value) { if (head == NULL) { return NULL; } if (head->data == value) { Node* temp = head; head = head->next; free(temp); return head; } Node* current = head; while (current->next != NULL && current->next->data != value) { current = current->next; } if (current->next == NULL) { printf("Value %d not found in list\n", value); return head; } Node* temp = current->next; current->next = temp->next; free(temp); return head; } // Search for a value (iterative) bool searchIterative(Node* head, int key) { Node* current = head; while (current != NULL) { if (current->data == key) { return true; } current = current->next; } return false; } // Search for a value (recursive) bool searchRecursive(Node* head, int key) { if (head == NULL) { return false; } if (head->data == key) { return true; } return searchRecursive(head->next, key); } // Get node at position Node* getNodeAtPosition(Node* head, int position) { Node* current = head; int count = 0; while (current != NULL && count < position) { current = current->next; count++; } return current; } // Count occurrences of a value int countOccurrences(Node* head, int key) { int count = 0; Node* current = head; while (current != NULL) { if (current->data == key) { count++; } current = current->next; } return count; } // Reverse linked list (iterative) Node* reverseIterative(Node* head) { Node *prev = NULL; Node *current = head; Node *next = NULL; while (current != NULL) { next = current->next; current->next = prev; prev = current; current = next; } return prev; } // Reverse linked list (recursive) Node* reverseRecursive(Node* head) { if (head == NULL || head->next == NULL) { return head; } Node* rest = reverseRecursive(head->next); head->next->next = head; head->next = NULL; return rest; } // Detect loop using Floyd's Cycle Detection bool detectLoop(Node* head) { Node* slow = head; Node* fast = head; while (slow && fast && fast->next) { slow = slow->next; fast = fast->next->next; if (slow == fast) { return true; } } return false; } // Find start of loop Node* findLoopStart(Node* head) { Node* slow = head; Node* fast = head; bool loopExists = false; while (slow && fast && fast->next) { slow = slow->next; fast = fast->next->next; if (slow == fast) { loopExists = true; break; } } if (!loopExists) { return NULL; } slow = head; while (slow != fast) { slow = slow->next; fast = fast->next; } return slow; } // Remove loop void removeLoop(Node* head) { Node* loopStart = findLoopStart(head); if (loopStart == NULL) { return; } Node* current = loopStart; while (current->next != loopStart) { current = current->next; } current->next = NULL; } // Find nth node from end Node* findNthFromEnd(Node* head, int n) { if (head == NULL || n <= 0) { return NULL; } Node* main_ptr = head; Node* ref_ptr = head; for (int count = 1; count <= n; count++) { if (ref_ptr == NULL) { printf("List has fewer than %d nodes\n", n); return NULL; } ref_ptr = ref_ptr->next; } while (ref_ptr != NULL) { main_ptr = main_ptr->next; ref_ptr = ref_ptr->next; } return main_ptr; } // Get middle node Node* getMiddleNode(Node* head) { if (head == NULL) { return NULL; } Node* slow = head; Node* fast = head; while (fast != NULL && fast->next != NULL) { slow = slow->next; fast = fast->next->next; } return slow; } // Merge two sorted lists Node* mergeSortedLists(Node* head1, Node* head2) { if (head1 == NULL) return head2; if (head2 == NULL) return head1; Node* result = NULL; if (head1->data <= head2->data) { result = head1; result->next = mergeSortedLists(head1->next, head2); } else { result = head2; result->next = mergeSortedLists(head1, head2->next); } return result; } Time Complexity Analysis
| Operation | Time Complexity | Description |
|---|---|---|
| Access by index | O(n) | Must traverse from head |
| Insert at beginning | O(1) | Update head pointer |
| Insert at end | O(n) | Traverse to last node |
| Insert at position | O(n) | Traverse to position |
| Delete at beginning | O(1) | Update head pointer |
| Delete at end | O(n) | Traverse to second last |
| Delete at position | O(n) | Traverse to position |
| Search | O(n) | Linear search |
| Reverse | O(n) | Traverse once |
| Get length | O(n) | Traverse entire list |
| Get middle | O(n) | Two-pointer technique |
Space Complexity Analysis
| Operation | Space Complexity | Description |
|---|---|---|
| Node creation | O(n) | n nodes in list |
| List reversal (iterative) | O(1) | Constant extra space |
| List reversal (recursive) | O(n) | Call stack |
| Merge sort | O(1) | In-place merging |
| Recursive operations | O(n) | Call stack depth |
Common Applications
| Application | Description | Example |
|---|---|---|
| Dynamic memory management | Grow/shrink as needed | Memory pools |
| Undo functionality | Store operation history | Text editors |
| Symbol tables | Compiler symbol management | Hash table chaining |
| Polynomial arithmetic | Store coefficients | Mathematical software |
| Sparse matrices | Efficient storage | Scientific computing |
| Task scheduling | Process queues | Operating systems |
| Browser history | Navigation | Web browsers |
Advantages and Disadvantages
Advantages
- Dynamic size - Can grow/shrink at runtime
- Efficient insertion/deletion - O(1) at beginning
- No memory wastage - Allocates exactly what's needed
- Flexible implementation - Easy to implement complex structures
Disadvantages
- Sequential access - No random access
- Extra memory - Stores pointer with each element
- Cache unfriendly - Nodes scattered in memory
- Traversal overhead - Must traverse from head for access
Conclusion
Linked lists are fundamental data structures that provide dynamic memory allocation and efficient insertion/deletion operations. Key takeaways:
- Dynamic nature - Lists can grow/shrink as needed
- Node structure - Each node contains data and pointer to next node
- Basic operations - Insert, delete, search, traverse
- Advanced operations - Reverse, detect loops, merge
- Time-space tradeoff - Flexibility comes with overhead
When to Use Linked Lists
- When size is unknown at compile time
- Frequent insertions/deletions at beginning
- Implementing stacks and queues
- Memory-constrained environments
- When random access is not required
When NOT to Use Linked Lists
- Frequent random access needed
- Memory overhead is critical
- Better cache performance required
- Simple array is sufficient
Linked lists are essential for understanding dynamic data structures and are widely used in system programming, algorithm implementation, and as building blocks for more complex data structures.
Complete C Programming Guide + Compilers Collection
1. C srand() Function – Understanding Seed Initialization
https://macronepal.com/understanding-the-c-srand-function
Explains how srand() initializes the pseudo-random number generator in C by setting a seed value. Using the same seed produces the same sequence, while time(NULL) gives different results each run.
2. C rand() Function Mechanics and Limitations
https://macronepal.com/c-rand-function-mechanics-and-limitations
Explains how rand() generates pseudo-random numbers between 0 and RAND_MAX, its deterministic nature, and limitations for security use cases.
3. C log() Function
https://macronepal.com/c-log-function-2
Covers natural logarithm calculation using <math.h> and its applications.
4. Mastering Date and Time in C
https://macronepal.com/mastering-date-and-time-in-c
Explains <time.h> functions like time(), clock(), difftime(), and struct tm.
5. Mastering time_t Type in C
https://macronepal.com/mastering-the-c-time_t-type-for-time-management
Explains time representation as seconds since Unix epoch and conversion functions.
6. C exp() Function
https://macronepal.com/c-exp-function-mechanics-and-implementation
Explains exponential function exp(x) and its scientific applications.
7. C log() Function (Alternate Guide)
https://macronepal.com/c-log-function
Comparison of log() and log10() with usage examples.
8. C log10() Function
https://macronepal.com/mastering-the-log10-function-in-c
Explains base-10 logarithm for engineering and scientific applications.
9. C tan() Function
https://macronepal.com/understanding-the-c-tan-function
Explains tangent function and radian-based calculations.
10. Random Numbers in C (Secure vs Predictable)
https://macronepal.com/mastering-c-random-numbers-for-secure-and-predictable-applications
Explains difference between rand() and secure randomness methods.
11. Free Online C Compiler
https://macronepal.com/free-online-c-code-compiler-2
Browser-based compiler for testing C programs instantly.
C Functions, Arguments, Parameters & Flow
Mastering Functions in C – Complete Guide
https://macronepal.com/c/mastering-functions-in-c-a-complete-guide/
Covers function structure, modular programming, and real-world usage.
Function Arguments in C
https://macronepal.com/c-function-arguments/
Explains how arguments are passed and used in function calls.
Function Parameters in C
https://macronepal.com/c-function-parameters/
Explains defining inputs for functions and matching them with arguments.
Function Declarations in C
https://macronepal.com/c-function-declarations-syntax-rules-and-best-practices/
Covers prototypes, syntax rules, and best practices.
Function Calls in C
https://macronepal.com/understanding-function-calls-in-c-syntax-mechanics-and-best-practices/
Explains execution flow and parameter handling during function calls.
Void Functions in C
https://macronepal.com/understanding-void-functions-in-c-syntax-patterns-and-best-practices/
Explains functions that do not return values.
Return Values in C
https://macronepal.com/c-return-values-mechanics-types-and-best-practices/
Explains different return types and how functions return results.
Pass-by-Value in C
https://macronepal.com/aws/understanding-pass-by-value-in-c-mechanics-implications-and-best-practices/
Explains how copies of variables are passed into functions.
Pass-by-Reference in C
https://macronepal.com/c/understanding-pass-by-reference-in-c-pointers-semantics-and-safe-practices/
Explains using pointers to modify original variables.
C strstr() Function
https://macronepal.com/aws/c-strstr-function/
Explains substring search inside strings in C.
C Preprocessor & Macros
https://macronepal.com/mastering-c-variadic-macros-for-flexible-debugging/
https://macronepal.com/mastering-the-stdc-macro-in-c/
https://macronepal.com/c-time-macro-mechanics-and-usage/
https://macronepal.com/understanding-the-c-date-macro/
https://macronepal.com/c-file-type/
https://macronepal.com/mastering-c-line-macro-for-debugging-and-diagnostics/
https://macronepal.com/mastering-predefined-macros-in-c/
https://macronepal.com/c-error-directive-mechanics-and-usage/
https://macronepal.com/understanding-the-c-pragma-directive/
https://macronepal.com/c-include-directive/
C Structures, Memory, Scope & Linkage
https://macronepal.com/mastering-structures-in-c/
https://macronepal.com/c-structure-declaration-mechanics-and-usage/
https://macronepal.com/c-structure-initialization-mechanics-and-best-practices/
https://macronepal.com/mastering-c-structure-member-access-for-reliable-data-handling/
https://macronepal.com/c-nested-structures/
https://macronepal.com/mastering-arrays-of-structures-in-c/
https://macronepal.com/c-structure-pointers-mechanics-and-implementation/
https://macronepal.com/understanding-c-structure-parameter-passing-mechanics/
https://macronepal.com/mastering-c-returning-structures-for-efficient-data-flow/
https://macronepal.com/c-self-referential-structures/
https://macronepal.com/mastering-structure-alignment-in-c/
https://macronepal.com/c-structure-padding-mechanics-and-optimization/
https://macronepal.com/understanding-c-flexible-array-members-mechanics-and-usage/
https://macronepal.com/mastering-c-anonymous-structures-for-flattened-data-layouts/
https://macronepal.com/c-unions/
https://macronepal.com/mastering-c-name-mangling-and-symbol-decoration/
https://macronepal.com/c-no-linkage-mechanics-and-scope-isolation/
https://macronepal.com/understanding-c-internal-linkage-mechanics-and-architecture/
C Scope, Storage Classes & Typedef
https://macronepal.com/mastering-function-prototype-scope-in-c/
https://macronepal.com/c-function-scope-mechanics-and-visibility/
https://macronepal.com/understanding-c-file-scope-mechanics-and-architecture/
https://macronepal.com/mastering-c-scope-rules-for-predictable-name-resolution/
https://macronepal.com/c-scope-rules/
https://macronepal.com/mastering-c-register-storage-class-for-historical-context-and-modern-alternatives/
https://macronepal.com/mastering-_thread_local-in-c/
https://macronepal.com/c-extern-storage-class-mechanics-and-usage/
https://macronepal.com/understanding-the-c-static-storage-class-mechanics-and-usage/
https://macronepal.com/c-auto-storage-class/
https://macronepal.com/c-typedef-with-pointers/
Extra Articles
https://macronepal.com/13757-2/
https://macronepal.com/13748-2/
https://macronepal.com/13747-2/
https://macronepal.com/13746-2/
https://macronepal.com/13745-2/
https://macronepal.com/13708-2/
https://macronepal.com/13707-2/
https://macronepal.com/13702-2/
Online Compilers
https://macronepal.com/free-html-online-code-compiler/
https://macronepal.com/free-online-python-code-compiler/
https://macronepal.com/free-online-python2-code-compiler/
https://macronepal.com/free-online-java-code-compiler/
https://macronepal.com/free-online-javascript-code-compiler/
https://macronepal.com/free-online-node-js-code-compiler/
https://macronepal.com/free-online-c-code-compiler/
https://macronepal.com/free-online-c-code-compiler-2/
https://macronepal.com/free-online-c-code-compiler-3/
https://macronepal.com/free-online-php-code-compiler/
https://macronepal.com/free-online-ruby-code-compiler/
https://macronepal.com/free-online-perl-code-compiler/
https://macronepal.com/free-online-lua-code-compiler/
https://macronepal.com/free-online-tcl-code-compiler/
https://macronepal.com/free-online-groovy-code-compiler/
https://macronepal.com/free-online-j-shell-code-compiler/
https://macronepal.com/free-online-haskell-code-compiler/
https://macronepal.com/free-online-scala-code-compiler/
https://macronepal.com/free-online-common-lisp-code-compiler/
https://macronepal.com/free-online-d-code-compiler/
https://macronepal.com/free-online-ada-code-compiler/
https://macronepal.com/free-erlang-code-compiler/
https://macronepal.com/free-online-assembly-code-compiler/
