考虑数组的指针的时候我们要同时考虑类型和维数这两个属性。换一句话,就是说一个数组排除在其中存储的数值,那么可以用类型和维数来位置表示他的种类。

一维数组

在c和c++中数组的指针就是数组的起始地址(也就第一个元素的地址),而且标准文档规定数组名代表数组的地址(这是地址数值层面的数组表示)。例如:

int a[10];
int *p;

p=&a[0]//和p=a是等价的。

因为a是数组名,所以他是该数组的地址,同时因为第一个元素为a[0],那么&a[0]也代表了该数组的地址。但是我们是不是就说一个数组名 和该数组的第一个元素的&运算是一回事呢?在一维的时候当时是的,但是在高维的时候,我们要考虑到维数给数组带来的影响。

a[10]是一个数组,a是数组名,它是一个包含10个int类型的数组类型,不是一般的指针变量噢!(虽然标准文档规定在c++中从int[]到 int*直接转换是可以的,在使用的时候似乎在函数的参数为指针的时候,我们将该数组名赋值没有任何异样),a代表数组的首地址,在数字层面和a[10] 的地址一样。这样我们就可以使用指针变量以及a来操作这个数组了。
所以我们要注意以下问题:

  • p[i]和a[i]都是代表该数组的第i+1个元素;
  • p+i和a+i代表了第i+1个元素的地址,所以我们也可以使用 *(p+I)和*(a+I)来引用对象元素;
  • p+1不是对于指针数量上加一,而是表示从当前的位置跳过当前指针指向类型长度的空间,对于win32的int为4byte;

多维数组

对于二维数组a[4][6];由于数组名代表数组的起始地址,所以a(第一层)和第一个元素a[0][0]地址的数字是相同的,但是意义却是不同的。 对于该数组我们可以理解为:a的一维数组(第一层),它有四个元素a[0]、a[1]、a[2]、a[3](第二层),而每个元素又含有6个元素a[0] [0],a[0][1],a[0][2],a[0][3],a[0][4],a[0][5](第三层),…到此我们终于访问到了每个元素了,这个过程我们 经历了:a->a[0]->a[0][0];

整体来讲:a是一个4行5列的二维数组,a表示它指向的数组的首地址(第一个元素地址&a[0]),同时a[0]指向一行,它是这个行的名字 (和该行的第一个元素的首地址相同(第一个元素为地址&a[0][0]))。所以从数字角度说:a、a[0]、&a[0][0]是相同 的,但是他们所处的层次是不同的。

既然a代表二维数组,那么a+i就表示它的第i+1个元素*(a+i)的地址,而在二维数组中
*(a+i)又指向一个数组,*(a+i)+j表示这个数组的第j+1个元素的地址,所以要访问这个元素可以使用 *(*(a+i)+j)(也就是a[i][j])。

他们的示意图为(虚线代表不是实际存在的):

对照这个图,如下的一些说法都是正确的(对于a[4][6]):

  • a是一个数组类型,*a指向一个数组;
  • a+i指向一个数组;
  • a、*a和&a[0][0]数值相同;
  • a[i]+j和*(a+i)+j是同一个概念;

总结一下就是:我们对于二维指针a,他指向数组a[0,1,2,3],使用*,可以使他降级到第二层次,这样*a就指向了第一个真正的数组。对于其他的情况我们也可以采用相同的方式,对于其他维数和类型的数组我们可以采用相类似的思想。

说到指向数组的指针,我们还可以声明一个指针变量让它指向一个数组。例如:

int (*p)[5];

这时p就是一个指针,要指向一个含有5个int类型元素的数组,指向其他的就会出现问题。这个时候我们可以使用上面的什么东西来初始化呢?我们可以使用*a,*(a+1),a[2]等。原因很简单:我们在一个二维的数组中,那么表达方式有上面的相互类似的意义呢?只有 *a,*(a+1),a[2]等。

指针数组

一个指针数组是指一个数组中的每个元素都是一个指针,例如:

int *p[10];//而不能是int (*p)[10]

或者

char *p[10];

此时p是一个指针(数值上和&p[0]一样);

在前面有int t[10];

int * pt=t;//使用pt指向t

