Mastering Pointers in C/C++: 10 Practical Coding Exercises for Beginners

If you are diving into C or C++ programming, there is one concept you simply cannot escape: Pointers. Often considered the first major hurdle for beginners, pointers are actually incredibly powerful tools that give you direct access to memory and help you write highly efficient code.

Before jumping into the exercises below, if you need a quick conceptual refresher, I highly recommend checking out some classic guides such as [Pointers in C Programming: What is Pointer, Types & Examples] or an [Introduction to C Pointers].

To help you solidifying your understanding, here are 10 practical pointer exercises, complete with reference solutions. Let's code!

Exercise 1: Basic Pointer Syntax

Goal: Design a C program to demonstrate the foundational syntax of pointers, including pointer declaration, address-of retrieval (&), and dereferencing (*).

Reference Solution:

  1. /* Pointer Basic Syntax
  2. Author: Holan */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. int main() {
  6. int n = 50; // Variable declaration
  7. int *ip; // Pointer declaration
  8. ip = &n; // Assigning the address of 'n' to pointer 'ip'
  9. printf("The address of n (&n): %X\n", &n);
  10. printf("The value of n: %i\n", n);
  11. printf("The address of ip (&ip): %X\n", &ip);
  12. printf("The value stored in ip (address of n): %X\n", ip);
  13. printf("The value decompressed/dereferenced (*ip): %i\n", *ip);
  14. return 0;
  15. }

Exercise 2: Dynamic Memory Allocation

Goal: Write a C program that dynamically allocates memory for an array of integers based on user input using malloc(), and make sure to release it properly using free().

Reference Solution:

  1. /* Dynamic memory allocation
  2. Author: Holan */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. int main() {
  6. int n;
  7. int *pI;
  8. printf("How many integers? ");
  9. scanf("%d", &n);
  10. // Allocating memory dynamically using malloc
  11. pI = (int *) malloc(n * sizeof(int));
  12. if(pI == NULL) // Error handling if allocation fails
  13. {
  14. printf("Couldn't allocate memory\n");
  15. return 0; // Exit the program
  16. }
  17. printf("Memory successfully allocated.\n");
  18. // Always remember to free the memory allocated by malloc
  19. free(pI);
  20. return 0;
  21. }

Exercise 3: Multiplying Two Numbers Using Pointers

Goal: Create a simple program that takes two numbers from the user and multiplies them together. The catch? You must perform the math using pointers!

Reference Solution:

  1. /* Multiplying two numbers with pointers
  2. Author: Holan */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. int main() {
  6. int n1, n2;
  7. int *pn1, *pn2, product;
  8. printf("Enter num1: ");
  9. scanf("%d", &n1);
  10. printf("Enter num2: ");
  11. scanf("%d", &n2);
  12. // Assigning addresses to pointers
  13. pn1 = &n1;
  14. pn2 = &n2;
  15. // Dereferencing the pointers to multiply the values
  16. product = *pn1 * *pn2;
  17. printf("The product of %d and %d is %d\n", *pn1, *pn2, product);
  18. return 0;
  19. }

Exercise 4: Navigating Arrays with Pointers

Goal: In C, arrays and pointers are closely related. Write a program that uses a pointer to access and print every element of an integer array.

Reference Solution:

  1. /* Pointer and array
  2. Author: Holan */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #define N 5
  6. int main() {
  7. int a[N] = {2, 3, 5, 7, 11};
  8. int *pI = a; // Point to the base address of the array
  9. for(int i = 0; i < N; i++) {
  10. // Accessing array elements using pointer offsets
  11. printf("a[%d] = %d\t", i, *(pI + i));
  12. }
  13. return 0;
  14. }

Exercise 5: Pointer Arithmetic (Increment and Decrement)

Goal: In Exercise 4, we accessed elements by adding an integer to the pointer (*(pI + i)). For this exercise, achieve the exact same behavior, but use the increment (++) and decrement (--) operators instead.

(Tip: If you want to know more about the underlying mechanics, search for tutorials on "How pointer arithmetic works".)

Reference Solution:

  1. /* Pointer Arithmetic: increment and decrement
  2. Author: Holan */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #define N 5
  6. int main() {
  7. int a[N] = {2, 3, 5, 7, 11};
  8. int *pI = a;
  9. printf("Pointer increment:\n");
  10. // Print and move the pointer forward
  11. for(int i = 0; i < N; i++) {
  12. printf("a[%d] = %d\t", i, *(pI++));
  13. }
  14. printf("\n\nPointer decrement:\n");
  15. // Move the pointer backward to read in reverse order
  16. for(int i = N - 1; i >= 0; i--) {
  17. printf("a[%d] = %d\t", i, *(--pI));
  18. }
  19. return 0;
  20. }

Exercise 6: Calculating String Length

Goal: Strings in C are character arrays terminated by a null character ('\0'). Write a program that calculates the exact length of a user-inputted string using pointer traversal.

