
在C语言和C++等语言中,数组元素全为指针变量的数组称为指针数组,指针数组中的元素都必须具有相同的存储类型、指向相同数据类型的指针变量。指针数组是数组元素为指针的数组(例如 int *p[3],定义了p[0],p[1],p[2]三个指针),其本质为数组。
数据类型 *首地址[];
指针数组比较适合用来指向若干个字符串,使字符串处理更加方便、灵活。
指针数组每个元素都是指针,一维数组的地址可以赋值给指针。然后进行操作.
#include
using namespace std;
int main()
{
int* p[3]; //定义一个指针数组
int a[] = { 3,6,1,9,10 }; //定义一个整型数组
p[0] = a; //p[0]是一个类型为int* 指向int的指针,a是一个int*,指向int
p[1] = a + 1;
p[2] = a + 3;
cout << (*p[0]) << " " << (*p[1]) << " " << (*p[2]) << endl; //[]优先级比()高,所以()没起到作用
cout << a[0] << " " << a[1] << " " << a[3] << endl;
int* q; //普通指针
q = a + 1;
cout << *q;
}
如果是 二维数组a[0]+1;代表a[0][1]; 这时候a[0]是行数组名它代表这一行的首地址就是a[0][0],+1就等于加它类型的字节数1x字节数,(+2就是2x字数)结果就是a[0][1];如果是一维的话,更简单;+1就等于加它类型的字节数x1;结果是a[1];

#include
using namespace std;
int main()
{
int* p[3]; //定义一个指针数组
int a[2][3] = {{3,6,1} ,{12,9,10}}; //定义一个二维整型数组
p[0] = a[0]; //a[0]=&a[0][0]
p[1] = a[1]; // a[1]=&a[1][0]
cout << a[0][1] << endl; //输出a[0][1]
cout << *(a[0] + 1) << endl; //输出a[0][1],(a[0]+1)这样代表地址
cout << *(p[0] + 1) << endl; //输出a[0][1],指针+1代表移动一个数(列)
cout << *(p[0] + 2) << endl; //输出a[0][2],指针+1代表移动一个数(列)
return 0;
}
接下来让我们练习一道题:(二维数组全部元素求和)
#include
using namespace std;
int main()
{
int sum=0;
int* p[3]; //定义一个指针数组
int a[2][3] = {{3,6,1} ,{12,9,10}}; //定义一个二维整型数组
p[0] = a[0]; //a[0]=&a[0][0]
p[1] = a[1]; // a[1]=&a[1][0]
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
sum += *(p[i] + j);//或者 *(*(p+i)+j) 或者 p[i][j]
}
}
cout << "求和后得:" << sum << endl;
return 0;
}
【方法1基本格式】
int **p; //指针类型是int** 型,指向int*型的指针变量
p=new int*[列]
for(int i=0;i<列;i++)
{
p[i]=new int [列]
}

1.错误示范:
【指针指向二维数组不能用*p=a[0]】
#include
#include
using namespace std;
int main()
{
int a[2][2] = {1,2,3,4};
int* p;
*p = a[0];
for (int i = 0; i < 4; i++)
{
cout << setw(2) << *(p+i) ;
}
return 0;
}
2.指针数组申请动态二维数组
#include
using namespace std;
int main()
{
int m, n;
cout << "请输入行数为:" << endl;
cin >> m;
cout << "请输入列数:" << endl;
cin >> n;
int**p; //
p = new int*[n];
for (int i = 0; i < n; i++)
{
p[i] = new int[n]; //左边行,右边列
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> p[i][j];
}
}
cout << "输出为:" << endl;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout<< p[i][j]<<" ";
}
}
delete[]p;
return 0;
}
1.错误示范效果展示:

2.申请动态二维数组正确效果

*(p+1):走了一行; * (p+1)+1走了一列
指针数组名就是元素地址相当于一级指针取地址就是二级指针,故指针数组名相当于二级指针“数据类型 * p” 本身就是一个指针,而它的数据类型是int * 也是一个指针,故称为二级指针。

