(1)指针与二维数组
一个数组的名字代表该数组的的首地址,是地址常量(作为形式参数的数组名除外),这一规定对二维数组或更高维数组同样适用。
在c语言中定义的任何一个二维数组实际上都可以看做是一个一维数组,该一维数组中的每一个成员又是一个一维数组。
若有定义int d[3][4],i,j;且0<=i<=2,0<=j<=3;
1.数组元素d[i][j]的表示方法为:
d[i][j]
*(d[i]+j)
*(*(d+i)+j)
(*(d+i))[j]
*(&d[0][0]+4*i*j)
*(d[0]+4*i+j)
2.数组元素d[i][j]地址的表示方法为:
&d[i][j]
d[i]+j
*(d+i)+j
&((*(d+i))[j])
&d[0][0]+4*i*j
d[0]+4*i*j
例如:设数组d的首地址是无符号十进制整数40000,则各表示形式、含义与地址的关系如下所示。其中地址值增减变化随程序运行环境的不同而不同
二维数组d各表示形式、含义与地址的关系
d 二维数组名,数组首地址,第0行首地址 40000 d[0],*(d+0),*d 第0行第0列元素d[0][0]的地址 40000 d+1 第1行首地址 40008 d[1],*(d+1) 第1行第0列元素d[1][0]的地址 40008 d[1]+2,*d[+1]+2,&d[1][2] 第1行第2列元素d[1][2]地址 40012
二维数组名d是指向行的,例如d+2表示二维数组d第2行的首地址;一维数组名d[0],d[1],d[2]是指向各自对应的列元素的,例如d[0]+2表示元素d[0]+2表示元素d[0][2]的地址。*d与*(d+1)都不代表任何数组元素。
例子:将a矩阵与b矩阵相加,所得之和存入c矩阵中。a,b,c矩阵都是3*4的矩阵
#include<stdio.h> #include<stdlib.h> #include<time.h> int i,j; void maxtrix(int *x,int *y,int *z){ for(i=0;i<3;i++){ for(j=0;j<4;j++){ *(z+i*4+j)=*(x+i*4+j)+*(y+i*4+j); } } } int main(){ srand((int)time(NULL)); int (*p)[3][4],a[3][4],b[3][4],c[3][4]; printf("The value of a: "); for(i=0;i<3;i++){ for(j=0;j<4;j++){ *(a[i]+j)=(int)rand%1000; } } printf("the value of b: "); for(i=0;i<3;i++){ for(j=0;j<4;j++){ *(*(b+i)+j)=(int)rand%1000; } maxtrix(*a,b[0],&c[0][0]); } printf("The value of c:"); printf("%d",a[2][1]); return 0; }
这个程序运行时会出现错误,以后再讨论。
3.指针数组
如果一个数组的元素都是指针变量,则称这个数组是指针数组。
指针数组定义的一般形式:
类型说明符 *数组名[]......
4.指针与字符串数组
字符数组中每个元素都是一个字符,而字符串数组中指的是数组中的每个成员都是存放字符串的数组。
1)直接给字符串数组赋初值
char b[4][8]={"Turbo C","FORTRAN","BASIC","Foxpro"};
char b[][8]={"Turbo C","FORTRAN","BASIC","Foxpro"};
2)用给字符型指针数组赋初值的方式构成字符串数组
char *f[4]={"Turbo C","FORTRAN","BASIC","Foxpro"};
char *f[]={"Turbo C","FORTRAN","BASIC","Foxpro"};
实例:利用数字月份查找其英文月份名:
1 #include<stdio.h> 2 3 char *month_name(int n){ 4 char *name[]={ 5 "Illegal month", 6 "January","February","March", 7 "April","May","June","July", 8 "August","September","October", 9 "November","December"}; 10 return (n<1|n>12)?name[0]:name[n]; 11 } 12 13 int main(){ 14 int n; 15 scanf("%d",&n); 16 printf("%d month name is %s ",n,month_name(n)); 17 return 0; 18 }
5.指向数组的指针变量
指向数组的指针变量定义的一般形式:
类型说明符 (*变量名)[正整型常量表达式];
功能:定义一个名为"变量名"的指针变量,该指针变量所指向的是一个具有"正整型常量表达式"个元素的一维数组,该数组的每个元素都是"类型说明符"类型的。
例如:int (*p)[10],定义p是一个指针变量,它所指向的对象是一个具有10个元素的数组int型数组。
这种形式定义的指针一般用于指向二维的数组。
例如:int d[3][2],(*p)[2];p=d;
p=d;//p指向第0行,即指向整个数组d[0][0],d[0][1],d[0][2]......;
p++;//p指向第1行,即指向整个数组d[1][0],d[1][1],d[1][2]......;
(2) 二级指针
如果一个变量的值是其他变量的地址,而这些其他变量的值不再是内存地址,则这个变量是一级指针变量;
如果一个变量的值是一级指针的地址,则称这个变量是二级指针变量。
定义方法:
类型说明符 **标识符
int b,*m,**p;
m=&b;
p=&m;
实例1:二级指针输出整型数据:
1 #include<stdio.h> 2 3 void swap(int **m,int **n){ 4 int *i; 5 i=*m; 6 *m=*n; 7 *n=i; 8 } 9 int main(){ 10 int a,b,*pa,*pb; 11 pa=&a; 12 pb=&b; 13 scanf("a=%d,b=%d",pa,pb); 14 swap(&pa,&pb); 15 printf("pa=%d,pb=%d ",*pa,*pb); 16 printf("a=%d,b=%d",a,b); 17 return 0; 18 }
这里输入时要注意一个问题,就是输入时,要满足scanf语句中的格式,必须进行格式的完全匹配。
实例2:二级指针输出字符串型数据
1 #include<stdio.h> 2 3 int main(){ 4 char **p,*address[]={ 5 "China","Japan","English","" 6 }; 7 p=address; 8 for(;**p!='