用指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素。
1) 多维数组元素的地址
设有一个二维数组 a,它有 3 行 4 列。它的定义为:
int a[3][4]={{1,3,5,7},{9,11,13,15},{17,18,21,23}};
a 是一个数组名。a 数组包含 3 行,即 3 个元素:a [0],a [1],a [2]。而每一元素又是一个一维数组,它包含 4 个元素 (即 4 个列元素),例如,a [0] 所代表的一维数组又包含 4 个元素: a [0][0], a [0][1], a [0][2], a [0][3],如图所示。可以认为二维数组是 “数组的数组”,即数组 a 是由 3 个一维数组所组成的。
从二维数组的角度来看,a 代表二维数组首元素的地址,现在的首元素不是一个整型变量,而是由 4 个整型元素所组成的一维数组,因此 a 代表的是首行的起始地址 (即第 0 行的起始地址,&a [0]),a+1 代表 a [1] 行的首地址,即 & a [1]。
a [0],a [1],a [2] 既然是一维数组名,而 C++ 又规定了数组名代表数组首元素地址,因此 a [0] 代表一维数组 a [0] 中 0 列元素的地址,即 & a [0][0]。a [1] 的值是 & a [1][0],a [2] 的值是 & a [2][0]。
0 行 1 列元素的地址可以直接写为 & a [0][1],也可以用指针法表示。a [0] 为一维数组名,该一维数组中序号为 1 的元素显然可以用 a [0]+1 来表示。
欲得到 a [0][1] 的值,用地址法怎么表示呢?既然 a [0]+1 是 a [0][1] 元素的地址,那么,*(a [0]+1) 就是 a [0][1] 元素的值。而 a [0] 又是和 *(a+0) 无条件等价的,因此也可以用 *(*(a+0)+1) 表示 a [0][1] 元素的值。依此类推,*(a [i]+j) 或 *(*(a+i)+j) 是 a [i][j] 的值。
2) 指向多维数组元素的指针变量
① 指向数组元素的指针变量
【例1】输出二维数组各元素的值。这里采用的方法是用基类型为整型的指针变量先后指向各元素,逐个输出它们的值。(三种方法均可)
#includeusing namespace std;
int main()
{
int a[3][4] = { 1,3,5,7,9,11,13,15,17,19,21,23 };
//p是基类型为整型的指针变量
//p = a[0] 等同于 p = &a[0][0]; 也即0行首元素的地址
int* p;
for (p = a[0]; p< a[0] + 12; p++)
cout<< *p<< " ";
for (int i = 0;i<3;i++)
{
for (int j = 0;j<4;j++)
{
//cout<< *(*(a + i) + j)<< " ";
cout<< *(a[i] + j)<< " ";
}
}
cout<< endl;
return 0;
}
关于指向数组元素的指针变量的几点说明:- p 是指向整型数据的指针变量,在 for 语句中对 p 赋初值 a [0],也可以写成 “p=&a [0][0]”。
- 循环结束的条件是 “p
- 执行 “cout<<*p;” 输出 p 当前所指的列元素的值,然后执行 p++,使 p 指向下一个列元素。
可以定义一个指针变量,它不是指向一个整型元素,而是指向一个包含 m 个元素的一维数组。这时,如果指针变量 p 先指向 a [0](即 p=&a [0]),则 p+1 不是指向 a [0][1],而是指向 a [1],p 的增值以一维数组的长度为单位。
【例2】输出二维数组任一行任一列元素的值。
#includeusing namespace std;
int main( )
{
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int (*p)[4],i,j;
cin>>i>>j;
p=a;
cout<<*(*(p+i)+j)<
由于执行了 “p=a”,等同于"p = &a[0] "使 p 指向 a [0]。因此 p+2 是二维数组 a 中序号为 2 的行的起始地址 (由于 p 是指向一维数组的指针变量,因此 p 加 1,就指向下一个一维数组)。*(p+2)+3 是 a 数组 2 行 3 列元素地址。*(*(p+2)+3) 是 a [2][3] 的值。
3) 用指向数组的指针作函数参数
一维数组名可以作为函数参数传递,多维数组名也可作函数参数传递。
【例3】输出二维数组各元素的值。题目与例1相同,但本题用一个函数实现输出,用多维数组名作函数参数。
#includeusing namespace std;
int main( )
{
void output(int (*p)[4]); //函数声明
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
output(a); //多维数组名作函数参数
return 0;
}
//相当于 p = a;或者 p = &a[0];
void output(int (*p)[4]) //形参是指向一维数组的指针变量
{
int i,j;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
cout<<*(*(p+i)+j)<<" ";
cout<
指针数组和二维数组指针的区别指针数组和二维数组指针在定义时非常相似,只是括号的位置不同:
int *(p1[5]); //指针数组,可以去掉括号直接写作
int *p1[5]; int (*p2)[5]; //二维数组指针,不能去掉括号
指针数组和二维数组指针有着本质上的区别:指针数组是一个数组,只是每个元素保存的都是指针,以上面的 p1 为例,在 32 位环境下它占用 4×5 = 20 个字节的内存。二维数组指针是一个指针,它指向一个二维数组,以上面的 p2 为例,它占用 4 个字节的内存。
二级指针使用二级指针初始化一级指针
#include#include#includeenum
{
Success,NameErr,SexErr,StrNumErr,ScoreErr
};
typedef struct stu
{
char *name;
char *sex;
char *strNum;
float *score;
}STU;
int init(STU ** p)
{
*p = (STU *)malloc(sizeof(STU));//*p就是ps,申请一块空间里面存放4个不同类型的指针,将首地址赋值给ps
//初始化一级指针,使这4个不同类型的指针都有所指向
(*p)->name = (char *)malloc(sizeof(100));
if((*p)->name == NULL)
return NameErr;
(*p)->sex = (char *)malloc(sizeof(char));
if((*p)->sex == NULL)
return SexErr;
(*p)->strNum = (char *)malloc(sizeof(30));
if((*p)->strNum == NULL)
return StrNumErr;
(*p)->score = (float *)malloc(sizeof(float));
if((*p)->score == NULL)
return ScoreErr;
return Success;
}
int main(void)
{
STU * ps = NULL;
int ret = init(&ps);
if(ret != Success)
return -1;
strcpy(ps->name,"wahaha");
*(ps->sex) = 'x';
strcpy(ps->strNum,"语文");
*(ps->score) = 66.5;
printf("姓名:%s\n性别:%c\n科目:%s\n分数:%.2f\n",ps->name,*(ps->sex),ps->strNum,*(ps->score));
return 0;
}
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网站题目:C/C++二维数组指针(指向二维数组的指针)详解-创新互联
文章地址:http://lswzjz.com/article/dgddes.html