[C高手编程] 数组与指针:多维数组、动态数组、指针运算与字符串

在这里插入图片描述

💖💖⚡️⚡️专栏:C高手编程-面试宝典/技术手册/高手进阶⚡️⚡️💖💖
「C高手编程」专栏融合了作者十多年的C语言开发经验,汇集了从基础到进阶的关键知识点,是不可多得的知识宝典。如果你是即将毕业的学生,面临C语言的求职面试,本专栏将帮助你扎实地掌握核心概念,轻松应对笔试与面试;如果你已有两三年的工作经验,专栏中的内容将补充你在实践中可能忽略的新技术和技巧;而对于资深的C语言程序员,这里也将是一本实用的技术备查手册,提供全面的知识回顾与更新。无论处在哪个阶段,「C高手编程」都能助你一臂之力,成为C语言领域的行家里手。

概述

本章深入探讨C语言中的数组与指针技术,包括多维数组的使用、动态数组的创建与管理、指针与数组的关系、指针运算、多级指针以及指针与字符串的交互。这些概念对于理解和编写高效安全的C语言程序至关重要。通过本章的学习,读者将能够理解这些概念的工作原理,并能在实际编程中正确地运用它们。

1. 多维数组

1.1 定义与声明

  • 定义:多维数组是一种由多个一维数组组成的数组。
  • 详细说明:多维数组通常用于表示具有多个维度的数据结构,例如表格、矩阵或图像。在C语言中,可以使用嵌套的一维数组来创建多维数组。例如,一个3x4的整数矩阵可以表示为int matrix[3][4];

1.2 初始化

  • 定义:可以使用花括号{}初始化多维数组。
  • 示例代码:
    int matrix[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    
  • 详细说明:每个花括号内的数字代表一行。通过这种方式,可以为多维数组的每个元素赋初值。当数组被初始化时,如果某些元素没有被显式赋值,则默认会被赋值为0。

1.3 访问元素

  • 定义:使用下标访问多维数组中的元素。
  • 示例代码:
    int x = matrix[1][2]; // x will be 7
    
  • 详细说明matrix[1][2]表示第二行第三列的元素。在C语言中,索引是从0开始的,因此matrix[1][2]指的是第二行(即索引为1)的第三个元素(即索引为2)。

1.4 动态分配

  • 定义:可以在运行时动态分配多维数组。
  • 示例代码:
    int **matrix;
    matrix = (int **)malloc(3 * sizeof(int *));
    for (int i = 0; i < 3; i++) {
        matrix[i] = (int *)malloc(4 * sizeof(int));
    }
    
  • 详细说明:使用malloc动态分配多维数组的空间。需要注意的是,多维数组的动态分配通常涉及多层malloc调用,因为每一维都需要单独分配空间。使用完毕后,必须通过free函数释放每一维所分配的内存。

1.5 示例代码

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

int main() {
    int matrix[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };

    // Accessing elements
    int x = matrix[1][2];
    printf("Element at row 2, column 3: %d\n", x);

    // Printing the matrix
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }

    return 0;
}
  • 详细说明:该示例展示了如何访问多维数组中的特定元素,并打印整个矩阵。通过循环,我们可以遍历整个多维数组并打印出每个元素的值。

在这里插入图片描述

2. 动态数组

2.1 定义与创建

  • 定义:动态数组是在运行时分配空间的数组。
  • 详细说明:动态数组允许程序员在运行时确定数组的大小,这对于不确定数组大小的情况非常有用。动态数组的创建和管理通常涉及到mallocrealloc函数的使用。

2.2 创建与初始化

  • 定义:使用malloc函数动态分配空间。
  • 示例代码:
    int *arr;
    arr = (int *)malloc(5 * sizeof(int));
    
  • 详细说明:使用malloc函数动态分配空间。在分配内存之前,需要先声明一个指针变量arr,然后使用malloc函数为数组分配足够的空间。这里,我们分配了5个整数的内存空间。

2.3 访问元素

  • 定义:使用下标访问动态数组中的元素。
  • 示例代码:
    arr[2] = 10;
    
  • 详细说明arr[2]表示第三个元素。动态数组的访问方式与静态数组相同。

2.4 重新分配

  • 定义:可以使用realloc函数重新分配动态数组的空间。
  • 示例代码:
    arr = (int *)realloc(arr, 10 * sizeof(int));
    
  • 详细说明:使用realloc函数扩展数组的大小。realloc函数可以扩展或缩小已分配的内存块的大小。如果需要扩展数组,但realloc失败,则应检查返回值是否为NULL,并在必要时释放旧的内存块。

2.5 示例代码

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

