C char Arrays: Guide from Basics to String Operations

1. Introduction

The C language is still widely used in system development and embedded development. Among its features, “char arrays” are one of the most basic and important syntactic elements for handling strings.

The C language does not have a built-in string type. Instead, it represents strings by using arrays of characters (char arrays). Because this is not very intuitive for beginners, understanding char arrays often becomes a major hurdle in learning C.

Also, if you do not understand the nuances such as the distinction between char arrays and char pointers (char*) and the presence of the null character (\0), it can lead to unexpected bugs.

In this article, we focus on the topic \”C language char array\” and provide a clear explanation ranging from basic usage to advanced techniques and how to avoid common errors.

If you are about to study the C language seriously or want to review char arrays, please read through to the end. In the next chapter, we will first explain the definition and basic mechanics of char arrays.

2. What is a char array?

In the C language, a “char array” is an array for storing multiple characters (char type) together. This is the fundamental structure for handling strings.

What is the char type?

In C, the char type is a data type for representing a single character. For example, you can define a one-character variable as follows.

char c = 'A';

Thus, a single character enclosed in single quotes, such as 'A', is defined as a char type.

Basic syntax of a char array

To store multiple characters, use an array of the char type. Define it as follows:

char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

This array allocates memory for six characters: the five-character string "Hello" plus a null character (\0).

The importance of the null character ('

Array size and cautions

'
)

In C, a null character null character '\0' is used to indicate the end of a string. Without this marker, string manipulation functions may not work correctly and can exhibit unexpected behavior.

char str[] = "Hello"; // '\0' is automatically appended at the end

As shown above, when you use a string literal enclosed in double quotes, the compiler automatically appends a '\0' at the end.

3. Declaration and Initialization of char Arrays

When using a char array, you should allocate a size equal to the required number of characters + 1 (for the null character). Assigning a string to an undersized array can cause a buffer overflow, potentially leading to an abnormal program termination.

Static Declaration and Initialization

To use a char array, you first need appropriate declaration and initialization. Here, we will explain the basic declaration methods for char arrays in C, how to initialize them, and also the use of dynamic memory.

Initialization with String Literals

The most basic method is to declare the array with an explicit size and initialize it one character at a time.

char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

Doing this, str can be treated as the string "Hello". The important point is to always include '\0' at the end.

Assigning a Literal with a Specified Size

In C, you can also perform simple initialization using string literals as shown below.

char str[] = "Hello";

In this case, the array size is automatically set to the length of "Hello" plus '\0', i.e., 6 characters. If you want to modify the string contents, declaring it as a char array allows safe rewriting.

Using Dynamic Memory Allocation (malloc)

You can also initialize with a string literal while specifying the array size, but be careful of insufficient size.

char str[5] = "Hello"; // ❌ Error cause (insufficient size)

As shown above, "Hello" requires 5 characters plus 1 character (‘\0’) for a total of 6 characters. Therefore, you need at least char str[6].

4. String Manipulation

If you want to handle strings more flexibly, there is a method to dynamically allocate a char array using malloc.

#include 
#include 

char* str = malloc(6 * sizeof(char));
strcpy(str, "Hello");

With this approach, memory is allocated dynamically and the string is accessed through the pointer. After use, be sure to release the memory with free(str);.

String Copy: strcpy

In C, it is common to use standard library functions for string manipulation using char arrays. Here we explain the basic string manipulation functions and how to use them, with concrete examples.

String Concatenation: strcat

strcpy is a function that copies one string into another char array.

#include 

char src[] = "Hello";
char dest[10];
strcpy(dest, src);

Note: If dest does not have sufficient size, it can cause a buffer overflow. Ensure the size is the length of the string to copy plus 1 (for the null terminator).

Getting String Length: strlen

strcat concatenates two strings. It appends the contents of the second argument to the end of the first argument.

#include 

char str1[20] = "Hello";
char str2[] = " World";
strcat(str1, str2);

As a result, str1 becomes "Hello World". This also assumes that the array of the first argument has enough space to accommodate the total size after concatenation.

String Comparison: strcmp

strlen function returns the length of a string (the number of characters excluding the null terminator).

#include 

char str[] = "Hello";
int len = strlen(str); // len = 5

Since the null terminator is not counted, people unfamiliar with C need to be careful.

String Search: strchr and strstr

To compare whether two strings are the same, use strcmp.

