[大师C语言(第四十一篇)]C语言指针数组与数组指针技术详解

C语言中的指针和数组是两个核心概念,它们在许多高级编程任务中扮演着重要角色。本文将深入探讨C语言中的指针数组与数组指针,包括它们的基本概念、使用场景和技术细节。我们将通过详细的解释和实用的代码案例来展示如何有效地使用这些技术。

第一部分:指针数组

1.1 指针数组的基本概念

指针数组是一个数组,其元素是指针。这意味着每个元素都存储了一个地址,该地址指向某个数据类型的一个实例。指针数组的声明方式是在数组名前加上指针运算符*和数组大小。

#include <stdio.h>int main() {int a = 1, b = 2, c = 3;int *arr[3] = {&a, &b, &c}; // 指针数组,存储整型变量的地址for (int i = 0; i < 3; i++) {printf("%d ", *arr[i]); // 输出指针数组指向的整型值}return 0;
}

在上面的代码中,我们声明了一个整型指针数组arr,它包含三个元素,每个元素都是一个指向整型变量的指针。通过解引用这些指针,我们可以访问它们所指向的整型值。

1.2 指针数组的用途

指针数组常用于以下场景:

  • 存储一组字符串的地址,便于处理和访问。
  • 在函数参数中传递多个同类型参数的地址,避免使用可变长参数列表。
  • 在排序算法中,存储元素地址以便于交换和比较。
#include <stdio.h>int main() {char *strings[] = {"apple", "banana", "cherry"}; // 指针数组,存储字符串的地址for (int i = 0; i < 3; i++) {printf("%s\n", strings[i]); // 输出指针数组指向的字符串}return 0;
}

在上面的代码中,我们声明了一个字符型指针数组strings,它存储了三个字符串的地址。通过遍历这个数组,我们可以轻松地输出这些字符串。

1.3 指针数组的指针运算

指针数组的指针运算与普通数组的指针运算类似,可以通过指针算术运算来访问数组元素。例如,可以使用arr[i]来访问指针数组的第i个元素,也可以使用arr + i来获取指向第i个元素的指针。

#include <stdio.h>int main() {int a = 1, b = 2, c = 3;int *arr[3] = {&a, &b, &c}; // 指针数组,存储整型变量的地址int **ptr = arr; // 指向指针数组的指针for (int i = 0; i < 3; i++) {printf("%d ", **(ptr + i)); // 输出指针数组指向的整型值}return 0;
}

在上面的代码中,我们声明了一个指向整型指针数组的指针ptr,并通过指针算术运算来访问数组元素所指向的整型值。

总结

在本文的第一部分中,我们介绍了C语言中指针数组的基本概念、用途和指针运算。指针数组是一个数组,其元素是指针,用于存储地址信息。通过指针数组,我们可以方便地处理和访问一组数据,如字符串或函数参数。在下一部分中,我们将探讨数组指针的概念和使用,进一步深入理解C语言中的指针和数组技术。

第二部分:数组指针

2.1 数组指针的基本概念

数组指针是一个指针,它指向一个数组。与指针数组不同,数组指针本身是一个指针,而不是一个数组。数组指针的声明方式是在指针名后加上方括号[]和数组大小。数组指针通常用于指向数组的第一个元素,并通过指针算术运算来访问数组中的其他元素。

#include <stdio.h>int main() {int arr[3] = {1, 2, 3}; // 一个整型数组int (*ptr)[3] = &arr;   // 数组指针,指向整型数组arrfor (int i = 0; i < 3; i++) {printf("%d ", (*ptr)[i]); // 通过数组指针访问数组元素}return 0;
}

在上面的代码中,我们声明了一个整型数组arr和一个数组指针ptr。数组指针ptr指向数组arr的第一个元素,我们可以通过解引用ptr来访问数组元素。

2.2 数组指针的用途

数组指针常用于以下场景:

  • 在函数参数中传递数组,特别是当数组的大小不是固定值时。
  • 访问多维数组的行或列。
  • 在指针算术运算中,用于计算数组元素的地址。
