这俩兄弟长得实在太像,以至于经常让人混淆。然而细心领会和甄别就会发现它们大有不同。

前者是指针数组,后者是指向数组的指针。更详细地说。

前: 指针数组;是一个元素全为指针的数组.
后: 数组指针;可以直接理解是指针,只是这个指针类型不是int也不是char而是 int [4]类型的数组.(可以结合函数指针一并看看......)

int*p[4]------p是一个指针数组,每一个指向一个int型的
int (*q)[4]---------q是一个指针,指向int[4]的数组。

两者在定义的时候如下:

int k;
cin>>k;

char *p[2];
p[0]=new char[k];
p[1]=new char[k];

char (*b)[2];
b=new char[k][2];

这样空说是不是依旧小白?举个例子

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int *p[4]; //p是一个指针数组,每一个指针都指向一个int型数据
  6. int a=1,b=2,c=3,d=4;
  7. int i;
  8. p[0]=&a;
  9. p[1]=&b;
  10. p[2]=&c;
  11. p[3]=&d;
  12. int (*q)[4];//q是一个指针,指向int[4]数组
  13. //q[0]=&a;//error   q是指向int[4]数组的指针,而&a是一个int型指针,所以不能赋值
  14. int aa[4]={5,6,7,8};
  15. q=&aa;
  16. cout << "p的值:" << p << endl; //注意,p不等于p[0]
  17. cout << "p[0]的值:" << p[0] << "  a的地址:" << &a << endl;
  18. cout << "p[0]地址保存的值:" << *(p[0]) << "  a的值:" << a << endl;
  19. cout << "p[1]地址保存的值:" << *(p[1]) << "  b的值:" << b << endl;
  20. cout << "p[2]地址保存的值:" << *(p[2]) << "  c的值:" << c << endl;
  21. cout << "p[3]地址保存的值:" << *(p[3]) << "  d的值:" << d << endl;
  22. cout << "q的值:" << q << "  aa的地址:" << &aa << endl;
  23. cout << "q[i]的地址:" << endl;
  24. for(i = 0; i < 4; ++i)
  25. cout << q[i] << endl;//q[0] 与 q的值相同
  26. cout << "q指向int[4]的所有值:" << endl;
  27. for(i = 0; i < 4; i++)
  28. cout << q[0][i] << ' ';
  29. cout << endl;
  30. //cout<<*(p[0])<<*(q[0])<<endl;
  31. return 0;
  32. }

运行结果:

p的值:0x22ff60
p[0]的值:0x22ff5c  a的地址:0x22ff5c
p[0]地址保存的值:1  a的值:1
p[1]地址保存的值:2  b的值:2
p[2]地址保存的值:3  c的值:3
p[3]地址保存的值:4  d的值:4
q的值:0x22ff30  aa的地址:0x22ff30
q[i]的地址:
0x22ff30
0x22ff40
0x22ff50
0x22ff60
q指向int[4]的所有值:
5 6 7 8

以下为网友的解释,可能阐述得更为细致。

定义涉及两个运算符:“*”(间接引用)、“[]”(下标),“[]”的优先级别大于“*”的优先级别。

首先看int
*p[4],“[]”的优先级别高,所以它首先是个大小为4的数组,即p[4];剩下的“int
*”作为补充说明,即说明该数组的每一个元素为指向一个整型类型的指针。int
*p[4]的存储结构如下:(存储方格横向排列或竖向排列没区别,只要按内存地址顺序排列就行,此处只是为画图方便)

再看int (*q)[4]。它首先是个指针,即*q,剩下的“int [4]”作为补充说明,即说明指针q指向一个长度为4的数组。int (*q)[4]的存储结构如下:

请看以下定义:

int a[2][4]={{2,5,6,8},{22,55,66,88}};

int c[4]={5,8,9,4};

int d[3]={23,12,443};

int *p[4],(*q)[4];

q=a;

*p=c;

*(p+1)=d;

则int *p[4]和int (*q)[4]的存储数据为:

验证:

 

#include <stdio.h>

int main(void)

{

int a[2][4]={{2,5,6,8},{22,55,66,88}};

int c[4]={5,8,9,4};

int d[3]={23,12,443};

int *p[4],(*q)[4];

q=a;

*p=c;

*(p+1)=d;

int i,j;

for(i=0;i<2;i++)

for(j=0;j<4;j++)

{

if((i==1)&&(j==3)) break;

printf("*(*(p+%d)+%d)=%d\n",i,j,*(*(p+i)+j));

}

puts("===============");

for(i=0;i<2;i++)

for(j=0;j<4;j++)

printf("*(*(q+%d)+%d)=%d\n",i,j,*(*(q+i)+j));

return 0;

}

输出结果为:

*(*(p+0)+0)=5

*(*(p+0)+1)=8

*(*(p+0)+2)=9

*(*(p+0)+3)=4

*(*(p+1)+0)=23

*(*(p+1)+1)=12

*(*(p+1)+2)=443

===============

*(*(q+0)+0)=2

*(*(q+0)+1)=5

*(*(q+0)+2)=6

*(*(q+0)+3)=8

*(*(q+1)+0)=22

*(*(q+1)+1)=55

*(*(q+1)+2)=66