#include 

char str1[] = "Hello";
char str2[] = "World";

if (strcmp(str1, str2) == 0) {
    // equal
} else {
    // different
}

This function returns 0 if the strings are equal, and returns the difference of the character codes if they differ.

5. Difference between char arrays and pointers

To search for a specific character or substring, you can use functions like the following.

#include 

char str[] = "Hello World";

// character search
char *ptr1 = strchr(str, 'o'); // pointer to first 'o'

// substring search
char *ptr2 = strstr(str, "World"); // pointer to start of "World"

If not found, both functions return NULL.

Declaration differences

When handling strings in C, char array and char pointer (char*) may seem similar, but they actually have different characteristics. Understanding this difference correctly can prevent memory misuse and unexpected bugs.

Differences in mutability

First, let’s look at the differences in declaration methods.

char str1[] = "Hello";  // char array
char *str2 = "Hello";   // char pointer

str1 is an array with actual storage, and 6 bytes (“Hello” + ‘\\0’) are allocated in memory. On the other hand, str2 is a pointer to the memory region where the string literal is stored.

Differences in memory layout

Since str1 is a char array, the characters inside the array can be freely changed.

str1[0] = 'h'; // OK

However, when accessing a string literal via a pointer as in char* str2 = "Hello";, modifying its contents is undefined behavior.

str2[0] = 'h'; // ❌ Undefined behavior (possible runtime error)

Differences in obtaining size

  • char array
  • char pointerconstant area (read-only)heap area (malloc, etc.)you need to be careful with memory handling

Summary: Points for choosing between them

For an array, sizeof(str1) returns the total byte count of the array.

char str1[] = "Hello";
printf("%lu", sizeof(str1)); // → 6 (including '\\0')

On the other hand, for a pointer, sizeof(str2) returns the size of the pointer itself (typically 4–8 bytes), so it cannot be used to obtain the array size.

char *str2 = "Hello";
printf("%lu", sizeof(str2)); // → 8 (64-bit environment)

 

6. Passing char arrays to functions

Itemchar arraychar pointer
Content changepossibleNot allowed in principle (for literals)
Get Sizesizeof()strlen()
Rewrite usageSuitableNot suitable (read-only)
FlexibilityFixed sizeFlexible, but caution is needed.

Basic example: passing a char array as an argument

In C, when passing an array to a function, it is passed by pointer rather than by value. This is also true for char array, and when you pass it to a function, the array’s starting address (pointer) is passed.

Understanding this mechanism is crucial when manipulating strings or modifying their contents across functions.

Function that modifies contents

#include 

void printString(char str[]) {
    printf("String: %s\n", str);
}

int main() {
    char greeting[] = "Hello";
    printString(greeting);
    return 0;
}

In this example, the printString function is passed an argument of type char[], but in fact it is received as char*. In other words, char str[] is the same as char *str.

Managing array size

When modifying the contents of an array inside a function, you can directly manipulate the data via the passed address.

#include 

void toUpperCase(char str[]) {
    for (int i = 0; str[i] != ' '; i++) {
        if ('a' <= str[i] && str[i] <= 'z') {
            str[i] = str[i] - ('a' - 'A');
        }
    }
}

int main() {
    char text[] = "hello world";
    toUpperCase(text);
    printf("%s\n", text); // Output: HELLO WORLD
    return 0;
}

Thus, even when you want to change the contents of an array, because it is treated as a pointer, the operations performed inside the function are reflected in the caller.

Read‑only arguments using const

In C, when passing an array to a function, size information is not passed together. Therefore, the best practice for safe manipulation is to also pass the size as an argument.

void printChars(char str[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%c ", str[i]);
    }
    printf("\n");
}

Also, it is common to use the strlen function to dynamically obtain the length of a string. However, be careful not to use it on arrays that are not null‑terminated.

7. Practical Example: Displaying a String in Reverse Order

If a string is not modified inside a function, it is advisable to use const char* to explicitly indicate that it is read‑only.

void printConstString(const char *str) {
    printf("%s\n", str);
}

This helps prevent unintended modifications and clearly conveys the function’s contract.

Purpose

Here, we will actually create a program that displays a string in reverse order using the char array knowledge we have learned so far.

Sample Code

It outputs the string entered by the user one character at a time from the end toward the beginning. This is highly effective as practice of array manipulation, string length retrieval, and loop processing.