#include <stdio.h>void print_array(int (*arr)[3], int size) {for (int i = 0; i < size; i++) {for (int j = 0; j < 3; j++) {printf("%d ", (*arr)[j]); // 通过数组指针访问数组元素}printf("\n");arr++; // 移动到下一行}
}int main() {int arr[2][3] = {{1, 2, 3}, {4, 5, 6}}; // 二维整型数组print_array(arr, 2); // 传递二维数组的行指针给函数return 0;
}

在上面的代码中,我们定义了一个函数print_array,它接受一个数组指针和一个大小参数。这个函数可以用来打印任意大小的二维数组的行。在main函数中,我们传递了二维数组arr的行指针给print_array函数,并打印了数组的所有行。

2.3 数组指针的指针算术运算

数组指针的指针算术运算允许我们通过指针移动来访问数组的元素。例如,如果我们有一个指向数组的指针ptr,我们可以通过ptr + i来获取指向数组第i个元素的指针。

#include <stdio.h>int main() {int arr[3] = {1, 2, 3}; // 一个整型数组int (*ptr)[3] = &arr;   // 数组指针,指向整型数组arrfor (int i = 0; i < 3; i++) {printf("%d ", *(*ptr + i)); // 通过数组指针和指针算术运算访问数组元素}return 0;
}

在上面的代码中,我们使用了指针算术运算*ptr + i来访问数组arr的元素。这种运算方式是数组指针的一种常见用法,尤其是在处理多维数组时。

总结

在本文的第二部分中,我们介绍了C语言中数组指针的基本概念、用途和指针算术运算。数组指针是一个指针,它指向一个数组,通常用于指向数组的第一个元素,并通过指针算术运算来访问数组中的其他元素。数组指针在处理数组参数、多维数组以及指针算术运算中非常有用。在下一部分中,我们将探讨指针数组和数组指针的结合使用,以及如何在实际编程中灵活运用这些技术。

第三部分:指针数组与数组指针的结合使用

3.1 指针数组与数组指针的区分

在C语言中,指针数组和数组指针虽然都涉及到指针和数组,但它们的概念和用途是不同的。指针数组是一个数组,其元素是指针;而数组指针是一个指针,它指向一个数组。理解这两者之间的区别对于正确使用它们至关重要。

#include <stdio.h>int main() {int arr[3] = {1, 2, 3}; // 一个整型数组int *ptr[3];           // 指针数组,每个元素是一个整型指针int (*array_ptr)[3] = &arr; // 数组指针,指向一个整型数组// 初始化指针数组for (int i = 0; i < 3; i++) {ptr[i] = &arr[i];}printf("指针数组元素地址:\n");for (int i = 0; i < 3; i++) {printf("%p\n", ptr[i]);}printf("数组指针指向的数组首元素地址: %p\n", array_ptr);return 0;
}

在上面的代码中,我们定义了一个整型数组arr,一个整型指针数组ptr,以及一个整型数组指针array_ptr。指针数组ptr的每个元素都指向arr数组中的一个元素,而数组指针array_ptr指向整个arr数组。

3.2 指针数组和数组指针的结合使用

在实际编程中,指针数组和数组指针可以结合使用,以实现复杂的数据结构和算法。例如,我们可以使用指针数组来存储一组字符串,然后使用数组指针来访问这些字符串。

#include <stdio.h>int main() {char *strings[] = {"apple", "banana", "cherry"}; // 指针数组,存储字符串的地址char *(*array_ptr)[3] = &strings;               // 数组指针,指向指针数组printf("指针数组中的字符串:\n");for (int i = 0; i < 3; i++) {printf("%s\n", (*array_ptr)[i]); // 通过数组指针访问指针数组的元素}return 0;
}

在上面的代码中,我们定义了一个字符型指针数组strings,用于存储字符串的地址。然后,我们定义了一个字符型数组指针array_ptr,它指向strings数组。通过数组指针,我们可以访问指针数组中的字符串。

3.3 指针数组和数组指针在多维数组中的应用

在处理多维数组时,指针数组和数组指针尤为有用。我们可以使用指针数组来存储每一行的地址,然后使用数组指针来访问这些行。

