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:
#define NAME value
Example:
#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:
#include <header.h> // For standard library headers
#include "myheader.h" // For user-defined headers
Example:
#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:
int main(int argc, char *argv[]) {
// argc: Number of command line arguments
// argv: Array of strings representing the arguments
}
Example:
#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:
typedef struct Node {
int data; // Data part
struct Node *next; // Pointer to the next node
} Node;
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:
#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).