Explanation

#include 
#include 

void printReversed(char str[]) {
    int len = strlen(str);
    for (int i = len - 1; i >= 0; i--) {
        putchar(str[i]);
    }
    putchar('n');
}

int main() {
    char text[100];

    printf("Please enter a string: ");
    fgets(text, sizeof(text), stdin);

    // Remove newline character (countermeasure when using fgets)
    size_t len = strlen(text);
    if (len > 0 && text[len - 1] == 'n') {
        text[len - 1] = '\0';
    }

    printf("When displayed in reverse order: ");
    printReversed(text);

    return 0;
}

Execution Example

  • fgets
  • We also make sure to remove the (newline characters) that are appended at the end of the input.
  • strlen()

Application Tips

Please enter a string: OpenAI
When displayed in reverse order: IAnepO

8. Common Errors and Their Solutions

This process can be applied to string palindrome detection and understanding stack structures, among other algorithmic studies. It can also be rewritten using pointer arithmetic, providing a more advanced practice problem.

1. Forgetting the null terminator (

2. Insufficient Buffer Size

)

When working with char配列 in C, there are several pitfalls that can trap everyone from beginners to experts. Here we will explain the frequently occurring errors and their prevention and solutions in detail.

3. Modifying String Literals

One of the most common mistakes is forgetting to add the null character (\0) at the end of a string.

char str[5] = {'H', 'e', 'l', 'l', 'o'}; // ❌ No '\0' at the end
printf("%sn", str); // Undefined behavior

Solution:

char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; // ✅ Correct

Alternatively, using a string literal automatically adds the null character.

4. Forgetting to Handle Newline Characters from fgets

strcpy and strcat, when the destination array size is insufficient causes memory corruption (buffer overflow).

char str1[5];
strcpy(str1, "Hello"); // ❌ Copying 6 characters to array of size 5

Solution:

  • ensure sufficient size
  • Also consider using a safer
char str1[6];
strncpy(str1, "Hello", sizeof(str1) - 1);
str1[5] = '\0'; // Explicitly add null character at the end just in case

5. Confusing Pointers and Arrays

char *str = "Hello"; may point to a region that cannot be modified possibility of pointing to a non-writable area. Writing to it will cause a runtime error.

char *str = "Hello";
str[0] = 'h'; // ❌ Segmentation fault at runtime

Solution:

char str[] = "Hello"; // ✅ Declare as a modifiable array
str[0] = 'h';

9. Summary

fgets may leave a trailing newline character (n) at the end of the string, so you need to handle it.

fgets(str, sizeof(str), stdin);
// The string will contain something like "Hellon\0"

Solution:

size_t len = strlen(str);
if (len > 0 && str[len - 1] == 'n') {
    str[len - 1] = '\0';
}

What you learned in this article

Because they look similar, confusing char* with char[] can lead to undefined behavior. You need to be aware of differences such as size retrieval (sizeof) and mutability.

Advice for future learning

In this article, we explained “char arrays in C language” step by step from basics to advanced applications. Finally, we review the content of this article and introduce guidance for future learning.

What you learned in this article

  • Role and Declaration of char Arrays In C language, since there is no string type, strings are handled using arrays of char type.
  • Importance of String Literals and Null Characters (\0) To represent a string, a null character at the end is indispensable.
  • String manipulation using standard library functions , , , By using these, you can efficiently process strings.
  • Differences between char arrays and char pointers Arrays and pointers are similar yet distinct, with clear differences in memory structure and mutability.
  • How to pass arrays to functions and considerations for safety Since arrays are actually passed as pointers, care must be taken with modifications and size management.
  • Solidifying Understanding Through Practical Examples and Common Errors Through applying real code and handling errors, we learned more realistic usage.

Advice for future learning

Understanding how to use char arrays is the first step to understanding the fundamentals of memory manipulation in C language. The knowledge you gained here can be applied to the next steps such as the following.

  • Pointer Arithmetic
  • Dynamic Memory Managementmallocfree
  • Combining with struct

Also, by reading code written by others, you can absorb perspectives and coding styles you didn’t have. Developing a habit of reading real projects and OSS (Open Source Software) is also very effective.

Because C language offers high flexibility, it can be dangerous if not handled correctly, but if you carefully build the fundamentals, it becomes a very powerful tool. Understanding char arrays is the first step. Please use this article as a reference and steadily improve your skills.