| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 【C语言】指针和数组的深入理解(第三期) -> 正文阅读 |
|
[C++知识库]【C语言】指针和数组的深入理解(第三期) |
眼里藏星河,笑里带月亮.目录 1、指针变量在口语中为什么会跟指针混用?这里我们先阐述一个问题,为什么很多人会混用指针变量和指针呢?其实说法不是完全错误,为什么呢?请看如下代码:
看以上代码相信大家就能明白了,当指针做右值的时候,他本质上就是一个地址,地址就是指针,所以在这种情况下,指针变量可以理解成指针,但不建议这么理解,之所以在前两期我没有强调这个问题,是怕初学者会弄混淆了,有了前两期的学习,在来看这个问题就很轻松了。 但是我们心里面还是要把指针和指针变量区分开来,知道什么时候是混用什么时候不是混用的,为了书面表达以及名词阐述,后面的内容在口语上可能会混用,但是你们自己要有一个谱,还是建议要区分清楚这两个概念。 2、指针数组和数组指针?2.1 什么是指针数组??很多小伙伴在接触指针数组和数组指针的时候是非常头疼的,总会混淆两个的概念,?那么本期会以一个很清晰讲解带大家深入理解: 我们再来回顾一遍数组的定义:具有相同类型元素的集合,我们称为数组 指针是类型吗?不是,指针只是地址,那?int* 是类型吗?double* 是类型吗?是的!分别是整型指针类型,双精度浮点型指针类型,假设我有十个整型指针,也就对应其中十个变量的地址,我们可以把它们放到一个数组里吗?可以的!这就是指针数组:存放指针的数组,每个指针的类型都是一样。 它的语法格式是这样的:int* p[10]??意思是这个数组有十个元素,每个元素类型是 int*,那么指针数组是数组还是指针?数组!存放指针的数组! 2.2 什么是数组指针?上期我们也学习过 &arr,说它要放在一个数组指针里,我们今天就来探讨下什么是数组指针: 前面我们也了解过,int* p 它是一个可以指向整型数据的指针变量,float* p 它是一个可以指向单精度浮点数数据的指针变量。那么可以理解 *p 表示他是个指针变量,int 就是它对应指向的数据类型,那我如果要指向一个数组呢? 数组的类型是什么?int arr[10] 其实在C语言中这样定义数组在阅读上是有点变扭的,像Java中int[10] arr,?是定义数组,上期也讲过,数组拿 int arr[10] 来说,他的类型就是 int[10],一个数组十个元素,每个元素是 int 类型。所以我们要拿指针去指向int[10] 这种类型该如何写呢? int (*p)[10]?这样就是我们的数组指针,因为 [ ] 的优先级比 * 高,所以我们先 p 跟 * 结合,表示它是一个指针变量,指向的类型是 int[10],刚好跟我们 int* p 的说法吻合。 数组指针是指针!是一个存放数组地址的指针变量。(有时候为了说法方便,会混用指针和指针变量,大家要自己注意区分) 2.3 指针数组和数组指针的布局为了方便大家的理解,请看以下图片,但是这并不是真实的内存布局。就好似指针变量并没有一根线去指向一个地址,他只是一个变量存放着地址。 所以看到这里,你应该更能理解上一期取地址数组名与数组名的区别了吧! 2.4 数组指针的使用简单的使用:
在我们打印数组中,可以用数组指针来接收,数组名是 arr,表示首元素地址,但是二维数组的首元素的第一行,所以我们这里传递的首元素地址本质是第一行一维数组的地址,所以我们可以用数组指针来接受,因为数组指针是一个指向数组的指针。? 3、多维数组和多维指针3.1 二维数组二维数组,其实也是个麻烦的地方,很多书中都把二维数组画成一个几行几列的图形,这样图确实可以帮助我们理解,但是我们也要清楚一点,这些是示意图,并非真正的内存布局。下面我们来通过代码来看看二维数组在内存中如何布局的: 通过打印每个元素的地址,我们也能发现,二维数组在内存中的布局是连续的。如果我们要画比较真实的内存布局的话,应该这么画: 数组的定义是:具有相同类型元素的集合,数组当中可以保存任何类型,这里的二维数组图是不是相当于数组保存了数组,一个数组有三个元素,每个元素保存了三个数组类型 int[3],其实我们完全可以理解成,这些二维数组可以当成一维数组来看,只不过它内部的元素也是数组而已,这里就能说明,既然一维数组是线性递增的,而一维数组每个元素又保存的数组,所以整体二维数组也是线性递增的,所以:二维数组可以被看作内部元素是一维数组的数组。 那既然是连续的,我们第一次打印数组每个元素的内存时,是不是可以换种方法打印?
但是我们通常也不会这么去做,下面有一道关于二维数组的题,如果你能看懂,并且能自己分析,那就证明对数组的理解没有问题了,一定要注意数组名是什么的问题!
3.2 二级指针在学习二级指针之前,我们要了解,指针变量是一个变量,既然是变量就有地址,如果我们要保存一个一级指针变量的地址该如何做呢?用二级指针变量来存放一级指针变量的地址! 简单使用: 二级指针, 当 pp 第一次解引用,访问的是 p 指针变量,如果此时进行赋值,则是修改了 p 里面存放的地址,当 pp 第二次解引用,本质是先访问 p 指针变量,然后对 p 指针变量解引用,最后也就是访问 p 保存地址对应的内容。 至于超过二维的数组,和超过二级的指针,一般用的很少,感兴趣的可以按照上面分析的方法下来自己研究研究。 3.3 一道面试题
我们结合图解,再来分析这道题的解法: 这道题,首先要找出 &arr[4][2] 所对应的地址,这个很简单,可是 &p[4][2] 对应的地址如何找呢?首先我们知道 指针+1 跳过的是对应类型的大小,而 p 的类型是 int[4] 的类型,所以他 +1 可以跳过四个整型,而 p[4][2] 又可以写成 *(*(p+4)),这样一来 p + 4 先是跳过了 16?个整型,因为是二维数组,解引用也就是相当于找到了一维数组,站在 p 的角度 +4 之后解引用可以访问后续的一维数组,在进行 +2 解引用,则跳过了两个整型,就来到了图中的位置。 首先我们来看图,&arr[4][2] 的地址肯定是要高于 &p[4][2] 的,我们也知道,指针相减,得到的是之间的元素个数,所以 &arr[4][2] - &p[4][2] 得到的肯定是 -4,那如果以 %p 打印的话是打印无符号进制,我们将 -4 的补码当成无符号数打印出来就是:0xFFFFFFFC 下期预告:【C语言】指针和数组的深入理解(第四期) |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 13:18:04- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |