C Language Arrays: From Beginner to Mastery – A Comprehensive Guide

Recent Hot Articles

2025 Latest C Language Learning Path | Beginner, Intermediate, Practical

C Language Functions: From Beginner to Mastery – A Comprehensive Guide

C Language Pointers: From Beginner to Mastery – A Comprehensive Guide

C Language Learning Guide: Have You Mastered These Core Knowledge Points?

Beginner’s Guide to Avoiding Pitfalls in C Language: Avoid These 12 Devilish Details to Double Your Efficiency!

Main Content

1. The Essence of Arrays: Why Do We Need Arrays?

In C language, an array is a collection of elements of the same data type stored in contiguous memory space.

  • Core Function: Manage similar data in bulk, avoiding the need to define individual variables repeatedly. For example, when storing the scores of 50 students, using an array <span>int scores[50]</span> is more efficient than defining 50 separate variables.
  • Physical Characteristics: Array elements are contiguously arranged in memory, and the address of each element can be calculated from the base address. Assuming the base address of the array is <span>0x1000</span>, and each element occupies 4 bytes (like <span>int</span> type), then the address of the 3rd element <span>scores[2]</span> is <span>0x1000 + 2×4 = 0x1008</span>.

2. Declaring and Initializing Arrays: How to Create an Array?

1. Declaration Syntax

data_type array_name[element_count];
  • The element count must be a constant or a constant expression (C99 allows variable-length arrays (VLA), but be cautious of scope). Example:
    int nums[5];       // Valid: element count is constant 5  
    const int n = 10;  
    float arr[n];      // Valid (C99): n is a constant expression  
    int m = 20;  
    char str[m];       // Invalid (before C99), valid as VLA after C99 (compiler support required)  
    

2. Initialization Methods

  • Complete Initialization: Explicitly specify the value of all elements.
    int scores[5] = {85, 90, 78, 92, 88};  // All elements initialized  
    
  • Partial Initialization: Unspecified elements are automatically initialized to 0 (for numeric types) or <span>'\0'</span> (for character types).
    int data[5] = {1, 2};  // First two elements are 1, 2; last three are 0  
    char ch_arr[3] = {'a', 'b'};  // Third element is '\0'  
    
  • Omitting Array Length: The compiler automatically infers the length based on the number of initialization values.
    int ages[] = {18, 20, 22};  // Equivalent to int ages[3] = {...}  
    char str[] = "Hello";       // Automatically adds '\0', actual length is 6  
    

3. Accessing Arrays: How to Operate on Array Elements?

1. Subscript Access

Access elements through <span>array_name[subscript]</span>, with subscripts starting from <span>0</span>.

  • Example:
    int arr[3] = {10, 20, 30};  
    printf("%d", arr[1]);  // Outputs 20 (equivalent to *(arr+1))  
    
  • Essence:<span>arr[i]</span> is equivalent to <span>*(arr + i)</span>, the compiler accesses it through pointer arithmetic.

2. The Deep Relationship Between Arrays and Pointers

  • Dual Meaning of Array Name:
    • When the array name is used as a <span>sizeof</span> operand, it returns the total byte size of the entire array (not the pointer size).
      sizeof(arr);  // Result is 5×4=20 (int array)  
      
    • When the array name is used as a <span>&</span> operand, it returns the array pointer (<span>int (*)[5]</span> type).
      int (*p_arr)[5] = &amp;arr;  // Pointer to an array containing 5 ints  
      
    • In Most Cases: the array name is implicitly converted to a pointer to the first element (<span>int*</span> type).
      int arr[5];  
      int *p = arr;  // Equivalent to p = &amp;arr[0]  
      
    • Exceptions:

4. Multidimensional Arrays: How to Handle Two-Dimensional and Higher Data?

1. Logical and Physical Structure of Two-Dimensional Arrays

  • Logical Structure: Similar to a table (rows × columns), for example, <span>int matrix[2][3]</span> represents an array with 2 rows and 3 columns.
  • Physical Structure: Stored continuously in row-major order.
    int matrix[2][3] = {  
        {1, 2, 3},  
        {4, 5, 6}  
    };  
    

    Memory order is:<span>1 → 2 → 3 → 4 → 5 → 6</span>.

2. Address Calculation and Pointer Types

  • The address of the element <span>matrix[i][j]</span> is:<span>&matrix[0][0] + i×number_of_columns + j</span>
  • Row Pointer and Column Pointer:
    int (*row_ptr)[3] = matrix;  // Row pointer, points to an array containing 3 ints (i.e., one row)  
    int *col_ptr = &amp;matrix[0][0]; // Column pointer, points to a single int element  
    

3. Multidimensional Arrays as Function Parameters

  • All dimensions except the first must be specified so that the compiler can calculate the address.
    void print_matrix(int arr[][3], int rows) {  // Correct declaration, number of columns must be specified  
        for (int i=0; i&lt;rows; i++) {  
            for (int j=0; j&lt;3; j++) {  
                printf("%d ", arr[i][j]);  
            }  
        }  
    }  
    

