指向数组的指针:
很多人以为“指向数组的指针”就是“指向指针的指针”,于是有人写这样的代码:
int a[3][4];
int **p = a;//错误
这个代码的错误之处在于a是一个数组,它的成员也是数组,所以a叫做“数组的数组”——C++中严格说来没有二维数组。那么,你要用一个指针来记录a,就要用一个能表示“数组的数组”的指针,以下代码是正确的:
int (*p)[4] = a;//正确
只有这样才能保证++p使p指向a的下一对像(该对像是一个数组)。
顺便提一句:不要写成“int *p[4];”
指针本身就是一个变量,当指向数组时,也有类型:
如:
intc[3][4][5];
c,&c,&(&c),c[0]所指都是数组首地址,可是类型不同。
&c的类型是(int(*)[3][4][5])
&c+1指的是:&c+sizeof(int)*3*4*5
c的类型是(int(*)[4][5]),
c+1指的是:c+sizeof(int)*4*5
*c,即c[0],类型是int(*)[5]
*c+1指的是:c+sizeof(int)*5
*c[0]类型是int*
*c[0]+1指的是:c+sizeof(int)+1
数组做为形参时,退化为指针
三维数组,退化为指向二维数组的指针
二维数组,退化为指向一维数组的指针
一维数组,退化为指向类型(如int)的指针
#include<stdio.h>
void main()
{
void average(float *p,intn);//求平均分数,形参为指向变量的指针变量
void search(float(*p)[4],intn);//求第n个学生的成绩,形参为一指向4维数组的指针变量
floatscore[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};
average(*score,12);//传入实参*score与&score[0][0]即指向的是元素
search(score,2);//传入实参score其指向为数组中的一行。
}
void average(float *p,int n)
{
float*p_end;
float sum=0,aver;
p_end=p+n-1;
for(;p<=p_end;p++)//p指向下一个元素
sum+=*p;
aver=sum/n;
printf("average=%5.2fn",aver);
}
void search(float (*p)[4],intn)
{
int i;
printf("the score of No.%d are:n",n);
for(i=0;i<4;i++)
printf("%5.2f",*(*(p+n)+i));
printf("n");
}
输出结果如下:
指向数组的指针的解引用
三维数组,可以看做是指向二维数组的指针,解引用后为指向一维数组的指针,即二维数组
二维数组,可以看做是指向一维数组的指针,解引用后为指向类型(如int)的指针,即一维数组
一维数组,可以看做是指向类型(如int)的指针,解引用后为类型数(如int数),即一个数
{
inta[5]={1,2,3,4,5};
intb[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
printf("%pn",&a);
printf("%pn",&a+1);
printf("n");
printf("%pn",a);
printf("%pn",a+1);
printf("n");
printf("%pn",&b);
printf("%pn",&b+1);
printf("n");
printf("%pn",b);
printf("%pn",b+1);
printf("n");
printf("%pn",*b);
printf("%pn",*b+1);
printf("n");
printf("%pn",**b);
printf("%pn",**b+1);
getch();
return0;
}
有人问我二三维指针的事,讲了一大堆,总结了以下代码:
void TestPointer()
{
//优先级:()>[]>*
int i,j,k;
// 指针和数组
// 看是指针还是数组要看他的名字(不带[]也不带*)能否直接对其进行内存分配
// 因为数组是确定的分配好内存地址的,而指针则是用于指向地址的
// 所以为指针分配内存或赋值时,应该理解为指向数组地址或其他地址
// 读法:由低优先级向高优先级读
// *Array0[10]:指针——数组
// int **Array1[2]:指针——指针——数组(二维指针数组)
// *(*pPointer4)[2]:指针——数组——指针(指向指针数组的指针)
// (*pPointer3)[30][20]:数组——数组——指针(指向二维数组的指针)
// 1、数组和指针数组
intArray[10]; //Array是数组,有10个元素,元素的类型是int型
int*Array0[10];// Array0是指针数组,有10个元素,元素的类型是int型指针
for( i=0; i<10; i++ )
{
Array0 = newint[i+1]; //Array0是int型的指针
delete[] Array0;
}
int**Array1[2];// 一个指向指针的指针的数组(二维指针数组),拥有两个元素
// 每一个元素都是int ** 型(指向指针的指针) ,但 Array1 终究也是个数组,
Array1[0]=new int*[10]; // int*[10]为指针数组,见下面一条
Array1[1]=new int *[10];
delete [] Array1[0];
delete [] Array1[1];
// 2、指向数组的指针
int *pPointer0=newint[10]; //pPointer0是指针,赋值号右边但申请的是一个数组,只不过用指针指向它
// 指向“指针数组”的“指向指针的指针”
// 定义一个数组,有10个元素,元素的类型是int*
// 用指向指针的指针指向该指针数组, pPointer1[]表示数组中的每个元素(int *)
// 为指针数组中每个元素申请空间,并为申请到的空间中的元素赋值
int **pPointer1=new int*[10];
for( i=0; i<10; i++ )
{
// *(pPointer1+i) = new int[i+1]; 也可
pPointer1 = new int[i+1];
for( j=0; j<i+1; j++ )
{
// *(*(pPointer1+i)+j) = 1;
pPointer1[j] = 1;
}
delete[] pPointer1;
}
delete [] pPointer1;
// 指向二维数组的指针,
// 该二维数组最低维数的元素数量为8个,类型为int
int (*pPointer2)[8];
// 理解 (*pPointer2)[8]:
// (*pPointer2)说明它是一个指针,
// (*pPointer2)[8]说明p2一次跳过8个元素,
//即pPointer2指向一个二维数组,且最低维为8,该数组元素不是指针
pPointer2= new int[10][8];
for( i=0; i<10; i++ )
{
for( j=0; j<8; j++ )
{
pPointer2[j] = 20;
}
}
delete []pPointer2; // 删除(释放)二维数组
// 指向三维数组的指针,该三维数组低两维的元素数量为[30],[20],类型为int
int(*pPointer3)[30][20];// 这个数组低两维必须是确定的
pPointer3=new int[1][30][20];
delete []pPointer3; //删除(释放)三维数组
// 指向二维指针数组的指针
// 声明一个3*2的二维数组,元素是指针,
// 用一个指针的指针pPointer4指向该数组首地址
// pPointer4[j]是该二维数组的每个元素,(i<=3j<=2)
int *(*pPointer4)[2] = new int *[3][2];
// 对*(*pPointer4)[2]的理解:
// (*pPointer4)说明pPointer4是指针,
//(*pPointer4)[2]说明这个指针写成pPointer4时,一次跳两个元素,即pPointer4指向的数组最低维=2
// *(*pPointer4)[2]说明每个元素都是指针
for( i=0; i<3; i++ )
{
for( j=0; j<2; j++ )
{
pPointer4[j] = new int [5];
for( k=0; k<5; k++ )
{
pPointer4[j][k] = 5;
}
delete[] pPointer4[j];
}
}
delete[] pPointer4;
}