Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

String Manipulation with Character Pointers

Hello! In our last lesson, we explored how to pass pointers to functions to modify their arguments, a technique known as simulating pass-by-reference. You saw how passing the address of an int allowed a swap function to alter the original variables.

Today, we'll apply these powerful pointer concepts to one of C's most common data types: strings. You've already worked with strings as character arrays. Now, you'll learn how to manipulate them directly and efficiently using character pointers (char *). This approach is not just a different way of doing things; it's fundamental to how C's standard library works and is key to writing high-performance code that processes text.

By the end of this lesson, you will be able to use character pointers to traverse, read, and modify strings, solidifying your understanding of the deep relationship between pointers and arrays in C.

1. How Pointers and Strings Connect

Let's start by reinforcing a core concept. In C, a "string" is not a built-in type. It's a convention: a null-terminated character array. This means it's an array of characters where the end is marked by a special null character, '\0'.

This structure makes strings a perfect match for pointers. A pointer of type char * can store the memory address of the first character in the array. Since the characters of a string are stored contiguously in memory, we can then use pointer arithmetic to move from one character to the next.

This diagram shows how the string "Hello" is stored in memory as a `char` array. Each character, including the final null terminator `\0`, occupies a consecutive memory address.

We can create a pointer that "points to" this string.

Here, the pointer variable `ptr` holds the starting memory address (100) of the character array `str`. We say that `ptr` points to the string.

This gives us a powerful way to access the string's content.

2. Traversing a String with a Pointer

The two fundamental pointer operations we've learned—dereferencing (*) and arithmetic (++)—are all we need to iterate through a string.

  • *p: Dereferences the pointer p to give us the char value at the memory address it's currently pointing to.
  • p++: Increments the pointer p to point to the memory address of the next character in the string.

Let's see this in action. The following video provides a step-by-step guide on how to loop through a string using a pointer.

Iterate Through A String Using A Pointer | C Programming Example

This video from Portfolio Courses, "Iterate Through A String Using A Pointer," will walk you through the entire process, from setting up the pointer to building the loop.

Please watch the following segments: First, get a quick refresher on strings and the null terminator in the introduction. Next, see how to declare a char * pointer and make it point to the beginning of a string in the segment on initializing a pointer. Then, learn how pointer arithmetic (p++) and dereferencing (*p) work together in the section on accessing characters. Finally, see how this is all combined in a while loop to iterate through the string.

The core logic you just saw can be summarized in this common C idiom:




#include <stdio.h>

int main(void) {
    char message[] = "Jump";
    char *p = message; // p points to the first character, 'J'

    // Loop until the pointer p points to the null terminator '\0'
    while (*p != '\0') {
        printf("%c", *p); // Print the character p is pointing to
        p++;              // Move p to point to the next character
    }
    printf("\n"); // Output: Jump

    return 0;
}

A More Concise Loop

As the video also explains, C's boolean logic allows for a more compact loop. The null character '\0' has an integer value of 0. In a while condition, a value of 0 is treated as false, and any non-zero value is true. Since all printable characters have non-zero values, the loop condition while (*p != '\0') can be shortened to just while (*p).

Iterate Through A String Using A Pointer | C Programming Example

Let's revisit the same video to understand this C idiom.

Watch the short segment explaining how the null terminator evaluates to false, which simplifies the loop condition.

This leads to the more common and idiomatic way of writing the loop:

// Idiomatic C loop for string traversal
while (*p) {
    printf("%c", *p++); // The post-increment p++ happens after *p is evaluated
}

This version combines the print and the increment into a single, efficient line.

3. Modifying Strings with Pointers: Reversing a String

Now, let's tackle a more complex task that combines what you've learned about string traversal with the pass-by-reference technique from the previous lesson. We will write a function that reverses a string in place.

The algorithm uses two pointers:

  1. A start pointer, initialized to the beginning of the string.
  2. An end pointer, initialized to the last character of the string (just before the null terminator).

We then loop, swapping the characters pointed to by start and end, and moving the pointers towards each other (start++, end--). The loop stops when the pointers meet or cross in the middle.

This process is a fantastic practical application of pointer manipulation.

Reverse A String Using Pointers | C Programming Example

The video "Reverse A String Using Pointers" by Portfolio Courses provides a complete implementation of this algorithm.

Watch the video from the function signature explanation through the discussion of the loop condition. Pay close attention to these key steps: The reverse_string(char *string) function signature. How two pointers, start and end, are initialized. The loop that finds the end of the string. The swap logic using a temporary variable, which should look very familiar! The while (start < end) condition that controls the main loop.

After watching, try to write the reverse_string function yourself. This is an excellent exercise to test your understanding.

4. A Critical Pitfall: Character Arrays vs. String Literals

When using pointers with strings, there is a crucial distinction you must understand to avoid program crashes.

  1. char message[] = "Hello";
    This creates a mutable character array on the stack. You are free to change its contents. The variable message is the array itself.

  2. char *message = "Hello";
    This creates a pointer to a string literal. String literals are often stored in a read-only section of memory. The variable message is a pointer that holds the address of the literal "Hello". Attempting to modify the string through this pointer results in undefined behavior, which usually means a crash.

String Pointer in C: Complete Beginner Guide - upGrad

The "upGrad" article on string pointers has a great section on common mistakes.

Read the section titled "Common Pitfalls to Avoid When Using String Pointers in C". Focus on item #1, "Trying to Modify a String Literal," which explains this exact problem.

Here is a code example illustrating the difference:




#include <stdio.h>

int main(void) {
    // This is an array, stored in writable memory (usually the stack).
    // It is safe to modify.
    char str_array[] = "Writable";
    printf("Original array: %s\n", str_array);
    str_array[0] = 'w'; // OK!
    printf("Modified array: %s\n", str_array);

    // This is a pointer to a string literal, which is often in read-only memory.
    // It is UNSAFE to modify.
    char *str_literal = "Read-Only";
    printf("Original literal: %s\n", str_literal);
    
    // The following line will likely cause a segmentation fault (crash).
    // str_literal[0] = 'r'; // DANGER: Undefined Behavior!

    return 0;
}

Rule of thumb: If you need to modify a string, declare it as a character array (char name[]). If you only need to read it, using a pointer (const char *name) is efficient and signals your intent. The const keyword tells the compiler that the function promises not to change the string, which is good practice.

Conclusion

In this lesson, you've taken a significant step forward by applying your knowledge of pointers to string manipulation. This is a cornerstone of effective C programming.

Key Takeaways:

  • Strings in C are null-terminated character arrays.
  • A char * pointer can be used to efficiently traverse a string by using pointer arithmetic (p++) and dereferencing (*p).
  • A common loop condition for string traversal is while (*p), which continues until the pointer reaches the null terminator (\0).
  • Passing a char * to a function is the standard, efficient way to work with strings, as it avoids copying the entire string.
  • You must be careful about the distinction between a mutable character array (char s[]) and a pointer to an immutable string literal (char *s), as trying to modify a literal leads to undefined behavior.

Preview of the Next Lesson:
So far, we've worked with pointers to fundamental types (int, char) and arrays. But what if you need to group different types of data together—like a student's name, ID, and GPA? In the next lesson, we will introduce structs, which allow you to define your own custom data types. You will then learn how to combine structs with pointers, opening the door to creating powerful and complex dynamic data structures.

Can't find a good explanation? Sign up and we'll make it for you

Sign up