程序诗篇里的灵动笔触:指针绘就数据的梦幻蓝图<8>

在这里插入图片描述

大家好啊,我是小象٩(๑òωó๑)۶
我的博客:Xiao Xiangζั͡ޓއއ

很高兴见到大家,希望能够和大家一起交流学习,共同进步
在这里插入图片描述
今天我们复习前面学习的指针知识

目录

  • 关于指针数组和数组指针的区别
    • 指针数组(Array of Pointers)
    • 1 指针数组的定义
    • 指针数组模拟二维数组
  • 数组指针(Pointer to Array)
    • 数组指针变量是什么?
    • 数组指针变量怎么初始化
    • 二维数组传参的本质
  • 字符指针变量,数组指针变量,函数指针变量的区别
    • 字符指针变量
    • 数组指针变量
    • 函数指针变量
  • 结尾

关于指针数组和数组指针的区别

指针数组(Array of Pointers)

定义:一个数组,每个元素都是指针。
声明:int arr[size];
方括号[]优先级高,arr是数组,元素为int
类型

C语言中的指针数组是一种特殊的数组,其元素都是指针类型。每个元素可以指向不同类型或相同类型的数据,常用于管理多个地址(如字符串数组、动态内存分配等)。

指针数组是指针还是数组?
我们类比一下,整型数组,是存放整型的数组,字符数组是存放字符的数组。
那指针数组呢?是存放指针的数组。

1 指针数组的定义

语法:数据类型 *数组名[数组长度];

特点:数组的每个元素都是一个指针,需单独初始化后才能使用。

示例:

int *ptr_arr[5];  // 定义一个包含5个整型指针的数组
char *str_arr[3]; // 定义一个包含3个字符指针的数组

指针数组的每个元素是地址,又可以指向一块区域。

指针数组模拟二维数组

#include <stdio.h>
int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 2,3,4,5,6 };int arr3[] = { 3,4,5,6,7 };//数组名是数组⾸元素的地址,类型是int*的,就可以存放在parr数组中int* parr[3] = { arr1, arr2, arr3 };int i = 0;int j = 0;for (i = 0; i < 3; i++){for (j = 0; j < 5; j++){printf("%d ", parr[i][j]);}printf("\n");}return 0;
}

代码分析
数组定义:定义了三个一维整型数组 arr1、arr2 和 arr3,每个数组都包含 5 个整数元素。
指针数组定义与初始化:定义了一个指针数组 parr,它包含 3 个元素,每个元素都是 int* 类型的指针。将 arr1、arr2 和 arr3 的首地址分别赋值给 parr 的三个元素。
嵌套循环遍历:使用嵌套的 for 循环来遍历 parr 指针数组中的每个元素,并访问它们所指向的数组中的每个元素。外层循环控制访问哪个数组,内层循环控制访问数组中的每个元素。 输出结果:使用printf 函数将每个元素打印出来,并在每行结束时换行。

parr[i]是访问parr数组的元素,parr[i]找到的数组元素指向了整型一维数组,parr[i][j]就是整型一维数组中的元素。
上述的代码模拟出二维数组的效果,实际上并非完全是二维数组,因为每一行并非是连续的。

数组指针(Pointer to Array)

定义:一个指针,指向整个数组。
声明:int (*ptr)[size];
括号()让ptr先被解释为指针,指向int[size]类型的数组。

数组指针变量是什么?

在C语言中,数组指针变量(也叫指向数组的指针)是一种特殊的指针变量,它指向的是一个数组。
之前我们学习了指针数组,指针数组是⼀种数组,数组中存放的是地址(指针)。
数组指针变量是指针变量?还是数组?
答案是:指针变量。
我们已经熟悉:
• 整形指针变量: int * pint; 存放的是整形变量的地址,能够指向整形数据的指针。
• 浮点型指针变量: float * pf; 存放浮点型变量的地址,能够指向浮点型数据的指针。
那数组指针变量应该是:存放的应该是数组的地址,能够指向数组的指针变量。
形式:

int (*p)[5];

