欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > 深入理解指针(2)(C语言版)

深入理解指针(2)(C语言版)

2025/4/8 1:04:47 来源:https://blog.csdn.net/cui211472325/article/details/146507914  浏览:    关键词:深入理解指针(2)(C语言版)

文章目录

    • 前言
    • 一、数组名的理解
    • 二、使用指针访问数组
    • 三、一维数组传参的本质
    • 四、冒泡排序
    • 五、二级指针
    • 六、指针数组
    • 七、指针数组模拟二维数组
    • 总结

前言

在上一篇文章中,我们初步了解了指针的基本概念和用法。今天,我们将继续深入探索指针在数组、函数传参以及复杂数据结构中的应用,帮助大家更全面地掌握指针的精髓。
在这里插入图片描述

一、数组名的理解

数组名在 C 语言中是一个非常特殊的概念。它本质上是一个指向数组首元素的指针。例如,对于数组 int arr[5];arr 就是数组名,它指向数组的第一个元素 arr[0]。我们可以通过打印 arr&arr[0] 的值来验证这一点,它们的值是相同的。

#include <stdio.h>int main() {int arr[5] = {1, 2, 3, 4, 5};printf("arr的地址:\t\t%p\n", arr);printf("数组首元素的地址:\t%p\n", &arr[0]);return 0;
}

数组名的理解

运行结果会显示两个地址相同,这证明了数组名就是一个指向首元素的指针。

数组名作为一个指针,它具有一些特殊的性质。首先,数组名的值是常量,不能被修改。也就是说,我们不能对数组名进行赋值操作,如 arr = &arr[1]; 是非法的。其次,数组名的类型是指向数组中元素类型的指针。例如,对于 int arr[5];arr 的类型是 int*,即指向整型的指针。

二、使用指针访问数组

既然数组名是首元素的地址,我们就可以通过指针来访问数组中的元素。例如,*(arr + i) 就相当于 arr[i],表示数组中第 i 个元素的值。

#include <stdio.h>int main() {int arr[5] = {1, 2, 3, 4, 5};for (int i = 0; i < 5; i++) {printf("arr[%d] = %d\n", i, *(arr + i));}return 0;
}

在这里插入图片描述

这段代码通过指针的方式遍历了数组中的每个元素,输出结果与直接使用数组下标访问相同。

指针访问数组元素的原理是基于指针的偏移。指针本身存储的是一个内存地址,当我们对指针进行加法运算时,实际上是根据指针所指向的数据类型计算偏移量。例如,对于 int* ptr;ptr + 1 的值是 ptr 的值加上 sizeof(int),即指针指向下一个整数元素的地址。

三、一维数组传参的本质

当我们将一维数组作为参数传递给函数时,实际上传递的是数组的首地址。也就是说,函数内部接收到的并不是整个数组,而是一个指向数组首元素的指针。因此,在函数内部,我们可以通过指针来操作数组中的元素。

#include <stdio.h>void printArray(int arr[], int size) {for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}printf("\n");
}int main() {int arr[5] = {1, 2, 3, 4, 5};printArray(arr, 5);return 0;
}

在这里插入图片描述

在这个例子中,printArray 函数接收一个指针和数组大小作为参数,然后通过指针访问数组中的元素并打印出来。

需要注意的是,当数组作为函数参数传递时,数组的大小信息会丢失。因此,我们需要额外传递一个参数来指定数组的大小,以便在函数内部正确地操作数组。

四、冒泡排序

冒泡排序是一种简单的排序算法,它通过比较相邻元素的大小并交换位置来实现排序。在实现冒泡排序时,我们通常会使用指针来操作数组元素。

#include <stdio.h>void bubbleSort(int arr[], int size) {for (int i = 0; i < size - 1; i++) {for (int j = 0; j < size - 1 - i; j++) {if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}int main() {int arr[5] = {5, 3, 8, 1, 2};bubbleSort(arr, 5);printf("排序后的数组:");for (int i = 0; i < 5; i++) {printf("%d ", arr[i]);}return 0;
}

冒泡排序

这段代码实现了冒泡排序算法,通过指针操作数组元素,将数组从小到大排序。

冒泡排序的时间复杂度为 O(n²),其中 n 是数组的大小。虽然它的效率不高,但对于小规模的数据集或者学习排序算法的基本原理来说,冒泡排序是一个很好的起点。

五、二级指针

二级指针是指指向指针的指针。它在处理指针数组或者动态分配的二维数组时非常有用。例如,我们可以通过二级指针来操作一个字符串数组。

#include <stdio.h>int main() {char *strArray[] = {"Hello", "World", "C", "Language"};char **ptr = strArray;for (int i = 0; i < 4; i++) {printf("%s\n", *(ptr + i));}return 0;
}

二级指针

在这个例子中,strArray 是一个指针数组,ptr 是一个二级指针,指向 strArray 的首元素。通过 ptr 我们可以访问数组中的每个字符串。

二级指针的使用需要注意指针的初始化和解引用操作。在使用二级指针之前,必须确保它指向一个有效的内存地址,并且在解引用时要逐步进行,先获取一级指针,再访问最终的数据。

六、指针数组

指针数组是一个数组,其元素都是指针类型。常见的应用场景是存储多个字符串的首地址,方便对字符串进行操作。

#include <stdio.h>int main() {char *strArray[] = {"Apple", "Banana", "Cherry", "Date"};for (int i = 0; i < 4; i++) {printf("%s\n", strArray[i]);}return 0;
}

在这里插入图片描述

这里定义了一个指针数组 strArray,每个元素都是一个指向字符的指针,存储了不同水果名称的首地址。

指针数组的优势在于可以方便地对一组指针进行统一管理。例如,我们可以对指针数组中的字符串进行排序、查找等操作。

七、指针数组模拟二维数组

利用指针数组,我们可以模拟二维数组的操作。通过动态分配内存,我们可以根据需要创建不同大小的“二维数组”。

#include <stdio.h>
#include <stdlib.h>int main() {int rows = 3, cols = 4;int **array = (int **)malloc(rows * sizeof(int *));for (int i = 0; i < rows; i++) {array[i] = (int *)malloc(cols * sizeof(int));}// 初始化数组for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {array[i][j] = i * cols + j + 1;}}// 打印数组for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {printf("%d ", array[i][j]);}printf("\n");}// 释放内存for (int i = 0; i < rows; i++) {free(array[i]);}free(array);return 0;
}

在这里插入图片描述

这段代码通过指针数组模拟了一个 3 行 4 列的二维数组,实现了动态内存分配、初始化、打印和释放内存的操作。

在动态分配内存时,我们需要先为指针数组本身分配内存,然后再为每个指针元素分配相应的内存。这样可以灵活地控制每一行的大小,甚至可以创建不规则的二维数组。

总结

通过本文的学习,我们深入理解了指针在数组、函数传参以及复杂数据结构中的应用。从数组名作为指针的概念,到使用指针访问数组元素,再到一维数组传参的本质,我们逐步掌握了指针在数组操作中的核心技巧。同时,我们还学习了冒泡排序算法的实现,以及二级指针、指针数组和指针数组模拟二维数组的用法。这些知识将为我们进一步学习 C 语言中的高级指针应用打下坚实的基础。在实际编程中,灵活运用指针可以让我们更高效地操作数据,实现复杂的功能。希望同学们能够多加练习,通过实际编写代码来加深对指针的理解和掌握。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词