本文由 babystep原创,禁止转载!数组
本文经过语言加代码的方式,力图彻底理解指针、数组、指针数组和数组指针这四个东西,尤为是指针数组和数组指针,每次用起来都得从新搜索是啥意思,因此此次决定用一篇博客说明白。url
数组和指针常常用,可是理解时候容易有误差,致使不能理解指针数组和数组指针的区别,因此建议读者一步一步详细阅读。对数组和指针有好的理解,能够直接调到指针数组和数组指针部分。.net
数组: 内存空间中一段连续的内存。例如 int a[5]; a是一段连续5个int大小内存片断的首地址,首地址这点很关键,关键在哪里?关键在这说明a是常量,而不是变量。因此,虽然a是地址,但它就是那5个int片断的首地址,你能够改变这个首地址中存放的东西,可是不能改变这个地址,也就是说不能改变a。以下作法是错误的:指针
int *p; int a[5]; a = p; //错误,a是常量
指针: 是一个变量,这个变量的内容是一个地址,这个地址指向其余地方。什么是指向呢?指向的意思就是指针变量所保存的其余地址单元中所存放的数据类型。例如 int *p; p自己就是一个地址,32位系统下是4个字节,64位系统下是8个字节。它指向的数据类型用前面的int来讲明,因此咱们称p指向int数据类型。code
指针变量是变量,因此能够给指针变量赋值,以下:对象
int *p; int a[5]; p = a;//正确
说明数组指针和指针数组以前,先回顾下上面。blog
//请问下面语句对吗?为何 char s[]="hello"; char *p = "wolrd"; s = p;
首先char s[] = "hello";
是对的,这是c语言中数组变量的典型初始化方法。可是char *p = "world"
为何也能够?这是由于”world“常量字符串其实是一个常量指针,指针指向的地方是字符串首字符。所以天然能够赋值给p。 第三句错误,上文已经讲了,s是数组变量,数组的首地址,而不是指针变量,因此是常量,不能给赋值。内存
接下来讲明指针数组和数组指针字符串
顾名思义,指针数组是数组,只不过数组的元素是指针;数组指针是指针,只不过指向的对象是数组。get
//请问下面p是是数组指针仍是指针数组 int (*p)[5]; //答案是 数组指针。这是由于'*'的优先级小于[],只能用括号来增长优先级,因此括起来的p首先与* //结合,被认为是指针,指向一维数组,大小为5个int。 int a[5]; p = a;//错误,a是数组,p是数组指针 p = &a;//正确。 /*--------------------------------------------------------*/ //相对应的,指针数组以下,p先与[]结合,说明p是数组变量而不是指针变量 int *p[3]; int a[3][5]; p = a; //错误,数组变量是地址常量,不能赋值 p[0] = a[0];
由c语言知识知道,数组变量名是一个地址常量,这个地址常量表示的大小是随数组变化而变化的。举例来来理解:
int a[5]; //那么a就是&a[0] //a+1实际是 &a[1] int a[3][4];//稍微复杂点,a实际是a[0],a[0]是什么呢,是一维数组(矩阵的第一行)int [4] //所以,a+1 就等于 a[1],是第二行一维数组的地址
理解了上面,定义
int a[3][4]; int b[3][4]={0}; //要用指针数组和数组指针表示二维数组a,该怎么作? //指针数组作法:指针数组有三个元素,分别为三行的首地址 int *p[3]; for (int i=0;i<3;i++) { p[i]=a[i]; for(int j=0;j<4;j++) p[i][j]=b[i][j]; //完成赋值 } //数组指针作法:由于c语言约定最右边的下标为低维,即a[3][4]中4为低维,存储元素过程是从低维到 //高维,二维状况下是一行一行存储,因此须要知道列数 int (*p)[4]; p=a; //至关于p = a[0]; for(int i=0;i<3;i++) { for(int j=0;j<4;j++) (*p)[j] = b[i][j]; p++; //由于是数组指针,因此每自加1,地址移动其数组大小的距离。 }
例子仍是有点少,但愿有点帮助吧。