二维数组指针理解
int b[k], *q=0;//用指针要初始化!
q = b; //指针q指向数组b的首地址
以后使用数组b的元素,比如b[?],均可用q[?]代替!(注:?表示某整数索引值)
q = b+i;//此时指针q不再指向数组首地址,而是指向b[i]元素的地址
若要给b[i]元素更新值,可以:
b[i] = ?; 或者
q[i] = ?; 都是等价的。
而这是的q[i]可以写作:*(q+i),注意加括号!也就是说,
q[i]与*(q+i)等价!代表“值”
&q[i]与 q+i 等价!代表“地址”
这是一维数组,稍后给你分析二维,情况会复杂起来,因为你必须了解“指向指针的指针”这一较为抽象的概念。(老实说,对于编程老手,都有可能在某些时候晕头,更何况初学者。事实上,对于初学者还是不要过早接受这一概念为宜,但若要研究二维数组,你必须接触这个概念)
少写了!开始的地方:int b[k],这个“k”应该使用一个宏:
#define k 100
或其他数。不能直接用一个变量声明数组!
法律的确没有规定指针必须初始化,但这是一种好的编程风格!再说一遍,使用类型任何指针,请以以下两种方式之一声明:(以int为例)
int *p = 0; // 或int *p = NULL;
int *p = new int;//C中用:int *p = (int *)malloc(sizeof(int));
这两种方法任选其一。
至于用变量定义数组?不是开玩笑吧!
int k=3;
int array[k];
你把这两句写上,你看看编译器报不报错!!
至于2维数组,接下着重讲一下,首先你要对二维数组有一个正确的认识。
int a[3][5];
对于这句,你先把[5]挡住,别看:int a[3]
什么意思?声明一个数组a,有三个元素,分别是a[0],a[1],a[2]
物理位置:
口口口
a[0],a[1],a[2]
再接上[5]:int a[3][5];
什么意思?对于数组a的三个元素,每个元素又都有5个元素,分别是:
a[0]——a[0][0],a[0][1],a[0][2],a[0][3],a[0][4]
a[1]——a[1][0],a[1][1],a[1][2],a[1][3],a[1][4]
a[2]——a[2][0],a[2][1],a[2][2],a[2][3],a[2][4]
物理位置:
口口口口口 口口口口口 口口口口口
前五个“口”对应与上一个图的第一个“口”;中间五个对应第二个“口”,最后五个对应第三个“口”。这相当于又把上一个图里的三个“口”每一个都细分了5份!
你该看出来:a[0],a[1],a[2]相当于三个一维数组!每个都有5个元素。
二维数组名“a”,标识a[0][0]的地址。注意,它是一个地址常量,不能被更新,比如:a++,a--,a=?……都是错的!但可以用在赋值号“=”的右边。稍后举例。
我再给你讲解一下“指向指针的指针”之一抽象概念,希望你好好看。
声明:
int *p=0,**pp=0,b=0;
注意:p是一个指针,而pp是一个“指向指针的指针”。
对于p,你可以:
p = &b; // 令p指向变量b
但是,你不能:
pp = &b;
因为pp是一个指向指针的指针,它应该指向一个指针,但b并不是指针。可p是一个指针,所以,我们可以:
pp = &p;
注意:你可不要“等量代换”,写成:
pp = &p = &(&b)= &&b;
这是错误的!&是求地址运算符,不能对一个变量连续求两次地址!
回去接着说:
p=&b; pp=&p;
使得:p指向b,pp指向p
若要修改b的值,比如赋值为2,可以:
b = 2; 或
*p = 2; 或
**pp = 2;
前两个,你应该没什么疑问,着重看一下第三个方法:
**pp = 2;
实际上,是*(*pp) = 2;
*pp是什么?*pp是“引用pp指向的对象的值”。而它指向的对象是什么?因为pp是一个“指向指针的指针”,所以,它指向的对象是一个指针,在此例中,是指针p,即*pp 和 p 是完全等价的。
因此,对于第二种赋值方法,*p = 2;
我们可以用*pp来代换p,就成了*(*pp) = 2;//括号去掉即成为第三种方法了。
最后附上一个源程序:
#include<stdio.h>
int main(void)
{
int *p=0, **pp=0, b;
p = &b;
pp = &p;
b = 0;
printf("b= %d\n", b);
*p = 1;
printf("b= %d\n", b);
**pp = 2;
printf("b= %d\n", b);
return 0;
}
先用方法1,将b更新为0,
后用方法2,将b更新为1,
最后用方法3,将b更新为2.
明晰这个概念后,让我们来看一看如何使用“指向指针的指针”来构造一个二维数组。
#include<stdio.h>
#include<stdlib.h>
#define ROW 3
#define COLUMN 5
int main(void)
{
int **pp=0, i,j;
pp = (int **)malloc(sizeof(int)*ROW);
for (i=0; i<ROW; i++)
pp[i] = (int *)malloc(sizeof(int)*COLUMN);
for (i=0; i<ROW; i++)
for (j=0; j<COLUMN; j++)
pp[i][j] = rand()%2;
for (i=0; i<ROW; i++)
for (j=0; j<COLUMN; j++)
printf("pp[%d][%d]= %d\n", i,j,pp[i][j]);
return 0;
}
请先自己看一下,如若不明白,再解释,如果你能自己写出来类似的代码,基本上,“指向指针的指针”就不会难倒你了。