C Program For Reversing A String

9 min read

Reversing a string in C is a fundamental programming task that illustrates how to manipulate character arrays, work with pointers, and manage memory efficiently. The operation involves taking a sequence of characters and producing a new sequence where the order of characters is inverted. On the flip side, for example, the string "hello" becomes "olleh". This simple transformation serves as a building block for more complex algorithms such as palindrome checking, string rotation, and data encryption. In this guide we will explore several approaches to implement a c program for reversing a string, discuss the underlying concepts, and highlight best practices to avoid common mistakes That's the part that actually makes a difference..

Understanding the Problem

Before writing any code, it is essential to clarify what “reversing a string” means in the context of C. Also, a string in C is an array of characters terminated by a null character ('\0'). The reversal process must preserve this null terminator while swapping characters from the start and end of the array until they meet in the middle. The result should be a valid C string that can be printed or used in further computations.

Basic In‑Place Reversal

The most straightforward method is to modify the original array directly. This technique is called in‑place reversal because it does not require additional memory for a second array. The algorithm works as follows:

  1. Determine the length of the string, excluding the null terminator.
  2. Set two indices: one at the beginning (i = 0) and one at the end (j = length - 1).
  3. Swap the characters at these indices.
  4. Move the indices toward each other (i++, j--).
  5. Repeat until i >= j.

Implementation

#include 
#include 

void reverse_in_place(char *str) {
    int len = strlen(str);
    int i = 0, j = len - 1;
    while (i < j) {
        char temp = str[i];
        str[i] = str[j];
        str[j] = temp;
        i++;
        j--;
    }
}

int main() {
    char s[] = "example";
    reverse_in_place(s);
    printf("Reversed: %s\n", s);
    return 0;
}

In this example, strlen computes the length, and the loop swaps characters using a temporary variable. The function modifies the original array, which is acceptable when you no longer need the original order.

Handling Edge Cases

A strong implementation must consider several edge cases:

  • Empty string: The length is zero, so the loop should not execute.
  • Single character: Swapping is unnecessary but harmless.
  • String with spaces or special characters: The algorithm treats all characters uniformly, so spaces and punctuation are reversed along with letters.
  • Null pointer: If the function receives NULL, it should return immediately to avoid dereferencing an invalid address.

Adding a simple guard at the beginning of reverse_in_place addresses the null pointer scenario:

if (str == NULL) return;

Recursive Approach

Recursion offers an elegant alternative, especially for educational purposes. The idea is to swap the first and last characters and then recursively reverse the substring that excludes those two characters.

void reverse_recursive(char *str, int left, int right) {
    if (left >= right) return;
    char temp = str[left];
    str[left] = str[right];
    str[right] = temp;
    reverse_recursive(str, left + 1, right - 1);
}

The initial call would be reverse_recursive(str, 0, strlen(str) - 1);. While recursion is conceptually clear, it consumes stack space proportional to the string length, making it less suitable for very long strings compared to the iterative method.

Using Library Functions

C’s standard library does not provide a direct reverse function, but you can combine strrev (available on some platforms) or implement a wrapper. On the flip side, relying on non‑standard functions reduces portability. A portable solution is to write your own, as shown earlier.

Performance Considerations

The time complexity of the in‑place algorithm is O(n), where n is the length of the string, because each character is visited at most once. The space complexity is O(1), as only a few temporary variables are used. The recursive version also

has O(n) time complexity, but its space complexity is O(n) because each recursive call adds a new frame to the call stack. For most practical purposes, the iterative in-place approach is more efficient and safer for large inputs Worth keeping that in mind..

Another important consideration is that C strings are arrays of bytes terminated by a null character ('\0'). The simple reversal algorithm shown here reverses bytes, not human-readable characters. Reversing the bytes directly can corrupt such strings. Consider this: this distinction matters for multibyte encodings such as UTF-8, where a single visible character may be represented by multiple bytes. For basic ASCII text, however, the algorithm works as expected.

A slightly safer complete version of the iterative function is shown below:

#include 
#include 

void reverse_in_place(char *str) {
    if (str == NULL) return;

    int len = strlen(str);
    int i = 0;
    int j = len - 1;

    while (i < j) {
        char temp = str[i];
        str[i] = str[j];
        str[j] = temp;

        i++;
        j--;
    }
}

int main() {
    char s[] = "example";

    reverse_in_place(s);

    printf("Reversed: %s\n", s);

    return 0;
}

The output is:

Reversed: elpmaxe

Common Mistakes

One common mistake is trying to reverse a string literal directly:

char *s = "example";
reverse_in_place(s);  // Undefined behavior

String literals may be stored in read-only memory, so modifying them can cause a crash. Instead, use a mutable character array:

char s[] = "example";
reverse_in_place(s);

Another mistake is allocating a new buffer but forgetting to add the null terminator:

char reversed[len + 1];

The extra + 1 is necessary because C strings require space for '\0'. Without it, functions like printf("%s", reversed) may read beyond the intended buffer Small thing, real impact..

Conclusion

Reversing a string in C is a simple but useful operation that demonstrates pointer manipulation, array indexing, and memory management. The most common solution is the iterative in-place method, which swaps characters from both ends of the string until they meet in the middle. It is efficient, requiring O(n) time and O(1) extra space.

Recursive solutions are elegant and useful for learning, but they use additional stack space and are generally less suitable for long strings. Regardless of the method chosen, it is important to check that the string is mutable, properly null-terminated, and handled safely in edge cases such as empty strings or null pointers That's the part that actually makes a difference..