数组指针,指的是数组名的指针,即数组首元素地址的指针。即是指向数组的指针。例:int (*p)[10]; p即为指向数组的指针,又称数组指针。
数据类型(*p)[];
数组指针是指向数组地址的指针,其本质为指针;
#include
using namespace std;
int main()
{
int(* p)[3]; //定义一个数组指针
int a[2][3] = {{3,6,1} ,{12,9,10}}; //定义一个二维整型数组
return 0;
}
这里a是个二维数组的数组名,相当于一个二级指针常量;//二维数组名与二级指针毫无关系(初学者常常混淆)。
p是一个指针变量,它指向包含5个int元素的一维数组,此时p的增量以它所指向的一维数组长度为单位;
p+i是一维数组a[i]的地址,即p+i==&a[i];对该式两边作取内容运算()得(p+i)a[i],由于二维数组中a[i]&a[i][0], 则 * (p+i)表示a[i][0]的地址,即 * (p+i)==&a[i][0](p+2)+3表示a[2][3]地址(第一行为0行,第一列为0列),(*(p+2)+3)表示a[2][3]的值。

注意a[0],a[1],a[2]表示的都是对应那行的数组首地址,和数组名,而不是一个元素,(这里得到*号不是指针,而是取地址)!!!!!!!!!!!
多维数组地址的表示方法
设有整型二维数组a[3][4]如下:
1000 1001 1002 1003
1004 1005 1006 1007
1008 1009 1010 1011
设数组a的首地址为1000,各下标变量的首地址及其值。C语言允许把一个二维数组分解为多个一维数组来处理。因此数组a可分解为三个一维数组,即a[0],a[1],a[2]。 每一个一维数组又含有四个元素。例如a[0]数组,含有a[0][0],a[0][1],a[0][2],a[0][3]四个元素。数组及数组元素的地址表示如下: a是二维数组名,也是二维数组0行的首地址,等于1000。a[0]是第一个一维数组的数组名和首地址,因此也为1000。(a+0)或a是与a[0]等效的,它表示一维数组a[0]0号元素的首地址。也为1000。&a[0][0]是二维数组a的0行0列元素首地址,同样是1000。因此,a,a[0] ,*(a+0), * a,&a[0][0]是相等的。同理,a+1是二维数组1行的首地址,等于1004。a[1]是第二个一维数组的数组名和首地址,因此也为1004。&a[1][0]是二维数组a的1行0列元素地址,也是1004。因此a+1,a[1],* (a+1),&a[1][0]是等同的。由此可得出:a+i,a[i], * (a+i),&a[i][0]是等同的。此外,&a[i]和a[i]也是等同的。因为在二维数组中不能把&a[i]理解为元素a[i]的地址,不存在元素a[i]。
C语言规定,它是一种地址计算方法,表示数组a第i行首地址。由此,我们得出:a[i],&a[i], * (a+i)和a+i也都是等同的。另外,a[0]也可以看成是a[0]+0是一维数组a[0]的0号元素的首地址,而a[0]+1则是a[0]的1号元素首地址,由此可得出a[i]+j则是一维数组a[i]的j号元素首地址,它等于&a[i][j]。
由a[i]= * (a+i)得a[i]+j= * ( a+i)+j,由于 * (a+i)+j是二维数组a的i行j列元素的首地址,该元素的值等于 * ( * (a+i)+j)。

1.数组指针和二维数组的联用
#include
using namespace std;
int main()
{
int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
int(*p)[4];
p = (int(*)[4])a; //目的是为了把a看作参数
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++) printf("%d ", p[i][j]); //或者 *(*(p+i)+j) 或者 *(p[i]+j)
printf("\n");
}
}
2.数组指针创建动态二维数组
#include
using namespace std;
int main()
{
int m, n;
cout << "请输入行数为:" << endl;
cin >> m;
int(*p)[3];
p = new int[m][3]; //列数是实参,否则报错哦
for (int i = 0; i < m; i++)
{
for (int j = 0; j < 3; j++)
{
cout << "请输入p[" << i << "][" << j << "]的值" << endl;
cin >> p[i][j];
}
}
cout << "输出为:" << endl;
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 3; j++)
{
cout<< p[i][j]<<" ";
}
}
return 0;
}
1.数组指针和二维数组联用

2.数组指针和动态二维数组





祝君更上一层楼!!!!!!