c
examples
examples.c๐งc
/**
* =============================================================================
* POINTERS AND FUNCTIONS - EXAMPLES
* =============================================================================
*
* This file demonstrates the interaction between pointers and functions in C:
* - Passing pointers as function parameters
* - Call by value vs call by reference
* - Returning pointers from functions
* - Function pointers
* - Callback functions
* - Generic programming with void pointers
*
* Compile: gcc -o examples examples.c -Wall
* Run: ./examples
* =============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* ============================================================
* EXAMPLE 1: Call by Value vs Call by Reference
* ============================================================ */
void byValue(int x) {
x = 999; // Only modifies local copy
printf(" Inside byValue: x = %d\n", x);
}
void byReference(int *x) {
*x = 999; // Modifies original through pointer
printf(" Inside byReference: *x = %d\n", *x);
}
void example1_value_vs_reference(void) {
printf("\n=== EXAMPLE 1: Call by Value vs Call by Reference ===\n\n");
int a = 10, b = 10;
printf("Initial values: a = %d, b = %d\n\n", a, b);
// Call by value
printf("Calling byValue(a):\n");
byValue(a);
printf("After byValue: a = %d (unchanged!)\n\n", a);
// Call by reference
printf("Calling byReference(&b):\n");
byReference(&b);
printf("After byReference: b = %d (changed!)\n\n", b);
printf("Summary:\n");
printf(" byValue(a) โ a stays %d (copy was modified)\n", 10);
printf(" byReference(&b) โ b becomes %d (original modified)\n", 999);
}
/* ============================================================
* EXAMPLE 2: Swapping Variables
* ============================================================ */
// Wrong way - doesn't work
void swapWrong(int a, int b) {
int temp = a;
a = b;
b = temp;
}
// Correct way - using pointers
void swapCorrect(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
void example2_swap(void) {
printf("\n=== EXAMPLE 2: Swapping Variables ===\n\n");
int x = 10, y = 20;
printf("Original: x = %d, y = %d\n\n", x, y);
// Wrong way
printf("Calling swapWrong(x, y)...\n");
swapWrong(x, y);
printf("After swapWrong: x = %d, y = %d (no change!)\n\n", x, y);
// Correct way
printf("Calling swapCorrect(&x, &y)...\n");
swapCorrect(&x, &y);
printf("After swapCorrect: x = %d, y = %d (swapped!)\n", x, y);
}
/* ============================================================
* EXAMPLE 3: Modifying Arrays Through Pointers
* ============================================================ */
void doubleArray(int *arr, int size) {
for (int i = 0; i < size; i++) {
arr[i] *= 2; // Or: *(arr + i) *= 2;
}
}
void example3_modify_array(void) {
printf("\n=== EXAMPLE 3: Modifying Arrays Through Pointers ===\n\n");
int arr[] = {1, 2, 3, 4, 5};
int size = 5;
printf("Original array: ");
for (int i = 0; i < size; i++) printf("%d ", arr[i]);
printf("\n");
doubleArray(arr, size);
printf("After doubleArray: ");
for (int i = 0; i < size; i++) printf("%d ", arr[i]);
printf("\n");
printf("\nNote: Arrays are always passed by reference in C.\n");
}
/* ============================================================
* EXAMPLE 4: Returning Pointers from Functions
* ============================================================ */
// Safe: returning pointer to static variable
int* getStaticValue(void) {
static int value = 42;
return &value;
}
// Safe: returning dynamically allocated memory
int* createArray(int size, int initialValue) {
int *arr = (int*)malloc(size * sizeof(int));
if (arr == NULL) return NULL;
for (int i = 0; i < size; i++) {
arr[i] = initialValue;
}
return arr; // Caller must free!
}
// Returns pointer to maximum element
int* findMax(int *arr, int size) {
if (size <= 0) return NULL;
int *maxPtr = arr;
for (int i = 1; i < size; i++) {
if (arr[i] > *maxPtr) {
maxPtr = &arr[i];
}
}
return maxPtr;
}
void example4_return_pointers(void) {
printf("\n=== EXAMPLE 4: Returning Pointers from Functions ===\n\n");
// Static variable example
int *staticPtr = getStaticValue();
printf("Static value: %d\n", *staticPtr);
// Modify the static value
*staticPtr = 100;
printf("After modification: %d\n\n", *getStaticValue());
// Dynamic allocation example
int *arr = createArray(5, 7);
if (arr != NULL) {
printf("Dynamic array: ");
for (int i = 0; i < 5; i++) printf("%d ", arr[i]);
printf("\n");
free(arr);
}
// Finding maximum example
int numbers[] = {23, 67, 12, 89, 45};
int *maxPtr = findMax(numbers, 5);
printf("\nArray: {23, 67, 12, 89, 45}\n");
printf("Maximum element: %d at address %p\n", *maxPtr, (void*)maxPtr);
}
/* ============================================================
* EXAMPLE 5: Returning Multiple Values
* ============================================================ */
void getMinMax(const int *arr, int size, int *min, int *max) {
if (size <= 0) return;
*min = *max = arr[0];
for (int i = 1; i < size; i++) {
if (arr[i] < *min) *min = arr[i];
if (arr[i] > *max) *max = arr[i];
}
}
void divideWithRemainder(int dividend, int divisor, int *quotient, int *remainder) {
*quotient = dividend / divisor;
*remainder = dividend % divisor;
}
void example5_multiple_return_values(void) {
printf("\n=== EXAMPLE 5: Returning Multiple Values ===\n\n");
// Min and max
int arr[] = {45, 12, 89, 23, 56, 7, 78};
int min, max;
getMinMax(arr, 7, &min, &max);
printf("Array: {45, 12, 89, 23, 56, 7, 78}\n");
printf("Minimum: %d\n", min);
printf("Maximum: %d\n\n", max);
// Division with remainder
int q, r;
divideWithRemainder(17, 5, &q, &r);
printf("17 รท 5 = %d remainder %d\n", q, r);
}
/* ============================================================
* EXAMPLE 6: Function Pointers Basics
* ============================================================ */
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divide_int(int a, int b) { return b != 0 ? a / b : 0; }
void example6_function_pointers(void) {
printf("\n=== EXAMPLE 6: Function Pointers Basics ===\n\n");
// Declare function pointer
int (*operation)(int, int);
int a = 20, b = 5;
// Point to add
operation = add;
printf("Using add: %d + %d = %d\n", a, b, operation(a, b));
// Point to subtract
operation = subtract;
printf("Using subtract: %d - %d = %d\n", a, b, operation(a, b));
// Point to multiply
operation = multiply;
printf("Using multiply: %d * %d = %d\n", a, b, operation(a, b));
// Point to divide
operation = divide_int;
printf("Using divide: %d / %d = %d\n", a, b, operation(a, b));
printf("\nFunction pointer address: %p\n", (void*)operation);
}
/* ============================================================
* EXAMPLE 7: Array of Function Pointers
* ============================================================ */
void example7_function_pointer_array(void) {
printf("\n=== EXAMPLE 7: Array of Function Pointers ===\n\n");
// Array of function pointers
int (*operations[4])(int, int) = {add, subtract, multiply, divide_int};
const char *names[] = {"Addition", "Subtraction", "Multiplication", "Division"};
int x = 12, y = 4;
printf("Performing all operations on %d and %d:\n\n", x, y);
printf("โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโ\n");
printf("โ Operation โ Result โ\n");
printf("โโโโโโโโโโโโโโโโโโโโผโโโโโโโโโค\n");
for (int i = 0; i < 4; i++) {
printf("โ %-16s โ %6d โ\n", names[i], operations[i](x, y));
}
printf("โโโโโโโโโโโโโโโโโโโโดโโโโโโโโโ\n");
}
/* ============================================================
* EXAMPLE 8: Callback Functions
* ============================================================ */
typedef void (*ElementCallback)(int);
void forEachElement(int *arr, int size, ElementCallback callback) {
for (int i = 0; i < size; i++) {
callback(arr[i]);
}
}
void printElement(int x) {
printf("%d ", x);
}
void printSquare(int x) {
printf("%d ", x * x);
}
void printDouble(int x) {
printf("%d ", x * 2);
}
void example8_callbacks(void) {
printf("\n=== EXAMPLE 8: Callback Functions ===\n\n");
int arr[] = {1, 2, 3, 4, 5};
int size = 5;
printf("Array: {1, 2, 3, 4, 5}\n\n");
printf("Using printElement callback:\n Elements: ");
forEachElement(arr, size, printElement);
printf("\n");
printf("\nUsing printSquare callback:\n Squares: ");
forEachElement(arr, size, printSquare);
printf("\n");
printf("\nUsing printDouble callback:\n Doubles: ");
forEachElement(arr, size, printDouble);
printf("\n");
}
/* ============================================================
* EXAMPLE 9: Sorting with Comparison Callback
* ============================================================ */
typedef int (*CompareFunc)(const void*, const void*);
void bubbleSort(int *arr, int size, CompareFunc compare) {
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - 1 - i; j++) {
if (compare(&arr[j], &arr[j+1]) > 0) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
int compareAscending(const void *a, const void *b) {
return *(const int*)a - *(const int*)b;
}
int compareDescending(const void *a, const void *b) {
return *(const int*)b - *(const int*)a;
}
void example9_sort_callback(void) {
printf("\n=== EXAMPLE 9: Sorting with Comparison Callback ===\n\n");
int arr1[] = {64, 34, 25, 12, 22, 11, 90};
int arr2[] = {64, 34, 25, 12, 22, 11, 90};
int size = 7;
printf("Original array: ");
for (int i = 0; i < size; i++) printf("%d ", arr1[i]);
printf("\n\n");
// Sort ascending
bubbleSort(arr1, size, compareAscending);
printf("Sorted ascending: ");
for (int i = 0; i < size; i++) printf("%d ", arr1[i]);
printf("\n");
// Sort descending
bubbleSort(arr2, size, compareDescending);
printf("Sorted descending: ");
for (int i = 0; i < size; i++) printf("%d ", arr2[i]);
printf("\n");
}
/* ============================================================
* EXAMPLE 10: Using typedef with Function Pointers
* ============================================================ */
// Define types for clarity
typedef int (*BinaryOp)(int, int);
typedef void (*Action)(void);
int power(int base, int exp) {
int result = 1;
for (int i = 0; i < exp; i++) {
result *= base;
}
return result;
}
int modulo(int a, int b) {
return a % b;
}
void sayHello(void) {
printf("Hello!\n");
}
void sayGoodbye(void) {
printf("Goodbye!\n");
}
void example10_typedef_function_pointers(void) {
printf("\n=== EXAMPLE 10: Using typedef with Function Pointers ===\n\n");
// Using BinaryOp type
BinaryOp ops[] = {add, multiply, power, modulo};
const char *names[] = {"add", "multiply", "power", "modulo"};
printf("Using BinaryOp typedef:\n");
for (int i = 0; i < 4; i++) {
printf(" %s(3, 4) = %d\n", names[i], ops[i](3, 4));
}
// Using Action type
Action actions[] = {sayHello, sayGoodbye};
printf("\nUsing Action typedef:\n");
for (int i = 0; i < 2; i++) {
printf(" Action %d: ", i);
actions[i]();
}
}
/* ============================================================
* EXAMPLE 11: Const Pointers in Function Parameters
* ============================================================ */
// Read-only access to array
int sumArray(const int *arr, int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
// arr[i] = 0; // ERROR: cannot modify const
}
return sum;
}
// Read-only string
int countVowels(const char *str) {
int count = 0;
while (*str) {
char c = *str;
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' ||
c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
count++;
}
str++;
}
return count;
}
void example11_const_pointers(void) {
printf("\n=== EXAMPLE 11: Const Pointers in Parameters ===\n\n");
int numbers[] = {10, 20, 30, 40, 50};
printf("Array: {10, 20, 30, 40, 50}\n");
printf("Sum (using const int*): %d\n\n", sumArray(numbers, 5));
const char *text = "Hello World";
printf("String: \"%s\"\n", text);
printf("Vowel count (using const char*): %d\n", countVowels(text));
printf("\nBenefit: Compiler prevents accidental modification!\n");
}
/* ============================================================
* EXAMPLE 12: Generic Swap with void Pointer
* ============================================================ */
void genericSwap(void *a, void *b, size_t size) {
char temp[size]; // VLA
memcpy(temp, a, size);
memcpy(a, b, size);
memcpy(b, temp, size);
}
void example12_generic_swap(void) {
printf("\n=== EXAMPLE 12: Generic Swap with void* ===\n\n");
// Swap integers
int x = 10, y = 20;
printf("Integers before: x=%d, y=%d\n", x, y);
genericSwap(&x, &y, sizeof(int));
printf("Integers after: x=%d, y=%d\n\n", x, y);
// Swap doubles
double a = 3.14, b = 2.71;
printf("Doubles before: a=%.2f, b=%.2f\n", a, b);
genericSwap(&a, &b, sizeof(double));
printf("Doubles after: a=%.2f, b=%.2f\n\n", a, b);
// Swap chars
char c1 = 'A', c2 = 'Z';
printf("Chars before: c1='%c', c2='%c'\n", c1, c2);
genericSwap(&c1, &c2, sizeof(char));
printf("Chars after: c1='%c', c2='%c'\n", c1, c2);
}
/* ============================================================
* EXAMPLE 13: Function Returning Function Pointer
* ============================================================ */
typedef int (*MathOp)(int, int);
MathOp getOperation(char op) {
switch (op) {
case '+': return add;
case '-': return subtract;
case '*': return multiply;
case '/': return divide_int;
default: return NULL;
}
}
void example13_return_function_pointer(void) {
printf("\n=== EXAMPLE 13: Function Returning Function Pointer ===\n\n");
char operators[] = {'+', '-', '*', '/'};
int a = 15, b = 3;
printf("Calculating %d [op] %d:\n\n", a, b);
for (int i = 0; i < 4; i++) {
MathOp op = getOperation(operators[i]);
if (op != NULL) {
printf(" %d %c %d = %d\n", a, operators[i], b, op(a, b));
}
}
}
/* ============================================================
* EXAMPLE 14: Menu System with Function Pointers
* ============================================================ */
void menuOption1(void) { printf(" โ Executing Option 1: File operations\n"); }
void menuOption2(void) { printf(" โ Executing Option 2: Edit operations\n"); }
void menuOption3(void) { printf(" โ Executing Option 3: View operations\n"); }
void menuOption4(void) { printf(" โ Executing Option 4: Help\n"); }
typedef void (*MenuHandler)(void);
void example14_menu_system(void) {
printf("\n=== EXAMPLE 14: Menu System with Function Pointers ===\n\n");
MenuHandler handlers[] = {menuOption1, menuOption2, menuOption3, menuOption4};
const char *menuItems[] = {"File", "Edit", "View", "Help"};
printf("Menu:\n");
printf("โโโโโโโโโโโโโโโโโโโโ\n");
for (int i = 0; i < 4; i++) {
printf("%d. %s\n", i + 1, menuItems[i]);
}
printf("โโโโโโโโโโโโโโโโโโโโ\n\n");
printf("Simulating menu selections:\n");
for (int choice = 0; choice < 4; choice++) {
printf("Selected: %s\n", menuItems[choice]);
handlers[choice]();
printf("\n");
}
}
/* ============================================================
* EXAMPLE 15: Passing Function Pointer as Parameter
* ============================================================ */
int* transform(int *arr, int size, int (*transformer)(int)) {
int *result = (int*)malloc(size * sizeof(int));
if (result == NULL) return NULL;
for (int i = 0; i < size; i++) {
result[i] = transformer(arr[i]);
}
return result;
}
int square(int x) { return x * x; }
int cube(int x) { return x * x * x; }
int negate(int x) { return -x; }
void example15_function_as_parameter(void) {
printf("\n=== EXAMPLE 15: Function Pointer as Parameter ===\n\n");
int arr[] = {1, 2, 3, 4, 5};
int size = 5;
printf("Original array: ");
for (int i = 0; i < size; i++) printf("%d ", arr[i]);
printf("\n\n");
// Transform with square
int *squared = transform(arr, size, square);
printf("Squared: ");
for (int i = 0; i < size; i++) printf("%d ", squared[i]);
printf("\n");
free(squared);
// Transform with cube
int *cubed = transform(arr, size, cube);
printf("Cubed: ");
for (int i = 0; i < size; i++) printf("%d ", cubed[i]);
printf("\n");
free(cubed);
// Transform with negate
int *negated = transform(arr, size, negate);
printf("Negated: ");
for (int i = 0; i < size; i++) printf("%d ", negated[i]);
printf("\n");
free(negated);
}
/* ============================================================
* MAIN FUNCTION
* ============================================================ */
int main() {
printf("โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n");
printf("โ POINTERS AND FUNCTIONS - EXAMPLES โ\n");
printf("โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n");
example1_value_vs_reference();
example2_swap();
example3_modify_array();
example4_return_pointers();
example5_multiple_return_values();
example6_function_pointers();
example7_function_pointer_array();
example8_callbacks();
example9_sort_callback();
example10_typedef_function_pointers();
example11_const_pointers();
example12_generic_swap();
example13_return_function_pointer();
example14_menu_system();
example15_function_as_parameter();
printf("\nโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n");
printf(" All examples completed! \n");
printf("โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n");
return 0;
}