#include <stdio.h>int main() {int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}}; // 二维整型数组int (*row_ptr)[3];                         // 数组指针,指向整型数组的行// 使用指针数组存储每一行的地址int *ptr[2];for (int i = 0; i < 2; i++) {ptr[i] = matrix[i];}printf("二维数组的内容:\n");for (int i = 0; i < 2; i++) {row_ptr = (int (*)[3])ptr[i]; // 类型转换,将整型指针转换为数组指针for (int j = 0; j < 3; j++) {printf("%d ", (*row_ptr)[j]); // 通过数组指针访问行中的元素}printf("\n");}return 0;
}

在上面的代码中,我们定义了一个二维整型数组matrix和一个整型数组指针row_ptr。我们使用指针数组ptr来存储每一行的地址,然后通过类型转换将这些地址转换为数组指针,以便访问行中的元素。

总结

在本文的第三部分中,我们探讨了指针数组和数组指针的结合使用。我们强调了指针数组和数组指针的区别,并展示了它们在存储字符串、处理多维数组等场景中的应用。通过这些例子,我们可以看到指针数组和数组指针在C语言中提供了一种强大的方式来处理和访问复杂的数据结构。正确地使用这些技术不仅可以提高代码的效率,还可以增强代码的灵活性和可维护性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/42901.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matlab 卷积和多项式乘法

目录 一、算法原理1、原理概述2、主要函数二、代码实现1、通过卷积计算多项式乘法2、向量卷积3、卷积的中心部分三、参考链接一、算法原理 1、原理概述 两个向量 u u u和 v v v的卷积,表示

大屏自适应容器组件 v-scale-screen

在vue中&#xff0c;v-scale-screen可用于大屏项目开发&#xff0c;实现屏幕自适应&#xff0c;可根据宽度自适应&#xff0c;高度自适应&#xff0c;和宽高等比例自适应&#xff0c;全屏自适应。 仓库地址&#xff1a;github国内地址&#xff1a;gitee 一、安装 npm instal…

qr 获取当前路径

qDebug() 函数在 Qt 应用程序中用于输出调试信息。这些信息通常被发送到标准输出&#xff08;stdout&#xff09;或标准错误&#xff08;stderr&#xff09;&#xff0c;具体取决于你的应用程序是如何配置的。在大多数开发环境中&#xff0c;你可以通过以下方式查看 qDebug() 输…

React setState

老生常谈之setState 是同步的还是异步的&#xff1f; 设想setState是同步的&#xff0c;那也就是每次调用setState都要进行新旧虚拟DOM的对比&#xff0c;然后将差异化的dom更新到页面上&#xff0c;性能损耗很大 所以react把setState设置为了异步&#xff0c;当状态更新时不…

【Unity2D 2022:Audio】添加游戏音乐和音效

一、添加背景音乐 1. 创建空的游戏物体&#xff0c;名为BackgroundMusic 2. 为音频播放器添加音频源&#xff08;Audio Source&#xff09;组件 3. 将背景音乐音频赋值到AudioClip&#xff08;红色&#xff09; 4. 设置循环播放&#xff08;蓝色&#xff09; 二、添加草莓拾取…

springboot封装请求参数json的源码解析

源码位置&#xff1a; org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver#readWithMessageConverters(org.springframework.http.HttpInputMessage, org.springframework.core.MethodParameter, java.lang.reflect.Type…

解答 | http和https的区别,谁更好用

TTP&#xff08;超文本传输协议&#xff09;和HTTPS&#xff08;安全超文本传输协议&#xff09;的主要区别在于安全性和数据传输的方式。 一、区别 1、协议安全性&#xff1a; HTTP&#xff1a;使用明文形式传输数据&#xff0c;不提供数据加密功能&#xff0c;数据在传输过…

coze搭建工作流和Agent

coze搭建工作流和Agent Agent LLM 记忆感知规划使用工具 LLM是大语言模型&#xff0c;prompt提示词影响LLM的输出质量 描述需求——>背景——>解决思路&#xff0c;提示词文档。 当有明确的需求和实现需求的路径时&#xff0c;可以通过搭建工作流来完成标准化任务为…

函数声明与函数表达式的区别?

一、区别如下: 函数声明的方法定义的函数,函数名是必须的,函数表达式的函数名是可选的。函数声明的方法定义的函数,函数可以在函数声明之前调用,函数表达式的函数只能在声明之后调用。 函数声明的方法定义的函数并不是真正的声明,它们仅仅可以出现在全局中,或者嵌套在其他的函数…