int main() {
    int *arr;
    arr = (int *)malloc(5 * sizeof(int));

    // Initialize array
    for (int i = 0; i < 5; i++) {
        arr[i] = i + 1;
    }

    // Print the array
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    // Reallocate the array
    arr = (int *)realloc(arr, 10 * sizeof(int));

    // Check if realloc succeeded
    if (arr == NULL) {
        fprintf(stderr, "Failed to reallocate memory.\n");
        exit(EXIT_FAILURE);
    }

    // Extend the array
    for (int i = 5; i < 10; i++) {
        arr[i] = i + 1;
    }

    // Print the extended array
    for (int i = 0; i < 10; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    free(arr);

    return 0;
}
  • 详细说明:此示例展示了如何使用mallocrealloc来创建和扩展动态数组,并确保在realloc失败时正确处理错误。通过realloc函数,我们可以扩展动态数组的大小,从而容纳更多元素。

在这里插入图片描述

3. 指针与数组的关系

3.1 定义与访问

  • 定义:数组名实际上是一个指向数组第一个元素的指针。
  • 详细说明:在C语言中,数组名可以被视为指向数组第一个元素的常量指针。这意味着可以通过数组名来访问数组中的元素。

3.2 访问元素

  • 定义:可以通过指针访问数组中的元素。
  • 示例代码:
    int arr[5] = {1, 2, 3, 4, 5};
    int *p = arr;
    
  • 详细说明p指向数组arr的第一个元素。数组名arr可以被看作是指向数组第一个元素的指针,这使得可以通过指针访问数组中的元素。

3.3 指针算术

  • 定义:可以使用指针算术来访问数组中的元素。
  • 示例代码:
    int x = *(p + 2); // Equivalent to p[2]
    
  • 详细说明*(p + 2)表示数组中的第三个元素。指针算术允许通过增加或减少指针来访问数组中的不同元素。通过这种方法,可以有效地遍历数组中的所有元素。

3.4 示例代码

#include <stdio.h>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int *p = arr;

    // Accessing elements using pointer arithmetic
    for (int i = 0; i < 5; i++) {
        printf("%d ", *(p + i));
    }
    printf("\n");

    // Modifying elements
    *(p + 2) = 10;
    printf("Modified array: ");
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}
  • 详细说明:该示例展示了如何通过指针访问和修改数组中的元素。通过指针算术,我们可以遍历数组中的每个元素并进行必要的操作。

在这里插入图片描述

4. 指针运算

4.1 定义与算术

  • 定义:指针算术允许对指针进行算术操作。
  • 详细说明:指针算术是C语言中非常强大的工具,它允许程序员通过增加或减少指针来访问数组中的不同元素。指针算术对于遍历数组、执行数组中的操作以及其他基于指针的操作都非常有用。

4.2 指针加减

  • 定义:可以使用加法和减法来移动指针。
  • 示例代码:
    int *p = arr;
    p += 2; // Move to the third element
    p -= 1; // Move back to the second element
    
  • 详细说明p += 2将指针移动到第三个元素。p -= 1将指针移动回第二个元素。指针加减操作可以用来快速移动到数组中的特定位置。

4.3 指针比较

  • 定义:可以比较指针的相对位置。
  • 示例代码:
    int *p = arr;
    int *q = arr + 4;
    if (p < q) {
        printf("p is before q\n");
    }
    
  • 详细说明p < q判断p是否在q之前。指针比较可以用来确定指针的相对位置,这对于数组遍历和排序算法非常有用。

4.4 示例代码

#include <stdio.h>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int *p = arr;

    // Pointer arithmetic
    p += 2;
    printf("Third element: %d\n", *p);

    // Pointer comparison
    int *q = arr + 4;
    if (p < q) {
        printf("p is before q\n");
    }

    return 0;
}
  • 详细说明:该示例展示了如何使用指针算术访问数组中的特定元素,并比较两个指针的相对位置。通过指针算术,我们可以轻松地移动到数组中的特定位置,并通过指针比较确定两个指针之间的相对位置。

在这里插入图片描述

5. 多级指针

5.1 定义与使用

  • 定义:多级指针是指向指针的指针。
  • 详细说明:多级指针通常用于实现复杂的数据结构或传递指针的指针给函数。在多级指针中,指针可以指向另一层指针,这样就可以间接访问数据。

5.2 使用

  • 定义:可以使用多级指针来间接访问数据。
  • 示例代码:
    int x = 10;
    int *p = &x;
    int **pp = &p;
    printf("Value of x: %d\n", **pp);
    
  • 详细说明**pp表示x的值。通过多级指针可以间接访问变量的值,这对于某些情况下的数据处理非常有用。

5.3 示例代码

#include <stdio.h>