这里定义了一个名为p的指针变量,它指向一个包含5个int类型元素的数组。注意,(p)两边的括号不能省略,因为[]的优先级高于,如果没有括号int *p[5]; 这定义的是一个指针数组(一个包含5个int指针的数组),而不是指向数组的指针。

解释:p先和结合,说明p是⼀个指针变量,然后指针指向的是⼀个大小为5个整型的数组。所以p是
⼀个指针,指向⼀个数组,叫 数组指针。
这⾥要注意:[]的优先级要⾼于
号的,所以必须加上()来保证p先和*结合。

数组指针变量怎么初始化

数组指针变量是用来存放数组地址的,那怎么获得数组的地址呢?就是我们之前学习的 &数组名 。

int arr[10] = {0};
&arr;//得到的就是数组的地址

如果要存放个数组的地址,就得存放在数组指针变量中,如下:

int(*p)[10] = &arr;

我们调试也能看到 &arr 和 p 的类型是完全⼀致的。
数组指针类型解析:

int (*p) [10] = &arr;| | || | || | p指向数组的元素个数| p是数组指针变量名p指向的数组的元素类型

二维数组传参的本质

二维数组传参的本质是传递指向一维数组的指针,函数通过这个指针和已知的列数信息,按照连续内存存储的方式来访问和处理二维数组中的元素

有了数组指针的理解,我们就能够讲⼀下二维数组传参的本质了。
过去我们有⼀个二维数组的需要传参给⼀个函数的时候,我们是这样写的:

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

这⾥实参是⼆维数组,形参也写成⼆维数组的形式,那还有什么其他的写法吗?
⾸先我们再次理解⼀下⼆维数组,⼆维数组其实可以看做是每个元素是⼀维数组的数组,也就是⼆维数组的每个元素是⼀个⼀维数组。那么⼆维数组的⾸元素就是第⼀⾏,是个⼀维数组。
所以,根据数组名是数组⾸元素的地址这个规则,⼆维数组的数组名表⽰的就是第⼀⾏的地址,是⼀维数组的地址。根据上⾯的例⼦,第⼀⾏的⼀维数组的类型就是 int [5] ,所以第⼀⾏的地址的类型就是数组指针类型 int(*)[5] 。那就意味着⼆维数组传参本质上也是传递了地址,传递的是第⼀⾏这个⼀维数组的地址,那么形参也是可以写成指针形式的。如下:

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

总结:⼆维数组传参,形参的部分可以写成数组,也可以写成指针形式。

在这里插入图片描述

字符指针变量,数组指针变量,函数指针变量的区别

字符指针变量

本质上是一个指针,该指针专门用于指向字符类型的数据。在 C 语言里,由于字符串以字符数组形式存在且以空字符 ‘\0’ 结尾,字符指针常被用于指向字符串常量或者字符数组。
例如:

#include <stdio.h>int main() {// 指向字符串常量char *str = "Hello"; // 指向字符数组char arr[] = "World";char *ptr = arr; return 0;
}

数组指针变量

同样是指针,但它指向的是一个数组。也就是说,此指针保存的是整个数组的起始地址,而非数组首元素的地址。
例如:

#include <stdio.h>int main() {int arr[3] = {1, 2, 3};// 数组指针指向数组 arrint (*p)[3] = &arr; return 0;
}

函数指针变量

这是指向函数的指针。函数在程序编译后会被存储在内存中特定的代码段,函数指针存储的就是这个函数在内存中的起始地址,借助它可以调用该函数。
例如:

#include <stdio.h>int add(int a, int b) {return a + b;
}int main() {// 函数指针指向 add 函数int (*funcPtr)(int, int) = add; return 0;
}

使用场景
字符指针变量
常用于字符串处理,如字符串的复制、比较、查找等操作,也可用于动态分配内存存储字符串。
数组指针变量
主要用于处理多维数组,在函数参数传递时,能方便地操作二维或更高维数组。
函数指针变量
适用于实现回调函数、函数表等,可使程序在运行时动态选择要执行的函数,增强代码的灵活性和可扩展性。

结尾