Python爬虫原理以及3个小案例(源码)

一、爬虫原理 网络爬虫是一种用于自动获取网页内容的程序。它模拟用户浏览网页的过程&#xff0c;通过发送HTTP请求获取网页的源代码&#xff0c;并利用解析和提取技术来获取所需的数据。 1. HTTP请求与响应过程 爬虫向目标网站发送HTTP请求&#xff0c;请求包含URL、请求方…

Linux内核 -- DMA控制器之dmaengine框架的注册与使用流程

Linux Kernel dmaengine 框架 简介 Linux内核的dmaengine框架是一个用于管理DMA&#xff08;Direct Memory Access&#xff09;操作的通用框架。它抽象了不同DMA控制器的实现&#xff0c;使得上层代码可以方便地进行DMA传输。 初始化流程 1. 驱动注册 每个DMA控制器驱动都…

定义变量和声明变量、定义类和声明类

一、定义变量和声明变量 在编程中&#xff0c;定义变量和声明变量是两个相关但不同的概念&#xff0c;尤其是在静态类型的编程语言中。静态类型的编程语言比如Java 1、声明变量 &#xff08;1&#xff09;定义&#xff1a;声明变量是指告诉编译器变量的名字、类型和在某些情…

Mysql:时区问题

Mysql&#xff1a;时区问题 1、时区配置 Mysql默认使用系统的时区 mysql> show global variables like %time%zone%; -------------------------- | Variable_name | Value | -------------------------- | system_time_zone | | | time_zone | SYSTEM…

Multi-Wing Optimiser风扇选型软件介绍

Multi-Wing Optimiser风扇选型软件

一、YOLO V10安装、使用、训练大全

YOLO V10安装、使用、训练大全 一、下载官方源码二、配置conda环境三、安装YOLOV10依赖四、使用官方YOLO V10模型1.下载模型2.使用模型2.1 图片案例 五、制作数据集1.数据集目录结构2.标注工具2.1 安装标注工具2.2 运行标注工具2.3 设置自动保存2.4 切换yolo模式2.5 开始标注2.…

Socket.D 开源网络应用协议,v2.5.9 发布(已有 java, py, js SDK)

Socket.D 协议&#xff1f; Socket.D 是一个基于事件和语义消息流的网络应用协议。在微服务、移动应用、物联网等场景&#xff0c;可替代 http、websocket 等。协议详情参考《官网介绍》。 支持&#xff1a; tcp, udp, ws, kcp 传输。 目前&#xff1a;java&#xff0c;kotli…

Python不使用元类的ORM实现

不使用元类的简单ORM实现 在 Python 中&#xff0c;ORM&#xff08;Object-Relational Mapping&#xff09;是一种将对象和数据库之间的映射关系进行转换的技术&#xff0c;使得通过面向对象的方式来操作数据库更加方便。通常&#xff0c;我们使用元类&#xff08;metaclass&a…

关于go和rust语言的对比

文章目录 前言Rust 的优势&#xff1a;Go 的优势&#xff1a;总结 前言 Go 和 Rust 是两种现代的系统级编程语言&#xff0c;它们各自拥有独特的特性和应用场景。以下是它们的一些主要区别&#xff1a; Rust 的优势&#xff1a; 内存安全&#xff1a;Rust 引入了所有权和借用…

香橙派5plus上跑云手机方案二 waydroid

前言 上篇文章香橙派5plus上跑云手机方案一 redroid(带硬件加速)说了怎么跑带GPU加速的redroid方案&#xff0c;这篇说下怎么在香橙派下使用Waydroid。 温馨提示 虽然能运行&#xff0c;但是体验下来只能用软件加速&#xff0c;无法使用GPU加速&#xff0c;所有会很卡。而且…

Pat乙级题解

文章目录 1~2021 ~ 4041~6061~8081~100101~125 1~20 1001 害死人不偿命的(3n1)猜想 B1002 写出这个数 (20 分) B1003 我要通过&#xff01; B1004 成绩排名 1005 继续(3n1)猜想 B1006 换个格式输出整数 B1007 素数对猜想 1008 数组元素循环右移问题 B1009 说反话 1010 一元多项…