【C语言指针进阶讲解】第二章:指针数组和数组指针

时间:2024-10-02 11:59:46

第二章:指针数组和数组指针

1. 指针数组

定义与声明

指针数组是一个包含指针的数组,每个元素都是一个指针。例如,可以创建一个指向字符串的指针数组。

#include <stdio.h>

const char* strArray[] = {"Hello", "World", "C Language"};

上面的代码定义了一个包含三个指针的数组,每个指针分别指向一个字符串常量。

示例代码:使用指针数组存储字符串数组

#include <stdio.h>

int main() {
    // 定义一个包含字符串指针的数组
    const char* strArray[] = {"Hello", "World", "C Language"};

    // 遍历该指针数组并打印每个字符串
    for (int i = 0; i < 3; i++) {
        printf("%s\n", strArray[i]);
    }

    return 0;
}

实际应用场景

指针数组在处理字符串数组、动态创建多维数组和处理复杂数据结构时非常有用。例如,在命令行参数解析、数据库记录处理等场景中,指针数组能够提供高效灵活的解决方案。


2. 指向数组的指针

定义与声明

指向数组的指针是一个指针,指向一个数组的第一个元素。例如,一个指向整数数组的指针可以这样定义:

int (*arrayPtr)[10];

这里,arrayPtr 是一个指向包含10个整数的数组的指针。

二维数组与指向二维数组的指针

二维数组是数组的数组,即数组的每个元素本身又是一个数组。指向二维数组的指针可以表示为一个指向指针的指针。

int array[3][4];
int (*ptr)[4];

ptr 是一个指向包含4个整数数组的指针,它可以指向 array 的每一行。

示例代码:二维数组的动态内存分配

动态分配二维数组时,可以使用指针来管理内存。

#include <stdio.h>
#include <stdlib.h>

int main() {
    int rows = 3;
    int cols = 4;

    // 动态分配指向指针的数组(用于存储每一行的指针) [1]
    int **array = (int **)malloc(rows * sizeof(int *)); 
    if (array == NULL) {
        perror("Malloc failed");
        return EXIT_FAILURE;
    }

    for (int i = 0; i < rows; i++) {
        array[i] = (int *)malloc(cols * sizeof(int)); // 动态分配每一行的内存 [2]
        if (array[i] == NULL) {
            perror("Malloc failed");
            return EXIT_FAILURE;
        }
    }

    // 初始化数组并打印其内容
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            array[i][j] = i * cols + j;  // 初始化
            printf("%d ", array[i][j]);  // 打印每个元素
        }
        printf("\n");
    }

    // 释放分配的内存
    for (int i = 0; i < rows; i++) {
        free(array[i]);
    }
    free(array);

    return 0;
}
  1. 动态分配指向指针的数组(用于存储每一行的指针)

    • int **array:这一部分声明了一个指向int指针的指针。这个指针(array)将用于指向一个指针数组,每个指针将指向一个整数数组的第一行。最终,它将表示一个2D数组。
    • malloc(rows * sizeof(int *)):这部分代码使用了malloc函数来动态分配内存。
    • rows * sizeof(int *):这计算了要分配的总内存字节数。 sizeof(int *) 是指针的大小(通常在32位系统上是4字节,在64位系统上是8字节),rows 表示行数。因此,这行代码为rowsint * 类型的指针分配内存。
    • (int **):[强制类型转换] malloc 返回的是 void * 类型的指针。为了与声明的 int ** 类型匹配,需要进行强制类型转换。这样避免编译器发出警告并增加代码可读性。
    • 总结:这行代码的作用是为一个指针数组分配内存,每个指针将用于指向二维数组的一行。
  2. 动态分配每一行的内存

    • array[i]:这一部分获取了指向二维数组第i行的指针。array 是一个指针数组,每个元素(比如 array[i])是一个 int * 类型的指针,它将指向数组的一行。
    • malloc(cols * sizeof(int)):这部分代码再次使用 malloc 来分配内存。
      • cols * sizeof(int):这里计算了要分配的字节数。sizeof(int) 返回一个整数的大小,cols 是二维数组的列数。因此,这行代码为一行中的所有 cols 个整数分配内存空间。
    • (int *):[强制类型转换] malloc 返回 void *,需要将其转换为 int * 类型,以匹配指针数组元素的类型。
    • 总结:- array[i] 是一个指向 int 类型数组的指针,malloc 函数为每个数组分配足够的内存以存储 cols 个整数。这些数组即二维数组的各行。

在上面的代码中,通过 malloc 动态分配二维数组的内存,并演示了如何初始化和访问该数组的数据。最后,通过调用 free 释放分配的内存,以防止内存泄漏。