Beyond the basic swap‑loop, there are a few variations that can be useful depending on the context of your program.

Using Pointer Arithmetic Only

If you prefer to work exclusively with pointers rather than array indices, the same logic can be expressed as:

void reverse_ptr(char *str)
{
    if (!str) return;

    char *left  = str;
    char *right = str + strlen(str) - 1;   // points to the last character

    while (left < right) {
        char tmp = *left;
        *left++  = *right;
        *right-- = tmp;
    }
}

Here left and right move toward each other, dereferencing and swapping the characters they point to. This version makes the intent of “two‑ended traversal” explicit and can be slightly faster on architectures where pointer arithmetic is cheaper than index calculations It's one of those things that adds up..

Leveraging memmove for Overlapping Regions

When the source and destination buffers might overlap (for example, if you are reversing a substring inside a larger buffer), memmove guarantees correct behavior:

void reverse_memmove(char *str)
{
    size_t len = strlen(str);
    if (len < 2) return;

    char *tmp = malloc(len);
    if (!tmp) return;   // handle allocation failure as appropriate

    /* copy the string reversed into the temporary buffer */
    for (size_t i = 0; i < len; ++i)
        tmp[i] = str[len - 1 - i];

    /* copy it back; memmove handles overlap safely */
    memmove(str, tmp, len);
    free(tmp);
}

Although this approach uses O(n) extra space, it avoids the pitfalls of manual swapping when the operation is part of a larger in‑place transformation.

Tail‑Recursive Variant (with Compiler Optimization)

A recursive solution can be made tail‑recursive, allowing a smart compiler to reuse the same stack frame:

void reverse_tail(char *left, char *right)
{
    if (left >= right) return;

    char tmp = *left;
    *left    = *right;
    *right   = tmp;

    reverse_tail(left + 1, right - 1);
}

/* wrapper */
void reverse_recursive(char *str)
{
    if (!str) return;
    reverse_tail(str, str + strlen(str) - 1);
}

When compiled with optimizations (-O2 or higher) on GCC or Clang, the recursive calls are often transformed into a loop, giving you the readability of recursion without the stack‑depth penalty.

Handling Wide Characters (wchar_t)

For strings encoded in UTF‑16 or UTF‑32, the same swapping principle applies, but you must operate on the appropriate type:

#include 

void reverse_wcs(wchar_t *ws)
{
    if (!ws) return;
    size_t len = wcslen(ws);
    for (size_t i = 0; i < len / 2; ++i) {
        wchar_t tmp = ws[i];
        ws[i]       = ws[len - 1 - i];
        ws[len - 1 - i] = tmp;
    }
}

Remember that reversing code points does not always produce a visually correct result for complex scripts (combining marks, surrogate pairs, etc.Consider this: ). For full Unicode correctness you would need to grapheme‑cluster‑aware libraries such as ICU Nothing fancy..

Testing Edge Cases

A solid implementation should be exercised with:

  • NULL pointer – should return immediately without dereferencing.
  • Empty string ("") – length zero, loop body never executes.
  • Single‑character string – swapping loop does nothing, leaving the string unchanged.
  • Strings containing the null character inside the buffer (non‑C‑string data) – the algorithm will stop at the first '\0'; if you need to reverse a known‑length buffer, pass the length explicitly instead of relying on strlen.

Performance Note

All of the presented methods run in linear time O(n) with

O(1) auxiliary space (excluding the temporary buffer approach) and are memory‑bandwidth bound on modern architectures. The two‑pointer loop compiles to tight assembly—typically a load, a store, and a pointer increment per iteration—making it difficult to beat without resorting to SIMD intrinsics. For extremely large buffers, a vectorized implementation using SSE/AVX or NEON can process 16–64 bytes per cycle, but the scalar version remains the pragmatic default for general‑purpose code due to its portability and readability The details matter here..

Choosing the Right Approach

Scenario Recommended Method
General purpose, in‑place, ASCII/UTF‑8 code points Two‑pointer while (left < right) loop
Embedded / kernel code (no stdlib, strict stack limits) Two‑pointer loop or XOR swap (if types guarantee no aliasing)
Part of a larger buffer manipulation requiring a scratchpad Temporary buffer + memmove
Teaching / algorithmic clarity (with -O2 guarantee) Tail‑recursive wrapper
Wide‑character strings (wchar_t, char16_t, char32_t) Same two‑pointer logic on the appropriate type
Grapheme‑cluster correct Unicode reversal ICU ubrk_reverse or similar library

Conclusion

Reversing a string in C is a deceptively simple task that exposes the language’s close-to-the-metal nature: pointer arithmetic, memory layout, and the distinction between code units and user‑perceived characters all surface in a few lines of code. Still, the classic two‑pointer swap remains the gold standard for its optimal O(n) time, O(1) space, and zero dependency footprint. Even so, a professional C developer recognizes the boundaries of this algorithm—it reverses code units, not necessarily graphemes—and knows when to reach for a strong Unicode library instead of rolling their own. By mastering the idiomatic patterns shown here and understanding their trade‑offs, you check that this fundamental building block remains correct, efficient, and maintainable across the diverse constraints of real‑world C projects.

Out This Week

Latest Additions

Branching Out from Here

Familiar Territory, New Reads

Thank you for reading about C Program For Reversing A String. We hope the information has been useful. Feel free to contact us if you have any questions. See you next time — don't forget to bookmark!
⌂ Back to Home