那么这里我们用什么指向int *t[10]中的t呢?我们要使用一个指针的指针:

int **pt=t;

这是因为:在int *t[10]中,每个元素是指针,那么同时t又指向这个数组,数组上和&t[0]相同,也就是指向t[0],指向一个指针变量,可以说是一个指针的指针了,所以自然要用

int **pt;

指针的指针

一个指针变量内部可以存储一个值,这个值是另外一个对象的地址,所以我们说一个指针变量可以指向一个普通变量,同样这个指针变量也有一个地址,也就是 说有一个东西可以指向这个指针变量,然后再通过这个指针变量指向这个对象。那么如何来指向这个指针变量呢?由于指针变量本身已经是一个指针了(右值),那 么我们这里就不能用一般的指针了,需要在指针上体现出来这些特点,我们需要定义指针的指针(二重指针)。

int *p1=&i;
int**p2=&p1;

综合以上的所有点,下面是我们常常看到一些匹配(也是经常出错的地方):

int a[3],b[2][3],c,*d[3];
void fun1(int *p);
void fun2(int (*p)[3]);
void fun3(int **p);
void fun4(int p[3]);
void fun5(int p[]);
void fun6(int p[2][3]);
void fun7(int (&p)[3]);

函数 不会产生编译时刻的可能值(但逻辑上不一定都对)--这里我觉得应该是有效的值

函数

不会产生编译时刻的可能值(但逻辑上不一定都对)

fun1

a, &a[i], *b ,b[i],&b[i][j] ,&c ,d[i]

fun2

b,b+i,--(这里我觉得应该是*b,*(b+1),b[1])

fun3

d

fun4

a, &a[i], *b ,b[i],&b[i][j] ,&c ,d[i]

fun5

a, &a[i], *b ,b[i],&b[i][j] ,&c ,d[i]

fun6

b

fun7

a

为什么可以有这样的搭配,原因如下:

  • 对于fun1 fun4 fun 5: 在编译器看来fun1,fun4,fun5的声明是一样,在编译时候,编译器把数组的大小舍去不考虑,只考虑它是一个指针,也就是说有没有大小说明是一样的,所以三者的形式都是fun1的形式(其实只要提供了int*指针就可以了);
  • 对于fun7 :以上的解释对于引用是不适用的,如果变量被声明为数组的引用,那么编译器就要考虑数组的大小了,那么必须和声明一模一样(所以fun7就只有a合适);
  • 对于fun2:p是一个指向一个含有3个元素的数组,这样b和b+i正好合适,而a却不是(它是指向a[0]的,不是指向这个数组的);
  • 对于fun3:p是一个指针的指针,而d指向d[0],同时d[0]又是一个指针,所以d就是一个指针的指针。但是b却不是(它是一个2*3的矩阵也就是年int [2][3]类型);
  • 对于fun6,p是一个2*3的数组类型,和b恰好完全匹配;

