一、指向一维数组的指针常用运算
已知:一维数组:a[i]={0,1,2,3,4,…,i};*p=a;
故:a[i]=*(a+i)=p[i]=*(p+i)=*p++
二、二维数组中的行地址和列地址
1、列地址
(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 <stdio.h>
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));
}
printf("\na[1][2]=%d",a[1][2]);
printf("\na[1][2]=%d",*(a[0]+5));
printf("\na[1][2]=%d",*(a[1]+2));
printf("\n");
return 0;
}
结论:按列地址输出,可采用以上不同方式输出,效果一致。 列地址使用列指针来指向(指向数组元素的指针),赋值方法是: p=a[0]、p=&a[0][0]、p=*a
2、行地址
(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、元素
(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)))。
2、列指针(赋予列地址)
(1)定义 列指针:指向数组元素的指针变量。
如:int *p;
p=&a[0][0]或p=a[0]或p=*a;
则用p表示每个数组元素地址,方法为:p+i,表示距离a[0][0]第i个位置的元素的地址。 (2)应用 例1:
#include <stdio.h>
int main()
{
int a[3][3]={1,2,3,4,5,6,7,8,9};
int *p,*q;
system("cls");
p=&a[0][0];
q=&a[2][2];
for (;p<=q;p++)
{
printf("%d ",*p);
}
printf("\n");
return 0;
}
例2:
#include <stdio.h>
int main()
{
int a[3][3]={1,2,3,4,5,6,7,8,9};
int *p;
p=a[0];
for (;p<a[0]+9;p++)
{
printf("%x,%d\n",p,*p);
}
return 0;
}
3、行指针(赋予行地址)
(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 <stdio.h>
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;
}
例2:
#include <stdio.h>
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,(*(p+i))[j]);
}
}
printf("\n");
return 0;
}
四、指针数组
1、概念
一个数组,若其元素均为指针类型数据,称为指针数组,也就是说,指针数组中的每一个元素都相当于一个指针变量。 格式:类型名数组名[数组长度]; 例如: int *p[4]; p是一个具有4个元素的数组,每个元素都是一个能指向int型数据的指针变量。 注意:和 int (*p)[4]区别:p是一个指针变量,它能够指向一个具有4个元素的一维数组,也称数组指针。
2、指针数组应用
例:
#include <stdio.h>
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;
}
3、数组指针(行指针)和指针数组的比较
(1)指针指向二维数组:数组指针(行指针)
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i=0,j=0;
int a[3][3]={1,2,3,4,5,6,7,8,9};
int (*p)[3]=a;
printf("地址:%p\n",a);
printf("地址:%p\n",a[0]);
printf("地址:%p\n",&a[0]);
printf("地址:%p\n",&a[0][0]);
printf("地址:%p\n",a[1]);
printf("地址:%p\n",&a[1]);
printf("地址:%p\n",&a[1][0]);
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
printf("%d",*(*(p+i)+j));
}
}
printf("\n");
return 0;
}
(2)指针数组
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i=0;
char *name[3]={"admin","user","reader"};
for(i=0;i<3;i++)
{
printf("%s\n",name[i]);
}
return 0;
}
比较: int *s1[3], 则s1是具有三个整型指针元素的数组 (*s2)[3] , 则s2是指向具有三个元素的整型数组的指针
编辑 2020-07-03 23:58 首次编辑 增改 2021-07-10 18:27 内容结构优化
注:本文旨于作为自己的学习笔记,不作他用。
|