已知:一维数组:a[i]={0,1,2,3,4,…,i-1};*p=a;
故:a[i]=*(a+i)=p[i]=*(p+i)=*p++
(1)定义:第几个元素的地址,用单下标或双下标+&或*+行地址表示列地址。
如:a[0] 、a[i]、&a[0][0]、*a、*(a+i)。
已知:int a [3][4]={{0,1,2,3},{4,5,6,7},{8, 9,10,11}};
可把二维数组a 看成三个一维数组组成, 即a[0]、a[1]、a[2],它们是这三个一维数组的首元素的地址,也是这个二维数组的列地址。
列地址+1 或 列地址-1 表示左移或右移一个数据元素。
二维数组中:a[i]==*(a+i),表示数组a中第i行第0个元素的列地址。
a[0]、a[1]、a[2]是一维数组名,数组名代表数组首元素地址,故a[0]代表一维数组a[0]中第0列元素地址,即&a[0][0],a[1]值则为&a[1][0],a[2]值则为&a[2][0]
数组a中第i行第j列元素地址:
第0行0列元素地址: a[0]+0 == *(a+0)+0 == &a[0][0] == 2000==a[0]==*(a+0)==*a
第0行1列元素地址: a[0]+1 == *(a+0)+1 == &a[0][1] == 2004
第1行0列元素地址: a[1]+0 == *(a+1)+0 == &a[1][0] == 2016==a[1]==*(a+1)
第1行2列元素地址: a[1]+2 == *(a+1)+2 == &a[1][2] == 2024
第2行0列元素地址: a[2]+0 == *(a+2)+0 == &a[2][0] == 2032==a[2]==*(a+2)
*(a+i)表示第i行第0个元素的列地址
*(a+i)+j 表示第i行第j个元素的地址(=&a[i][j])
在一维数组中,a[i]表示a数组中序号为i的元素存储单元具有物理地址,占据存储空间。
在多维数组中,a[i]是一维数组名,只是一个地址,不代表某一个元素的值。
故 &a[i][j]=a[i]+j=a[0]+j=*(a+i)+j。
(2)列地址使用
使用列地址时,是将整个二维数组看成同一行。
#include
int main()
{
int a[3][3]={1,2,3,4,5,6,7,8,9};
int i;
for (i=0;i<9;i++)
{
printf("%d",*(a[0]+i));//输出:123456789
}
printf("\na[1][2]=%d",a[1][2]);//输出:a[1][2]=6
printf("\na[1][2]=%d",*(a[0]+5));//输出:a[1][2]=6
printf("\na[1][2]=%d",*(a[1]+2));//输出:a[1][2]=6
printf("\n");
return 0;
}
结论:按列地址输出,可采用以上不同方式输出,效果一致。
列地址使用列指针来指向(指向数组元素的指针),赋值方法是:
p=a[0]、p=&a[0][0]、p=*a
(1)定义:数组中的第几行,用不带下标的数组名或&+列地址表示。
如: a、a+i(不带下标的数组名)。(a+1:表示下移一行)
&a[2]=&*(a+2)=a+2 (*与&有抵消作用)
已知:int a [3][4]={{0,1,2,3},{4,5,6,7},{8, 9,10,11}};
从二维数组角度看,a代表二维数组首元素地址,此时首元素不是一个简单的整型元素,而是由4个整型元素组成的一维数组,故a为首行行地址(a=2000),
则a+1=2000+44=2016。
由于a[0]与(a+0)即*a等价,所以&a[0]就与&*a等价。而&*a就是a,它是行地址。
故:a+i=&a[0]=&*(a+i)。
(2)行地址使用
使用行地址时,是将整个二维数组看成i行j列。
如:
a 表示第0行的行地址 == &a[0]
a+1 表示1行行地址
a+i 表示第i行的行地址
注:行地址使用行指针来指向(指向一维数组的指针)
(1)*+列地址=元素
故 *&a[i][j]=a[i][j]=*(a[i]+j)=*(a[0]+j)=*(*(a+i)+j)。
如:
a[0][0]相当于*(*(a+0)+0)
a[1][2]相当于*(*(a+1)+2)
*(a+i)+j 表示第i行第j个元素的列地址(=&a[i][j])
(2)**+行地址=元素 (行地址本质上是二级地址,通过它取元素值时要多加一次*运算)
如:
**a 表示第0行0列元素值(=a[0][0]);
*(*(a+i)) 表示第i行第0列元素值(=a[i][0]);
第1行第2列元素值: *(a[1]+2) == *(*(a+1)+2 )== a[1][2]。
故 *(*(a+i))=*(*(&a[0]))=*(*(&*(a+i)))。
(1)定义
列指针:指向数组元素的指针变量。
如:int *p;
p=&a[0][0]或p=a[0]或p=*a;
则用p表示每个数组元素地址,方法为:p+i,表示距离a[0][0]第i个位置的元素的地址。
(2)应用
例1:
#include
int main()
{
int a[3][3]={1,2,3,4,5,6,7,8,9};
int *p,*q;
system("cls");
p=&a[0][0];/* p=a[0],p=*a也可以 */
q=&a[2][2];
for (;p<=q;p++)
{
printf("%d ",*p);
}
printf("\n");
return 0;
}
//执行输出:1 2 3 4 5 6 7 8 9
例2:
#include
int main()
{
int a[3][3]={1,2,3,4,5,6,7,8,9};
int *p;
//p=a;
//p=&a[0][0];
p=a[0];
for (;p<a[0]+9;p++)
{
printf("%x,%d\n",p,*p); //输出地址和元素值
}
return 0;
}
(1)定义
行指针:指向有m个元素组成的一维数组的指针变量。
格式:int (*p)[n];p=a;
含义:定义p是指向含有n个整形数据元素的一维数组的指针变量。即行指针。
如:int (*p)[4];
int a[3][4];
p=a;
p=a实现指向操作。行指针p是行地址性质的指针。此时,p+i=a+i,指向第 i行行首。
p+i表示第i行元素的地址等价于a+i;可以与二维数组用数组名表示的行地址互换使用。
p+i表示数组a的第i行的行地址。
*(p+i)相当于a[i],是指向第i行第0列的列地址。如*(p+2)相当于a[2]。
*(p+i)+j相当于a数组第i行第j列的列地址,如*(p+2)+1相当于&a[2][1]
a[2][1] == *(*(p+2)+1)
故当p是行指针时共有下面四种方法表达a[i][j]:
p[i][j]= * (*(p+ i)+j)= (*(p+ i))[j]= *(p[i]+j)=a[i][j];
例1:
#include
int main()
{
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int (*p)[4],i,j;
p=a;
scanf("%d%d",&i,&j);
printf("a[%d][%d]=%d\n",i,j,*(*(p+i)+j));
return 0;
}
//执行输出:1 2
// a[1][2]=13
例2:
#include
int main()
{
int a[3][3]={1,2,3,4,5,6,7,8,9};
int (*p)[3];
int i,j;
p=a;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
//printf("a[%d][%d]=%d\n",i,j,a[i][j]);
//printf("a[%d][%d]=%d\n",i,j,p[i][j]);
//printf("a[%d][%d]=%d\n",i,j,*(p[i]+j));
//printf("a[%d][%d]=%d\n",i,j,*(*(p+i)+j));
printf("a[%d][%d]=%d\n",i,j,(*(p+i))[j]);
}
}
printf("\n");
return 0;
}
//执行输出:1 2 3 4 5 6 7 8 9
一个数组,若其元素均为指针类型数据,称为指针数组,也就是说,指针数组中的每一个元素都相当于一个指针变量。
格式:类型名数组名[数组长度];
例如:
int *p[4]; p是一个具有4个元素的数组,每个元素都是一个能指向int型数据的指针变量。
注意:和 int (*p)[4]区别:p是一个指针变量,它能够指向一个具有4个元素的一维数组,也称数组指针。
例:
#include
int main()
{
char*weeks[]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
int i;
do
{
scanf("%d",&i);
}while(i<0||i>6);
printf("%s\n",weeks[i]);
return 0;
}
//执行输出:1
//Monday
(1)指针指向二维数组:数组指针(行指针)
#include
#include
int main()
{
int i=0,j=0;
int a[3][3]={1,2,3,4,5,6,7,8,9};
int (*p)[3]=a;//数组指针(行指针),3个指针相当于3*3二维数组
//一行是一个一维数组,3*3二维数组则是3个一维数组
//()优先级最高,p为一维指针,指向整型一维数组,数组长为3
printf("地址:%p\n",a);//数组首地址-->地址:0019FF1C
printf("地址:%p\n",a[0]);//第一个一维数组起始地址-->地址:0019FF1C
printf("地址:%p\n",&a[0]);//数组起始地址-->地址:0019FF1C
printf("地址:%p\n",&a[0][0]);//数组首元素地址-->地址:0019FF1C
printf("地址:%p\n",a[1]);//第二个一维数组起始地址-->地址:0019FF28
printf("地址:%p\n",&a[1]);//同上 相差&a[0] 12B
printf("地址:%p\n",&a[1][0]);
//第二个一维数组首元素地址-->地址:0019FF28
for(i=0;i<3;i++)//指针与二维数组应用,输出数组元素值
{
for(j=0;j<3;j++)
{
printf("%d",*(*(p+i)+j));//123456789
//p为地址->(p+i)为地址行偏移->*(p+i)->取值为行地址->*(p+i)+j->
//加该行上列地址偏移,生成总地址->*(*(p+i)+j)->对总地址取*,即该地址所指变量
//printf("%d",*(p[i]+j));//123456789
//printf("%d",*(&p[0][0]+i*3+j));//123456789
// printf("%d",(*(p+i))[j]);//123456789
}
}
printf("\n");
return 0;
}
(2)指针数组
#include
#include
int main()
{
int i=0;
char *name[3]={"admin","user","reader"};//定义并初始化指针数组
for(i=0;i<3;i++)
{
printf("%s\n",name[i]);//按下标法进行访问
}
//admin
//user
//reader
return 0;
}
//指针数组:数组里存放指针变量,它本身就是数组
比较:
int *s1[3], 则s1是具有三个整型指针元素的数组
(*s2)[3] , 则s2是指向具有三个元素的整型数组的指针
编辑 2020-07-03 23:58 首次编辑
增改 2021-07-10 18:27 内容结构优化
注:本文旨于作为自己的学习笔记,不作他用。