数组的指针、指针数组以及指向指针的指针相关推荐

  1. 20返回指针的函数与指向函数的指针

    一.返回指针的函数 指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的. 返回指针的函数的一般形式为:类型名 * 函数名(参数列表) 比如下面这个函数,返回一个指向char类型变 ...

  2. c/c++ 函数、常量、指针和数组的关系梳理

    压力才有动力,15年中旬就要准备实习,学习复习学习复习学习复习学习复习--无限循环中,好记性不如烂笔头--从数组开始,为主干. c 的array由一系列的类型相同的元素构成,数组声明包括数组元素个数和 ...

  3. C语言深度剖析书籍学习记录 第四章 指针和数组

    p 称为指针变量,p 里存储的内存地址处的内存称为 p 所指向的内存. 指针变量 p 里存储的任何数据都将被当作地址来处理 一个基本的数据类型(包括结构体等自定义类型)加上"*" ...

  4. c语言指针b 和b j,c语言精华 ------ 指针和数组

    一.指针. 它的本质是地址的类型.在许多语言中根本就没有这个概念.但是它却正是C灵活,高效,在面向过程的时代所向披靡的原因所在.因为C的内存模型基本上对应了现在von Neumann(冯·诺伊曼)计算 ...

  5. C语言指针这一篇够了(一万二千字,包含指针与数组,函数指针等详解)

    目录 零.前言 一.指针的定义 二.指针类型的意义 1.指针类型决定了指针解引用时一次访问几个字节. 2.指针类型决定了指针加减整数时的步长 三.野指针 1.未初始化的指针 2.指针的越界访问 3.指 ...

  6. 【C/C++学习】之七、指向函数的指针

    什么是指向函数的指针 函数指针是指向函数的指针变量,不是指向对象的指针!函数指针本身应该是"指针变量": "在C语言中,函数本身不是变量,但可以定义指向函数的指针,这种指 ...

  7. 【C语言学习笔记】26. 指针(3)指向指针的指针、传递指针给函数

    前言 指向指针的指针是一种多级间接寻址的形式,或者说是一个指针链.通常,一个指针包含一个变量的地址.当我们定义一个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置. ...

  8. 【数据结构基础】指向函数的指针

    文章目录 一.函数的指针 二.指向函数的指针变量 三.调用函数的两种方式 四.用指向函数的指针作函数参数(重点) 五.为什么要将指向函数的指针变量作为函数的形参(重点) 一.函数的指针 首先,函数名代 ...

  9. C指针8:二级指针(意思就是指向指针的指针)

    指针可以指向一份普通类型的数据,例如 int.double.char 等,以下简称一级指针: 也可以指向一份指针类型的数据,例如 int *.double *.char * 等.以下简称二级指针:即如 ...

  10. C++基础之指向成员的指针

    C++中指向成员的指针 一个类有两种基本的成员:函数成员和数据成员.同样的,指向成员的指针也有两种:指向函数成员的指针和指向数据成员的指针.后则其实并不常用,因为类一般是不含有公共数据成员的,仅当用在 ...

最新文章

  1. 【Linux学习笔记】 - 什么是Linux?
  2. javascript捕获ocx事件
  3. android读写文本文件,Android读写文件
  4. Java SecurityManager checkDelete()方法与示例
  5. java 不显示控制台_命令行启动java程序不显示控制台窗口
  6. java类成员方法(成员函数)的初步介绍
  7. centos修改磁盘uuid_如何修改linux磁盘的uuid
  8. 学习Python的利器:内置函数dir()和help()
  9. CS106A编程方法学二
  10. 新起点、新目标--获得MVP后的感悟
  11. es like模糊匹配_Elastic search模糊匹配,精确匹配显示在前
  12. matlab绘制三维机翼,三维机翼某一断面的压力系数X-Y曲线绘制——使用tecplot的extract功能...
  13. 了解腾讯云云支付CPay特性及应用场景
  14. 浏览器下载文件时文件名中文乱码问题
  15. 概率与数理统计学习总结四---连续型随机变量及其概率密度
  16. 智能搬运机器人系列之使用旭日X3派实现机器人防脱轨功能
  17. L39.linux命令每日一练 -- 第六章 文件备份与压缩命令 -- scp和rsync
  18. Plu2006即将开赛,参赛选手名单公布
  19. 用Bootstrap实现mansory网格瀑布流布局插件
  20. linux点用户输密码时就调回登录框,Linux系统登陆输入密码正确 闪回登陆界面

热门文章

  1. 用VISP+Opencv做相机到机械臂的标定
  2. java 又一次抛出异常 相关处理结果演示样例代码
  3. 求解二阶偏微分方程c语言,科学网—求解偏微分方程开源有限元软件deal.II学习--Step 3 - 亓欣波的博文...
  4. PHP_微信公众号开发(1)
  5. 关于移动硬盘故障:使用驱动器G:中的光盘之前需要将其格式化或者无法访问磁盘G:参数错误的解决办法
  6. autojs读取文字_Auto.js小白详细代码分析教程-如何阅读本文档 - Documentation
  7. NewstartHA 配置技巧
  8. 用 Vue 改造 Bootstrap,渐进提升项目框架[转]
  9. 机器学习损失函数 / 激活函数 / 优化算法 总览
  10. [经验技巧] 路由mini安装OpenWRT源的Transmission插件,实现PT下载(需SSH)