c
examples
examples.cš§c
/**
* Introduction to Pointers - Examples
*
* This file demonstrates basic pointer concepts in C.
*
* Compile: gcc examples.c -o examples
* Run: ./examples
*/
#include <stdio.h>
#include <stdlib.h>
/* ============================================================
* EXAMPLE 1: What is a Pointer?
* ============================================================ */
void example1_basics(void) {
printf("=== EXAMPLE 1: What is a Pointer? ===\n\n");
int x = 42; // Regular variable
int *ptr = &x; // Pointer to x
printf("Variable x:\n");
printf(" Value: %d\n", x);
printf(" Address: %p\n", (void*)&x);
printf("\nPointer ptr:\n");
printf(" Value (address it holds): %p\n", (void*)ptr);
printf(" Its own address: %p\n", (void*)&ptr);
printf(" Dereferenced value (*ptr): %d\n", *ptr);
printf("\nRelationships:\n");
printf(" &x == ptr? %s\n", (&x == ptr) ? "Yes" : "No");
printf(" x == *ptr? %s\n", (x == *ptr) ? "Yes" : "No");
}
/* ============================================================
* EXAMPLE 2: Address-of Operator (&)
* ============================================================ */
void example2_address_of(void) {
printf("\n=== EXAMPLE 2: Address-of Operator (&) ===\n\n");
int a = 10;
int b = 20;
int c = 30;
printf("Variable Value Address\n");
printf("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
printf("a %d %p\n", a, (void*)&a);
printf("b %d %p\n", b, (void*)&b);
printf("c %d %p\n", c, (void*)&c);
// Notice addresses might be consecutive or have gaps
printf("\nNote: Each int takes %zu bytes\n", sizeof(int));
printf("Address difference a to b: %ld bytes\n",
(long)((char*)&a - (char*)&b));
}
/* ============================================================
* EXAMPLE 3: Dereference Operator (*)
* ============================================================ */
void example3_dereference(void) {
printf("\n=== EXAMPLE 3: Dereference Operator (*) ===\n\n");
int x = 100;
int *ptr = &x;
printf("Before modification:\n");
printf(" x = %d, *ptr = %d\n", x, *ptr);
// Modify through pointer
*ptr = 200;
printf("\nAfter *ptr = 200:\n");
printf(" x = %d, *ptr = %d\n", x, *ptr);
// Modify original
x = 300;
printf("\nAfter x = 300:\n");
printf(" x = %d, *ptr = %d\n", x, *ptr);
printf("\nKey insight: x and *ptr always show the same value\n");
printf("because ptr points to x's memory location.\n");
}
/* ============================================================
* EXAMPLE 4: Pointer Types
* ============================================================ */
void example4_types(void) {
printf("\n=== EXAMPLE 4: Pointer Types ===\n\n");
char c = 'A';
int i = 42;
float f = 3.14f;
double d = 2.71828;
char *cp = &c;
int *ip = &i;
float *fp = &f;
double *dp = &d;
printf("Type Size of Data Size of Pointer\n");
printf("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
printf("char %zu byte %zu bytes\n", sizeof(c), sizeof(cp));
printf("int %zu bytes %zu bytes\n", sizeof(i), sizeof(ip));
printf("float %zu bytes %zu bytes\n", sizeof(f), sizeof(fp));
printf("double %zu bytes %zu bytes\n", sizeof(d), sizeof(dp));
printf("\nNote: All pointers are same size (%zu bytes on this system)\n",
sizeof(void*));
printf("because they all store memory addresses.\n");
printf("\nDereferenced values:\n");
printf(" *cp = '%c'\n", *cp);
printf(" *ip = %d\n", *ip);
printf(" *fp = %.2f\n", *fp);
printf(" *dp = %.5f\n", *dp);
}
/* ============================================================
* EXAMPLE 5: Pointer Initialization
* ============================================================ */
void example5_initialization(void) {
printf("\n=== EXAMPLE 5: Pointer Initialization ===\n\n");
// Method 1: Initialize with address of variable
int x = 10;
int *ptr1 = &x;
printf("Method 1 - Address of variable: *ptr1 = %d\n", *ptr1);
// Method 2: Initialize to NULL
int *ptr2 = NULL;
printf("Method 2 - NULL pointer: ptr2 = %p\n", (void*)ptr2);
// Method 3: Initialize with another pointer
int *ptr3 = ptr1;
printf("Method 3 - Copy pointer: *ptr3 = %d\n", *ptr3);
// Method 4: Initialize later
int *ptr4;
int y = 20;
ptr4 = &y; // Initialize before use
printf("Method 4 - Initialize later: *ptr4 = %d\n", *ptr4);
// Demonstrate that ptr1 and ptr3 point to same location
printf("\nptr1 and ptr3 point to same address:\n");
printf(" ptr1 = %p\n", (void*)ptr1);
printf(" ptr3 = %p\n", (void*)ptr3);
*ptr1 = 999;
printf(" After *ptr1 = 999: *ptr3 = %d\n", *ptr3);
}
/* ============================================================
* EXAMPLE 6: NULL Pointers
* ============================================================ */
void example6_null(void) {
printf("\n=== EXAMPLE 6: NULL Pointers ===\n\n");
int *ptr = NULL;
printf("NULL pointer check:\n");
printf(" ptr == NULL? %s\n", (ptr == NULL) ? "Yes" : "No");
printf(" ptr == 0? %s\n", (ptr == 0) ? "Yes" : "No");
printf(" !ptr? %s\n", (!ptr) ? "Yes (true)" : "No (false)");
// Safe usage pattern
printf("\nSafe usage pattern:\n");
if (ptr != NULL) {
printf(" Using pointer: %d\n", *ptr);
} else {
printf(" Pointer is NULL, skipping dereference\n");
}
// Now assign valid address
int x = 42;
ptr = &x;
printf("\nAfter assigning valid address:\n");
if (ptr != NULL) {
printf(" Pointer is valid: *ptr = %d\n", *ptr);
}
}
/* ============================================================
* EXAMPLE 7: Multiple Pointers to Same Variable
* ============================================================ */
void example7_multiple_pointers(void) {
printf("\n=== EXAMPLE 7: Multiple Pointers to Same Variable ===\n\n");
int x = 100;
int *ptr1 = &x;
int *ptr2 = &x;
int *ptr3 = ptr1; // Copy of ptr1
printf("Initial state:\n");
printf(" x = %d\n", x);
printf(" *ptr1 = %d, *ptr2 = %d, *ptr3 = %d\n", *ptr1, *ptr2, *ptr3);
printf("\nAll point to same address: %p\n", (void*)&x);
printf(" ptr1 = %p\n", (void*)ptr1);
printf(" ptr2 = %p\n", (void*)ptr2);
printf(" ptr3 = %p\n", (void*)ptr3);
// Modify through one pointer
*ptr2 = 500;
printf("\nAfter *ptr2 = 500:\n");
printf(" x = %d\n", x);
printf(" *ptr1 = %d, *ptr2 = %d, *ptr3 = %d\n", *ptr1, *ptr2, *ptr3);
printf("\nAll show 500 because they all point to x!\n");
}
/* ============================================================
* EXAMPLE 8: Pointer Arithmetic Preview
* ============================================================ */
void example8_arithmetic(void) {
printf("\n=== EXAMPLE 8: Pointer Arithmetic Preview ===\n\n");
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // Points to first element
printf("Array elements using pointer arithmetic:\n\n");
printf("Expression Value Address\n");
printf("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
for (int i = 0; i < 5; i++) {
printf("*(ptr + %d) %d %p\n",
i, *(ptr + i), (void*)(ptr + i));
}
printf("\nAddress differences:\n");
printf(" ptr+1 - ptr = %ld bytes\n",
(long)((char*)(ptr+1) - (char*)ptr));
printf(" This equals sizeof(int) = %zu\n", sizeof(int));
// Increment pointer
printf("\nPointer increment:\n");
printf(" Original ptr: %p, *ptr = %d\n", (void*)ptr, *ptr);
ptr++;
printf(" After ptr++: %p, *ptr = %d\n", (void*)ptr, *ptr);
ptr++;
printf(" After ptr++: %p, *ptr = %d\n", (void*)ptr, *ptr);
}
/* ============================================================
* EXAMPLE 9: Modifying Variables via Pointers
* ============================================================ */
void example9_modify(void) {
printf("\n=== EXAMPLE 9: Modifying Variables via Pointers ===\n\n");
int a = 10, b = 20;
int *ptr = &a;
printf("Initial: a = %d, b = %d, ptr points to a\n", a, b);
// Modify a through pointer
*ptr = 100;
printf("After *ptr = 100: a = %d\n", a);
// Increment through pointer
(*ptr)++;
printf("After (*ptr)++: a = %d\n", a);
// Change what pointer points to
ptr = &b;
printf("\nNow ptr points to b\n");
*ptr = 200;
printf("After *ptr = 200: b = %d\n", b);
// Demonstrate the difference between *ptr++ and (*ptr)++
int arr[] = {1, 2, 3};
ptr = arr;
printf("\nDifference between *ptr++ and (*ptr)++:\n");
printf(" Array: {1, 2, 3}, ptr points to arr[0]\n");
int value1 = *ptr++; // Gets value, then moves pointer
printf(" value1 = *ptr++: value1 = %d, ptr now at arr[1]\n", value1);
ptr = arr; // Reset
int value2 = (*ptr)++; // Increments value at pointer
printf(" value2 = (*ptr)++: value2 = %d, arr[0] = %d\n", value2, arr[0]);
}
/* ============================================================
* EXAMPLE 10: Swapping Values Using Pointers
* ============================================================ */
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
void example10_swap(void) {
printf("\n=== EXAMPLE 10: Swapping Values Using Pointers ===\n\n");
int x = 10, y = 20;
printf("Before swap: x = %d, y = %d\n", x, y);
swap(&x, &y); // Pass addresses
printf("After swap: x = %d, y = %d\n", x, y);
printf("\nHow it works:\n");
printf("1. swap() receives addresses of x and y\n");
printf("2. It dereferences to access/modify the actual values\n");
printf("3. Changes persist because we modified original variables\n");
}
/* ============================================================
* EXAMPLE 11: Returning Multiple Values
* ============================================================ */
void getMinMax(int arr[], int size, int *min, int *max) {
*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 example11_multiple_returns(void) {
printf("\n=== EXAMPLE 11: Returning Multiple Values ===\n\n");
int arr[] = {45, 12, 89, 3, 67, 23, 56};
int size = sizeof(arr) / sizeof(arr[0]);
int min, max;
printf("Array: ");
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
getMinMax(arr, size, &min, &max);
printf("Minimum: %d\n", min);
printf("Maximum: %d\n", max);
printf("\nThe function used pointers to 'return' two values!\n");
}
/* ============================================================
* EXAMPLE 12: Pointer Comparison
* ============================================================ */
void example12_comparison(void) {
printf("\n=== EXAMPLE 12: Pointer Comparison ===\n\n");
int arr[] = {10, 20, 30, 40, 50};
int *p1 = &arr[1];
int *p2 = &arr[3];
int *p3 = &arr[1];
printf("Array: {10, 20, 30, 40, 50}\n");
printf("p1 points to arr[1] (20)\n");
printf("p2 points to arr[3] (40)\n");
printf("p3 points to arr[1] (20)\n\n");
// Equality
printf("p1 == p3? %s (both point to arr[1])\n",
(p1 == p3) ? "Yes" : "No");
printf("p1 == p2? %s\n",
(p1 == p2) ? "Yes" : "No");
// Relational
printf("\np1 < p2? %s (arr[1] comes before arr[3])\n",
(p1 < p2) ? "Yes" : "No");
printf("p2 > p1? %s\n",
(p2 > p1) ? "Yes" : "No");
// Distance
printf("\np2 - p1 = %ld elements\n", p2 - p1);
}
/* ============================================================
* EXAMPLE 13: const with Pointers
* ============================================================ */
void example13_const(void) {
printf("\n=== EXAMPLE 13: const with Pointers ===\n\n");
int x = 10, y = 20;
// 1. Pointer to const int (can't modify value through pointer)
const int *ptr1 = &x;
// *ptr1 = 100; // ERROR!
ptr1 = &y; // OK - can change what it points to
printf("const int *ptr: Points to %d (can change pointer, not value)\n", *ptr1);
// 2. const pointer to int (can't change what it points to)
int *const ptr2 = &x;
*ptr2 = 100; // OK - can modify value
// ptr2 = &y; // ERROR!
printf("int *const ptr: Points to %d (can change value, not pointer)\n", *ptr2);
// 3. const pointer to const int (can't change either)
const int *const ptr3 = &y;
// *ptr3 = 100; // ERROR!
// ptr3 = &x; // ERROR!
printf("const int *const ptr: Points to %d (can't change anything)\n", *ptr3);
printf("\nRead right-to-left:\n");
printf(" const int *ptr ā ptr is a pointer to const int\n");
printf(" int *const ptr ā ptr is a const pointer to int\n");
printf(" const int *const ā ptr is a const pointer to const int\n");
}
/* ============================================================
* EXAMPLE 14: void Pointers
* ============================================================ */
void example14_void_pointer(void) {
printf("\n=== EXAMPLE 14: void Pointers ===\n\n");
int i = 42;
float f = 3.14f;
char c = 'A';
void *ptr; // Generic pointer - can point to any type
// Point to int
ptr = &i;
printf("Pointing to int: %d\n", *(int*)ptr);
// Point to float
ptr = &f;
printf("Pointing to float: %.2f\n", *(float*)ptr);
// Point to char
ptr = &c;
printf("Pointing to char: %c\n", *(char*)ptr);
printf("\nvoid* is useful for:\n");
printf(" - Generic functions (like qsort, malloc)\n");
printf(" - Storing pointers of unknown type\n");
printf(" - Must cast before dereferencing!\n");
}
/* ============================================================
* MAIN FUNCTION
* ============================================================ */
int main(void) {
printf("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
printf("ā INTRODUCTION TO POINTERS - EXAMPLES ā\n");
printf("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
example1_basics();
example2_address_of();
example3_dereference();
example4_types();
example5_initialization();
example6_null();
example7_multiple_pointers();
example8_arithmetic();
example9_modify();
example10_swap();
example11_multiple_returns();
example12_comparison();
example13_const();
example14_void_pointer();
printf("\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
printf("All examples completed!\n");
return 0;
}