int main() {
    int x = 10;
    int *p = &x;
    int **pp = &p;

    printf("Value of x: %d\n", **pp);
    printf("Address of p: %p\n", pp);
    printf("Value of p: %p\n", *pp);
    printf("Address of x: %p\n", p);

    return 0;
}
  • 详细说明:该示例展示了如何使用多级指针来间接访问变量的值。通过多级指针,我们可以访问到变量x的值,同时还可以访问到指针p的地址以及p指向的值。

在这里插入图片描述

6. 指针与字符串

6.1 定义与表示

  • 定义:字符串是一组以空字符\0结尾的字符。
  • 详细说明:字符串可以使用字符数组来表示,通常以空字符\0结尾。在C语言中,字符串可以被视为指向字符串第一个字符的指针。

6.2 字符串指针

  • 定义:可以使用指针来访问字符串中的字符。
  • 示例代码:
    char str[] = "Hello, World!";
    char *p = str;
    
  • 详细说明*p表示字符串中的第一个字符。字符串指针可以用来遍历字符串中的每一个字符。通过指针,我们可以访问字符串中的每个字符,并对其进行操作。

6.3 字符串操作

  • 定义:可以使用字符串函数来操作字符串。
  • 示例代码:
    char str1[] = "Hello";
    char str2[] = "World!";
    strcat(str1, str2);
    
  • 详细说明strcat函数将str2追加到str1的末尾。字符串函数如strcatstrcpystrlen等可以用来操作字符串。这些函数提供了一系列功能,如复制、拼接、获取长度等。

6.4 字符串比较

  • 定义:使用strcmp函数比较两个字符串。
  • 示例代码:
    char str1[] = "Hello";
    char str2[] = "hello";
    int result = strcmp(str1, str2); // result will be non-zero
    
  • 详细说明strcmp函数按字典序比较两个字符串,如果两个字符串相等则返回0,如果不相等则返回非零值。strcmp函数逐字符比较两个字符串,直到遇到结束标志\0或发现不同字符为止。

6.5 示例代码

#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Hello, World!";
    char *p = str;

    // Accessing characters
    printf("First character: %c\n", *p);

    // String concatenation
    char str1[] = "Hello";
    char str2[] = " World!";
    strcat(str1, str2);

    // String comparison
    char str3[] = "Hello World!";
    int result = strcmp(str1, str3);
    if (result == 0) {
        printf("Strings are equal\n");
    } else {
        printf("Strings are not equal\n");
    }

    return 0;
}
  • 详细说明:该示例展示了如何使用字符串指针访问字符串中的字符,以及如何使用字符串函数操作字符串。通过字符串指针,我们可以访问字符串中的每个字符,并使用字符串函数执行各种操作。

总结

通过本章的学习,我们深入了解了C语言中的数组与指针技术,包括多维数组、动态数组、指针与数组的关系、指针运算、多级指针以及指针与字符串的交互。我们不仅探讨了这些概念的基本概念、使用方法以及注意事项,而且还提供了详细的示例代码来帮助读者更好地理解每个概念。此外,我们还讨论了如何避免常见的陷阱和危险操作,确保代码的安全性和效率。

  • 多维数组:多维数组的定义、访问、初始化和动态分配。

    • 多维数组可以使用嵌套的一维数组来创建。
    • 可以通过指定数组大小来初始化多维数组。
    • 可以使用下标访问多维数组中的元素。
    • 多维数组也可以动态分配。
  • 动态数组:动态数组的创建、访问、重新分配。

    • 动态数组允许在运行时确定数组的大小。
    • 可以使用malloc函数来创建动态数组。
    • 可以使用realloc函数来扩展动态数组的大小。
    • 在使用完毕后,必须通过free函数释放动态分配的内存。
  • 指针与数组的关系:指针与数组之间的关系以及如何通过指针访问数组元素。

    • 数组名实际上是一个指向数组第一个元素的指针。
    • 可以通过指针访问数组中的元素。
    • 指针算术可以用来遍历数组中的元素。
  • 指针运算:指针算术的操作和比较。

    • 指针算术允许对指针进行加减操作。
    • 可以比较指针的相对位置。
    • 指针算术对于数组遍历和其他基于指针的操作非常有用。
  • 多级指针:多级指针的概念和使用。

    • 多级指针可以用来间接访问数据。
    • 通过多级指针可以访问到变量的值。
  • 指针与字符串:字符串指针的使用以及字符串函数的应用。

    • 字符串可以视为指向字符串第一个字符的指针。
    • 可以使用字符串指针遍历字符串中的每个字符。
    • 字符串函数如strcatstrcpystrlen等可以用来操作字符串。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值