An array is a collection of fixed-size items of the same data type, stored in contiguous memory locations.
int marks[5]; // Declares an array to hold 5 integers
marks[0] = 100; // Arrays are 0-indexed
marks[1] = 90;
// Processing with a loop
for (int i = 0; i < 5; i++) {
    printf("%d\n", marks[i]);
}When an array is passed to a function, what is actually passed is the address of its first element (a pointer). This means the function can modify the original array (Pass-by-Reference behavior).
void modifyArray(int arr[], int size) {
    arr[0] = 99; // This changes the original array
}Arrays of arrays, used to represent matrices or tables.
int matrix[2][3] = { {1, 2, 3}, {4, 5, 6} };
printf("%d", matrix[1][2]); // Prints 6In C, a string is simply an array of char, ending with a special null terminator ('\0').
char greeting[] = "Hello"; // Equivalent to {'H', 'e', 'l', 'l', 'o', '\0'}A pointer is a variable that stores the memory address of another variable.
& (Address-of operator): Gets the memory address of a variable.* (Dereference/Indirection operator): Gets the value at a memory address.int var = 10;
int *ptr;     // Declares a pointer to an integer
ptr = &var;   // 'ptr' now holds the address of 'var'
printf("Value of var: %d\n", var);    // Prints 10
printf("Value of var: %d\n", *ptr);  // Prints 10 (dereferencing ptr)
printf("Address of var: %p\n", &var);   // Prints address
printf("Address in ptr: %p\n", ptr);   // Prints the same addressBy passing pointers, we can achieve Pass-by-Reference, allowing a function to modify the original variables.
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}
int x = 5, y = 10;
swap(&x, &y); // Pass the addresses
// Now x = 10 and y = 5The name of an array is a constant pointer to its first element.
arris equivalent to&arr[0]
We can use address arithmetic to access elements.
arr[i] is identical to *(arr + i)&arr[i] is identical to (arr + i)Note: ptr++ (where ptr is an int*) increments the address by sizeof(int) (usually 4 bytes), not 1 byte.
A string literal ("Hello") can be assigned to a char*. Many string library functions (like strcpy, strlen) use character pointers.
char *name = "John Doe"; // 'name' points to the 'J'
printf("%c", *(name + 1)); // Prints 'o'An array where each element is a pointer. Useful for storing an array of strings.
char *names[] = {"Alice", "Bob", "Charlie"};
printf("%s\n", names[1]); // Prints "Bob"A pointer that stores the address of another pointer. Used in dynamic 2D arrays or to modify a pointer within a function.
int x = 10;
int *p = &x;
int **pp = &p;
printf("%d\n", **pp); // Prints 10This is a complex topic. For int matrix[2][3], matrix is a pointer to its first element, which is an array of 3 integers. Its type is int (*)[3].
Allows your program to receive arguments when it is executed from the command line.
// Signature of main
int main(int argc, char *argv[]) {
    // argc: (Argument Count) Number of arguments (program name is 1st)
    // argv: (Argument Vector) Array of strings (char*)
    
    printf("Program name: %s\n", argv[0]);
    if (argc > 1) {
        printf("First argument: %s\n", argv[1]);
    }
    return 0;
}
// Run: ./my_program test
// Output:
// Program name: ./my_program
// First argument: testA pointer that stores the address of a function. This allows functions to be passed as arguments to other functions.
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int main() {
    // 1. Declare a function pointer
    int (*operation)(int, int);
    // 2. Assign a function to it
    operation = add;
    printf("%d\n", operation(5, 3)); // Prints 8
    operation = subtract;
    printf("%d\n", operation(5, 3)); // Prints 2
    return 0;
}This is the primary use of function pointers, e.g., in a generic sorting function that takes a custom comparison function as an argument.