这一课的内容就到这里了,下节课继续学习指针的其他一些知识
如果内容有什么问题的话欢迎指正,有什么问题也可以问我!
在这里插入图片描述

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

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

相关文章

UE5.5 PCGFrameWork--GPU CustomHLSL

在上一篇UE5.5 PCGFrameWork使用入门-CSDN博客 大致介绍了UE5 PCG框架的基本使用. 本篇探索PCGFrame的高级应用--GPU点云。也就是利用GPU HLSL编程对点云进行操纵&#xff0c;可以大幅度提升点云生成效率。 目前在UE5 PCG框架中&#xff0c;点云GPU的应用大致分为三类: Point…

Games202 Lecture11 LTC | Disney principled BRDF | NPR

Shading with microfacet BRDFs under polygonal lighting -Linearly Transformed Cosines(LTC)Real-Time PBR Materials cont. -Disney principled BRDFNon-photorealistic rendering(NPR) Linearly Transformed Cosines(LTC) lobe花瓣 BRDF的2d形状 基本思路: 任意BRDF变…

Flink 内存模型各部分大小计算公式

Flink 的运行平台 如果 Flink 是运行在 yarn 或者 standalone 模式的话&#xff0c;其实都是运行在 JVM 的基础上的&#xff0c;所以首先 Flink 组件运行所需要给 JVM 本身要耗费的内存大小。无论是 JobManager 或者 TaskManager &#xff0c;他们 JVM 内存的大小都是一样的&a…

学习数据结构(8)双向链表

1.双向链表的实现 双向链表一般指带头双向循环链表 &#xff08;1&#xff09;双向链表的声明 &#xff08;2&#xff09;双向链表的打印 &#xff08;3&#xff09;向内存申请节点 &#xff08;4&#xff09;初始化双向链表 或 &#xff08;5&#xff09;尾部插入 &#xf…

【漫话机器学习系列】088.常见的输出层激活函数(Common Output Layer Activation Functions)

在神经网络中&#xff0c;输出层&#xff08;Output Layer&#xff09; 的激活函数&#xff08;Activation Function&#xff09;直接决定了模型的输出形式&#xff0c;并影响损失函数的选择及训练效果。不同的任务类型&#xff08;如分类或回归&#xff09;需要使用不同的激活…

Python 鼠标轨迹 - 防止游戏检测

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

工业相机在工业生产制造过程中的视觉检测技术应用

随着技术不断发展以及工业4.0时代的到来&#xff0c;利用工业相机进行视觉检测技术已经成为制造业不可或缺的一部分。通过结合先进的计算机视觉、AI算法和自动化设备&#xff0c;工业视觉检测为生产线质量控制和效率提升提供了革命性的解决方案。 一、什么是工业视觉检测技术 …

了解网络层

目录 一、IP协议 二、地址管理 IP地址 概念 作用 格式 网段划分 三、路由选择 网络层要做的事情主要是两个方面&#xff1a; 地址管理&#xff1a;制定一系列的规则&#xff0c;通过地址&#xff0c;描述出网络上一个设备的位置。路由选择&#xff1a;网络环境比较复杂…

NO.11十六届蓝桥杯备战|if-else语句|嵌套if|悬空else|练习4道(C++)

if-else语句 if语句 if语句的语法形式如下&#xff1a; if ( 表达式 ) 语句;表达式成⽴&#xff08;为真&#xff09;&#xff0c;则语句执⾏&#xff0c;表达式不成⽴&#xff08;为假&#xff09;&#xff0c;则语句不执⾏ 0为假&#xff0c;⾮0表⽰真&#xff0c;也就是…

Json-RPC框架项目(一)

目录 1. 项目介绍: 2. 技术选择; 3. 第三方库介绍; 4. 项目功能; 5. 模块功能; 6. 项目实现: 1. 项目介绍: RPC是远程过程调用, 像调用本地接口一样调用远程接口, 进行完成业务处理, 计算任务等, 一个完整的RPC包括: 序列化协议, 通信协议, 连接复用, 服务注册, 服务发…

Discourse 创建和配置用户自定义字段