Reference Solution:

  1. /* Length of a string
  2. Author: Holan */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. int main() {
  6. char str[100];
  7. int len = 0;
  8. printf("Enter a string: ");
  9. // Allows reading string with spaces until a newline is hit
  10. scanf("%[^\n]s", str);
  11. char *pC = str;
  12. // Loop through the characters until hitting the null terminator
  13. while(*pC != '\0') {
  14. len++;
  15. pC++; // Move to the next character address
  16. }
  17. printf("The length of the given string [%s] is: %d", str, len);
  18. return 0;
  19. }

Exercise 7: Swapping Two Numbers (Call by Reference)

Goal: Create a user-defined function that swaps the values of two variables. You must pass the variables by reference using pointers so the changes persist outside the function.

Reference Solution:

  1. /* Swap two numbers
  2. Author: Holan */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. // Function prototype utilizing pointer arguments
  6. void swapV(double *x, double *y);
  7. int main() {
  8. double n1, n2;
  9. printf("Enter number 1: ");
  10. scanf("%lf", &n1);
  11. printf("Enter number 2: ");
  12. scanf("%lf", &n2);
  13. printf("Before swap - n1: %lf, n2: %lf\n", n1, n2);
  14. // Passing addresses of n1 and n2
  15. swapV(&n1, &n2);
  16. printf("After swap - n1: %f, n2: %f\n", n1, n2);
  17. return 0;
  18. }
  19. // Function implementation
  20. void swapV(double *x, double *y) {
  21. double t = *x;
  22. *x = *y;
  23. *y = t;
  24. }
Exercise 8: Manual String Concatenation

Goal: Without using built-in string functions like strcat(), write a program that uses pointers to combine two separate strings into a single target buffer.

Reference Solution:

  1. /* String concatenation
  2. Author: Holan */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #define LEN 256
  6. int main() {
  7. char str1[LEN];
  8. char str2[LEN];
  9. char str3[LEN * 2];
  10. printf("Enter str1: ");
  11. scanf("%[^\n]%*c", str1);
  12. printf("Enter str2: ");
  13. scanf("%[^\n]%*c", str2);
  14. char *pC = str1;
  15. char *pStr = str3;
  16. // Copy first string to buffer
  17. while(*pC) {
  18. *pStr = *pC;
  19. pC++;
  20. pStr++;
  21. }
  22. // Append second string to buffer
  23. pC = str2;
  24. while(*pC) {
  25. *pStr = *pC;
  26. pC++;
  27. pStr++;
  28. }
  29. // Crucial step: manually terminate the string with '\0'
  30. *pStr = '\0';
  31. printf("Str1: %s\nStr2: %s\nConcatenated Str3: %s\n", str1, str2, str3);
  32. return 0;
  33. }

Exercise 9: Handling the Null Pointer

Goal: A null pointer points to nowhere. Attempting to dereference it will crash your program. Write a program that demonstrates how to safely check for NULL before accessing pointer data.

Reference Solution:

  1. /* NULL pointer
  2. Author: Holan */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. int main() {
  6. int *iP = NULL; // Initializing pointer to NULL
  7. if(iP == NULL) {
  8. printf("The value of iP is %u (It is a NULL pointer)\n", iP);
  9. // WARNING: De-commenting the line below will crash your application!
  10. // printf("The value of *iP is %d", *iP);
  11. } else {
  12. printf("The value of iP is %u\n", iP);
  13. printf("The value of *iP is %d\n", *iP);
  14. }
  15. return 0;
  16. }

Exercise 10: Function Pointers

Goal: Pointers don't just point to data; they can also point to functions! Create basic arithmetic functions (add, subtract, multiply, divide) and execute them dynamically through a single function pointer.

Reference Solution:

  1. /* Function pointers
  2. Author: Holan */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. // Mathematical function prototypes
  6. double add(double n1, double n2);
  7. double sub(double n1, double n2);
  8. double mul(double n1, double n2);
  9. double divi(double n1, double n2);
  10. int main() {
  11. double a = 3.44, b = 9.999;
  12. // Declaring a function pointer and initializing it to 'add'
  13. double (*op)(double, double) = add;
  14. printf("The addition of %f and %f is %f\n", a, b, op(a, b));
  15. op = sub;
  16. printf("The subtraction of %f and %f is %f\n", a, b, op(a, b));
  17. op = mul;
  18. printf("The multiplication of %f and %f is %f\n", a, b, op(a, b));
  19. op = divi;
  20. printf("The division of %f and %f is %f\n", a, b, op(a, b));
  21. return 0;
  22. }
  23. double add(double a, double b) { return a + b; }
  24. double sub(double a, double b) { return a - b; }
  25. double mul(double a, double b) { return a * b; }
  26. double divi(double a, double b) { return a / b; }

Wrapping Up

Pointers might feel intimidating at first, but once you master how addresses and variables interact in memory, they become an invaluable asset in your programming toolkit.

If you found these exercises helpful, please consider supporting the blog by clicking the ads or buying me a coffee. Happy coding! 

留言

這個網誌中的熱門文章