Pointers and Functions

Pointers and functions work together beautifully in C! Think of it like giving someone the address of your house instead of moving your entire house to them. When we pass pointers to functions, we're sharing the memory address rather than copying the entire data.

When you pass a regular variable to a function, C creates a copy of that variable. This is called pass by value. But sometimes you want the function to modify the original variable, not just a copy. That's where pointers come in handy!

Pass by Value vs Pass by Reference

Pass by Value (Regular Variables)

#include <stdio.h>

void tryToChange(int x) {
    x = 100;  // This only changes the copy
    printf("Inside function: x = %d\n", x);
}

int main() {
    int num = 5;
    printf("Before function: num = %d\n", num);
    tryToChange(num);
    printf("After function: num = %d\n", num);  // Still 5!
    return 0;
}

Pass by Reference (Using Pointers)

#include <stdio.h>

void actuallyChange(int *x) {
    *x = 100;  // This changes the original variable
    printf("Inside function: *x = %d\n", *x);
}

int main() {
    int num = 5;
    printf("Before function: num = %d\n", num);
    actuallyChange(&num);  // Pass the address
    printf("After function: num = %d\n", num);  // Now it's 100!
    return 0;
}

Practical Example: Swapping Two Numbers

Here's a classic example that shows why pointers are essential:

#include <stdio.h>

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int x = 10, y = 20;
    
    printf("Before swap: x = %d, y = %d\n", x, y);
    swap(&x, &y);
    printf("After swap: x = %d, y = %d\n", x, y);
    
    return 0;
}

Functions Returning Pointers

Functions can also return pointers, but be careful! Don't return pointers to local variables because they get destroyed when the function ends.

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

int* createArray(int size) {
    // Allocate memory dynamically
    int *arr = (int*)malloc(size * sizeof(int));
    
    // Initialize the array
    for(int i = 0; i < size; i++) {
        arr[i] = i * 2;
    }
    
    return arr;  // Safe to return because memory is allocated dynamically
}

int main() {
    int *myArray = createArray(5);
    
    printf("Array elements: ");
    for(int i = 0; i < 5; i++) {
        printf("%d ", myArray[i]);
    }
    printf("\n");
    
    free(myArray);  // Don't forget to free the memory!
    return 0;
}

Array Parameters are Actually Pointers

Here's something cool: when you pass an array to a function, you're actually passing a pointer to the first element!

#include <stdio.h>

void printArray(int arr[], int size) {
    // arr is actually a pointer to the first element
    for(int i = 0; i < size; i++) {
        printf("%d ", arr[i]);  // Same as *(arr + i)
    }
    printf("\n");
}

// This is equivalent to the above function
void printArrayPointer(int *arr, int size) {
    for(int i = 0; i < size; i++) {
        printf("%d ", *(arr + i));
    }
    printf("\n");
}

int main() {
    int numbers[] = {1, 2, 3, 4, 5};
    int size = 5;
    
    printArray(numbers, size);
    printArrayPointer(numbers, size);
    
    return 0;
}

Key Points to Remember

ConceptDescription
Pass by ValueFunction receives a copy of the variable
Pass by ReferenceFunction receives the memory address using pointers
&variableGets the address of a variable
*pointerDereferences a pointer to access the value
Array ParametersAre automatically treated as pointers

Common Pitfalls

  1. Don't return pointers to local variables - they get destroyed when the function ends
  2. Remember to use & when passing addresses - function(&variable) not function(variable)
  3. Use * to access the value - *pointer = 5 not pointer = 5
  4. Free dynamically allocated memory - use free() when you're done with malloc()

Pointers with functions unlock powerful programming techniques like dynamic memory allocation, efficient array processing, and the ability to modify multiple values from a single function call!