# Advanced topics

## **1. Preprocessor Directives**

Preprocessor directives are instructions that are processed before the actual compilation of the code begins. They start with the `#` symbol and are used for tasks like including files or defining constants.

**`#define`**

The `#define` directive defines a constant or macro. It helps make the code more readable and easier to maintain.

**Syntax:**

```c
#define NAME value
```

**Example:**

```c
#include <stdio.h>

#define PI 3.14159  // Define a constant for PI

int main() {
    printf("Value of PI: %.5f\n", PI);  // Use the defined constant
    return 0;
}
```

* **`#define PI 3.14159`**: Defines `PI` as `3.14159`.
* This allows us to use `PI` in our code instead of writing the number directly each time.

**`#include`**

The `#include` directive is used to include the contents of one file within another file. It’s commonly used to include standard library headers or other user-defined files.

**Syntax:**

```c
#include <header.h>    // For standard library headers
#include "myheader.h"  // For user-defined headers
```

**Example:**

```c
#include <stdio.h>  // Include standard I/O functions
#include "myheader.h"  // Include a user-defined header file

int main() {
    printf("Hello, World!\n");
    return 0;
}
```

* **`#include <stdio.h>`**: Includes the standard input/output library.
* **`#include "myheader.h"`**: Includes a custom header file named `myheader.h`.

***

## **2. Command Line Arguments**

Command line arguments are used to pass additional information to a program when it is executed. They provide a way to control the behavior of the program from the command line.

**Syntax:**

```c
int main(int argc, char *argv[]) {
    // argc: Number of command line arguments
    // argv: Array of strings representing the arguments
}
```

**Example:**

```c
#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("Number of arguments: %d\n", argc);
    
    for (int i = 0; i < argc; i++) {
        printf("Argument %d: %s\n", i, argv[i]);
    }
    
    return 0;
}
```

* **`argc`**: Counts how many arguments were passed to the program.
* **`argv`**: An array of strings, where each string is one of the command line arguments.

**Running the Program:**

```
$ ./program arg1 arg2
Number of arguments: 3
Argument 0: ./program
Argument 1: arg1
Argument 2: arg2
```

***

## **3. Linked Lists**

A linked list is a data structure where each element (node) points to the next one, forming a chain. This allows for flexible memory usage and easy insertion and deletion of elements.

**Basic Linked List Node**

**Definition:**

```c
typedef struct Node {
    int data;          // Data part
    struct Node *next; // Pointer to the next node
} Node;
```

**Example:**

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

typedef struct Node {
    int data;
    struct Node *next;
} Node;

int main() {
    // Create nodes
    Node *head = (Node *)malloc(sizeof(Node));
    Node *second = (Node *)malloc(sizeof(Node));
    Node *third = (Node *)malloc(sizeof(Node));
    
    // Assign data and link nodes
    head->data = 1;
    head->next = second;
    
    second->data = 2;
    second->next = third;
    
    third->data = 3;
    third->next = NULL;
    
    // Traverse and print list
    Node *temp = head;
    while (temp != NULL) {
        printf("%d -> ", temp->data);
        temp = temp->next;
    }
    printf("NULL\n");
    
    // Free memory
    free(head);
    free(second);
    free(third);
    
    return 0;
}
```

* **Node Structure**: Contains `data` and a pointer to the next node.
* **Traversal**: Moving from the `head` node through each `next` node until reaching `NULL`.

***

## **4. Stacks**

A stack is a data structure that follows the Last In, First Out (LIFO) principle. It has two main operations: push (add an item) and pop (remove an item).

**Stack Implementation Using Linked List**

**Example:**

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

typedef struct Node {
    int data;
    struct Node *next;
} Node;

typedef struct Stack {
    Node *top;
} Stack;

// Function to create a new stack
Stack *createStack() {
    Stack *stack = (Stack *)malloc(sizeof(Stack));
    stack->top = NULL;
    return stack;
}

// Push an item onto the stack
void push(Stack *stack, int data) {
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = stack->top;
    stack->top = newNode;
}

// Pop an item from the stack
int pop(Stack *stack) {
    if (stack->top == NULL) {
        printf("Stack is empty\n");
        return -1;
    }
    Node *temp = stack->top;
    int data = temp->data;
    stack->top = stack->top->next;
    free(temp);
    return data;
}

// Print the stack
void printStack(Stack *stack) {
    Node *temp = stack->top;
    while (temp != NULL) {
        printf("%d -> ", temp->data);
        temp = temp->next;
    }
    printf("NULL\n");
}

int main() {
    Stack *stack = createStack();
    
    push(stack, 10);
    push(stack, 20);
    push(stack, 30);
    
    printStack(stack);
    
    printf("Popped: %d\n", pop(stack));
    printStack(stack);
    
    return 0;
}
```

* **Push**: Adds a new item to the top of the stack.
* **Pop**: Removes and returns the item from the top of the stack.

***

## **5. Queues**

A queue is a data structure that follows the First In, First Out (FIFO) principle. It has two main operations: enqueue (add an item) and dequeue (remove an item).

**Queue Implementation Using Linked List**

**Example:**

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

typedef struct Node {
    int data;
    struct Node *next;
} Node;

typedef struct Queue {
    Node *front;
    Node *rear;
} Queue;

// Function to create a new queue
Queue *createQueue() {
    Queue *queue = (Queue *)malloc(sizeof(Queue));
    queue->front = NULL;
    queue->rear = NULL;
    return queue;
}

// Enqueue an item
void enqueue(Queue *queue, int data) {
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    if (queue->rear == NULL) {
        queue->front = newNode;
        queue->rear = newNode;
    } else {
        queue->rear->next = newNode;
        queue->rear = newNode;
    }
}

// Dequeue an item
int dequeue(Queue *queue) {
    if (queue->front == NULL) {
        printf("Queue is empty\n");
        return -1;
    }
    Node *temp = queue->front;
    int data = temp->data;
    queue->front = queue->front->next;
    if (queue->front == NULL) {
        queue->rear = NULL;
    }
    free(temp);
    return data;
}

// Print the queue
void printQueue(Queue *queue) {
    Node *temp = queue->front;
    while (temp != NULL) {
        printf("%d -> ", temp->data);
        temp = temp->next;
    }
    printf("NULL\n");
}

int main() {
    Queue *queue = createQueue();
    
    enqueue(queue, 10);
    enqueue(queue, 20);
    enqueue(queue, 30);
    
    printQueue(queue);
    
    printf("Dequeued: %d\n", dequeue(queue));
    printQueue(queue);
    
    return 0;
}
```

* **Enqueue**: Adds a new item to the rear of the queue.
* **Dequeue**: Removes and returns the item from the front of the queue.

***

#### **Summary**

* **Preprocessor Directives**: `#define` for constants, `#include` for file inclusion.
* **Command Line Arguments**: Access program arguments from the command line.
* **Linked Lists**: Dynamic data structures with nodes linked together.
* **Stacks**: LIFO structure with push and pop operations.
* **Queues**: FIFO structure with enqueue and dequeue operations.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://cs.d19.in/advanced-topics.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