*(*(q+1)+3)=88

C++中,指针数组和数组指针的更多相关文章

  1. C/C++中数组转换成指针的情况

    数组转换成指针:在大多数用到数组的表达式中,数组自动转换成指向数组首元素的指针.比如: int ia[10]; int *p = ia; //ia转换成指向数组首元素的指针 以下情况上述转换不会发生: ...

  2. C/C++中的指针数组和数组指针

    1. 指针数组 定义:int *p[n],由于[]的优先级高于*,p和[]结合成一个数组,该数组的元素存储的是int类型的指针,由于数组内容是指针,因此p+1的步长是sizeof(int*),在32位 ...

  3. PHP中使用数组指针函数操作数组示例

    数组的内部指针是数组内部的组织机制,指向一个数组中的某个元素.默认是指向数组中第一个元素通过移动或改变指针的位置,可以访问数组中的任意元素.对于数组指针的控制PHP提供了以下几个内建函数可以利用. ★ ...

  4. C语言中字符数组和字符串指针分析

    这几天搞Unix上的C程序,里面用到了很多字符数组和字符串指针,我记得在学完C语言后相当一段时间里,对指针这个东西还是模模糊糊,后来工作也没怎么 用到过C,虽然网上这类的文章也有很多,还是决定自己在这 ...

  5. 对于C语言中数组名是指针的理解

    我们都知道,c语言中数组名是一个指针,比如下面这段代码 #include<iostream>using namespace std;int main(){ int a[4]={1,2,3, ...

  6. C语言中的指针数组和数组指针

    代码: #include <iostream> using namespace std; int main(){ ]; ]; cout<<sizeof(a)<<en ...

  7. C语言中的函数、数组与指针

    1.函数:当程序很小的时候,我们可以使用一个main函数就能搞定,但当程序变大的时候,就超出了人的大脑承受范围,逻辑不清了,这时候就需要把一个大程序分成许多小的模块来组织,于是就出现了函数概念:  函 ...

  8. OpenCV二维Mat数组(二级指针)在CUDA中的使用

    CUDA用于并行计算非常方便,但是GPU与CPU之间的交互,比如传递参数等相对麻烦一些.在写CUDA核函数的时候形参往往会有很多个,动辄达到10-20个,如果能够在CPU中提前把数据组织好,比如使用二 ...

  9. C语言中数组变量和指针变量

    指针变量为什么需要类型? 数组变量和指针变量在使用sizeof时不同,sizeof(数组变量)是数组长度,sizeof(指针变量)是存储int的字节长度4或者8(64bit). 数组变量在参数传递中, ...

  10. 别人不会给你说的---C语言中数组名和指针的区别 及 sizeof用法

    引自: http://blog.csdn.net/tianyue168/article/details/5781924 #i nclude <iostream.h> int  main( ...

随机推荐

  1. Silverlight管理系统源码(用于开发ERP、OA、CRM、HR、进销存、财务等系统之用)

    Silverlight大型管理系统源代码(支持创建ERP.OA.CRM.HR.进销存.财务等系统之用) 可用于开发以下系统 SilverlightERP SilverlightCRM Silverli ...

  2. 关于CGContextSetBlendMode: invalid context 0x0的错误

    在ios 7的模拟器中,选择一个输入框准备输入时,会触发这个错误,以下是出错详细日志: <Error>: CGContextSetBlendMode: invalid context 0x ...

  3. Paxos一致性算法

    分布式系统的整体思路:协调者与参与者 分布式系统中,每个节点可以知道自己在事务操作过程中是成功还是失败,但无法获取其他节点的操作结果,所以就不知道这个事务是否在所有机器上全都执行成功,所以需要引入一个 ...

  4. 随机数生成器console

    #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { ]; ]; int i; ...

  5. Sonar升级遇到的那些事儿

    目录 背景 如何升级 如何回滚 问题解决 参考 背景 目前我们用SonarQube版本是4.0,这次准备升级到最新版本5.1, 以便支持以后的JavaScript的项目. 如何升级 我们可以直接跨越版 ...

  6. Python绑定方法,未绑定方法,类方法,实例方法,静态方法

    >>> class foo(): clssvar=[1,2] def __init__(self): self.instance=[1,2,3] def hehe(self): pr ...

  7. mac下删除svn账号

    以mac os x为例(Unix/Linux类似), 1.打开命令行窗口,即用户的根目录(用户的home目录) $ ls -al drwxr-xr-x   6 linxyz  staff    204 ...

  8. Quartus II中FPGA的管脚分配保存方法

    一.摘要 将Quartus II中FPGA管脚的分配及保存方法做一个汇总. 二.管脚分配方法 FPGA 的管脚分配,除了在QII软件中,选择“Assignments ->Pin”标签(或者点击按 ...

  9. loadrunner11遇到的问题汇总及相应的解决方案(持续更新)

    1.在此界面点击Run Load Tests提示: "Can not save the license information because access to the registry  ...

  10. Myeclipse以及Genymotion工具的使用以及java后台开发小结

    1. 服务端的Servlet程序修改并保存后,需要重启tomcat服务器才能使其修改有效.重新部署web项目是没有什么卵用的. 2. servers选项卡若是移走了看不到,在window-show v ...