5. Arrays as Function Parameters: Why Do They “Decay”?

When an array is passed as a function parameter, it will decay into a pointer to the first element, and the original array’s length information is lost.

  • Example:
    void func(int arr[5]) {  // Equivalent to void func(int *arr)  
        printf("%d", sizeof(arr));  // Outputs 4 or 8 (pointer size), not 20 (array size)  
    }  
    
  • Solution: When passing an array, an additional length parameter must be passed.
    void process(int *arr, int len) {  
        for (int i=0; i&lt;len; i++) { /* Process elements */ }  
    }  
    

6. Character Arrays and Strings: Special Applications of Arrays

1. The Essence of Strings

Character arrays use <span>'\0'</span> (ASCII code 0) as a termination marker, and the effective length is calculated by the <span>strlen</span> function (excluding <span>'\0'</span>).

  • Initialization Differences:
    char str1[] = "ABC";  // Length is 4 (including '\0')  
    char str2[3] = {'A', 'B', 'C'};  // Not a string, no '\0'  
    

2. String Manipulation Functions

Function Name Functionality Notes
<span>strcpy</span> Copy a string The target array must be large enough to avoid overflow
<span>strcat</span> Concatenate strings Same as above
<span>strcmp</span> Compare strings (lexicographically) Return value: <0 (less than), 0 (equal), >0 (greater than)
<span>sprintf</span> Format output to a character array Similar to <span>printf</span>, result written to array
  • Safe Function Alternatives (C11 standard): Use <span>strcpy_s</span>, <span>strcat_s</span>, and other functions with the <span>_s</span> suffix to detect buffer overflows.

7. Common Errors and Traps: How to Avoid “Pitfalls” with Arrays?

1. Array Out-of-Bounds Access

  • Consequences: Accessing illegal memory may cause program crashes or data corruption.
  • Example (Dangerous!):
    int arr[5];  
    arr[5] = 100;  // Out of bounds, maximum subscript is 4  
    

2. Uninitialized Arrays

  • The values of uninitialized array elements are undefined (garbage values), and must be initialized before use.
    int values[3];  
    printf("%d", values[0]);  // Outputs random value, may cause errors  
    

3. Limitations of Variable-Length Arrays (VLA)

  • C99 allows arrays with lengths determined at runtime (like <span>int arr[n]</span>, where <span>n</span> is a variable), but:
    • Cannot be declared at file scope (only within functions);
    • Cannot be initialized (like <span>int arr[n] = {1,2,3};</span> is illegal).

8. Dynamic Arrays: Breaking the Limitations of Static Arrays

Static arrays have a fixed length, while dynamic arrays allocate space dynamically in heap memory using <span>malloc</span>/<span>realloc</span>.

1. Basic Operation Example

#include &lt;stdlib.h&gt;

// Create dynamic array  
int* create_array(int size) {  
    int *arr = (int*)malloc(size * sizeof(int));  
    if (arr == NULL) { exit(EXIT_FAILURE); }  // Check for memory allocation failure  
    return arr;  
}

// Resize array  
int* resize_array(int *arr, int old_size, int new_size) {  
    int *new_arr = (int*)realloc(arr, new_size * sizeof(int));  
    return new_arr;  // If successful, return new address; if failed, return NULL and original array remains unchanged  
}

// Free memory after use  
void free_array(int *arr) {  
    free(arr);  
}  

2. Dynamic Arrays vs Static Arrays

Feature Static Array Dynamic Array
Memory Allocation Timing Compile Time Runtime
Variable Length No Yes (via <span>realloc</span>)
Memory Location Stack or Global Area Heap

9. Practical Applications: Typical Scenarios for Arrays

  1. Sorting and Searching:
  • Sorting: Algorithms like bubble sort, quick sort, etc., are implemented based on arrays;
  • Searching: Ordered arrays can use binary search (time complexity <span>O(logn)</span>).
  • Matrix Operations: Two-dimensional arrays represent matrices, enabling operations like multiplication and transposition.
  • Sparse Array Optimization: Only store the positions and values of non-zero elements, reducing memory usage (e.g., in board games, scientific computing).
  • 10. Conclusion: Knowledge Map of Arrays

    Core Knowledge System of Arrays  
    ├─ Basic Concepts: Contiguous storage, same type elements, subscripts start from 0  
    ├─ Declaration and Initialization: Complete/Partial initialization, character arrays and strings  
    ├─ Pointer Essence: Array name decays to pointer, address calculation, array pointers  
    ├─ Multidimensional Arrays: Row-major storage, function parameter declaration  
    ├─ Function Passing: Arrays decay to pointers, pass length parameter  
    ├─ Character Arrays: String termination character '\0', standard library functions  
    ├─ Common Pitfalls: Out-of-bounds, uninitialized, VLA limitations  
    └─ Dynamic Arrays: Usage of malloc/realloc/free  
    

    Leave a Comment