用户自定义字段能够让你在用户注册的是要求用户提供更多的信息。这些用户提供的信息可以在用户名片&#xff0c;用户摘要页面下显示&#xff0c;甚至还可以通过 Data Explorer plugin 插件进行查询。 本文能够帮助你对这些字段进行配置和设置。 添加一个用户字段 进入 Admin…

从零到一:我的元宵灯谜小程序诞生记

缘起&#xff1a;一碗汤圆引发的灵感 去年元宵节&#xff0c;我正捧着热腾腾的汤圆刷朋友圈&#xff0c;满屏都是"转发锦鲤求灯谜答案"的动态。看着大家对着手机手忙脚乱地切换浏览器查答案&#xff0c;我突然拍案而起&#xff1a;为什么不做一个能即时猜灯谜的微信…

【C++11】lambda和包装器

1.新的类功能 1.1默认的移动构造和移动赋值 原来C类中&#xff0c;有6个默认成员函数&#xff1a;构造函数/析构函数/拷⻉构造函数/拷⻉赋值重载/取地址重 载/const 取地址重载&#xff0c;最后重要的是前4个&#xff0c;后两个⽤处不⼤&#xff0c;默认成员函数就是我们不写…

Java企业电子招投标系统:Spring Cloud微服务架构-强化企业招采竞争力:电子化招投标平台助力效率与成本控制-支持二次开发

​在当今激烈的市场竞争环境下&#xff0c;企业规模的持续扩大使得招采管理变得日益重要&#xff0c;已成为企业提升核心竞争力的关键一环。为了实现更高效、更高质量的招采成果&#xff0c;我们设计了一套基于电子化平台的解决方案&#xff0c;旨在通过电子化招投标系统&#…

计算机毕业设计Spark+大模型知网文献论文推荐系统 知识图谱 知网爬虫 知网数据分析 知网大数据 知网可视化 预测系统 大数据毕业设计 机器学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

打家劫舍3

今天和打家讲一下打家劫舍3 题目&#xff1a; 题目链接&#xff1a;337. 打家劫舍 III - 力扣&#xff08;LeetCode&#xff09; 小偷又发现了一个新的可行窃的地区。这个地区只有一个入口&#xff0c;我们称之为root。 除了 root 之外&#xff0c;每栋房子有且只有一个“父“…

指定路径安装Ollama

通过鼠标双击安装&#xff0c;默认会安装到C盘下&#xff0c;如果需要更换默认路径则可以通过命令的方式将Ollama安装到其他盘的某个目录下。 OllamaSetup.exe /DIR"D:\Ollama" #DIR指定安装路径 执行上述命令后&#xff0c;会弹出OllamaSetup.exe安装窗体界面&…

Linux:库

目录 静态库 动态库 目标文件 ELF文件 ELF形成可执行 ELF可执行加载 ELF加载 全局偏移量表GOT(global offset table) 库是写好的&#xff0c;成熟的&#xff0c;可以复用的代码 现实中每个程序都要依赖很多的基础的底层库&#xff0c;不可能都是从零开始的 库有两种…

心脏滴血漏洞复现(CVE-2014-0160)

漏洞范围&#xff1a; OpenSSL 1.0.1版本 漏洞成因&#xff1a; Heartbleed漏洞是由于未能在memcpy()调用受害用户输入内容作为长度参数之前正确进 行边界检查。攻击者可以追踪OpenSSL所分配的64KB缓存、将超出必要范围的字节信息复 制到缓存当中再返回缓存内容&#xff0c;…

一文学会:用DeepSeek R1/V3 + AnythingLLM + Ollama 打造本地化部署的个人/企业知识库,无须担心数据上传云端的泄露问题

文章目录 前言一、AnythingLLM 简介&基础应用1.主要特性2.下载与安装3.配置 LLM 提供商4.AnythingLLM 工作区&对话 二、AnythingLLM 进阶应用&#xff1a;知识增强使用三、AnythingLLM 的 API 访问四、小结1.聊天模式2.本地存储&向量数据库 前言 如果你不知道Olla…