C语言中规定数组名是指针类型的符号常量, 该符号常量值等于数组首元素的地址 ( 简称数组首地址) ,它的类型是指向数组元素的指针类型。即数组名是指向该数组首元素的指针常量。
指向数组元素的指针
定义指向数组元素的指针变量:
int a[10];
int *p;
p=&a[0];
由于数组名是指向0号元素的指针类型符号常量, 所以a与&a[0]相等。
p=&a[0]; 与 p=a; 等价
注意:
①p=a不是把a的各元素赋给p
②注意数组名与指针变量的区别
(一)通过指针引用数组元素
在 int a[10],*p=a; 定义的情况下:
(1) p+i或a+i就是a[i]的地址。都要进行a+i×d的运算。
(2) *(p+i)或*(a+i)就是p+i或a+i所指向的数组元素a[i]。数组元素中的“[ ]”是变址运算符, 相当于*( + ) , a[i]相当于*(a+i)。
(3) 指向数组元素的指针变量也可带下标, 如 p[i]与*(p+i)等价。所以, a[i],*(a+i),p[i],*(p+i) 四种表示法全部等价。
(4) 注意p与a的差别,p是变量a是符号常量,不能给a赋值, 语句a=p; a++;都是错的。
引用数组元素可用:
1)下标法,如a[i],p[i]。
2) 指针法,如*(p+i)或*(a+i),其中p是指向数组a的元素的指针变量。

(二)例.输入/输出数组全部元素
#include<stdio.h>
int main( )
{ int a[10];
int *p,i;
for(p=a;p<(a+10);p++)
scanf("%d", p); //输入
printf("\n");
//输出
① for(i=0;i<10;i++)
printf("%d", a[i]);
② for(i=0;i<10;i++)
printf("%d", *(a+i));
③ p=a; /*不能省略*/
for(i=0;i<10;i++,p++)
printf("%d", *p);
④for(p=a;p<(a+10);p++)
printf("%d",*p);
return0;
}
数组或指针变量作函数参数
程序举例:
#include<stdio.h>
//数组作形参
void add(int a[],int n)
{
inti;
for(i=0;i<n;i++)
a[i]=a[i]+10;
}
//指针作形参
void add(int *p,int n)
{
int*p1=p+n;
for(;p<p1;p++)
*p=*p+10;
}
int main()
{
inta[5]={1,2,3,4,5};
inti;
int*p=a;
//数组名作实参
add(a,5);
//指针作实参
add(p,5);
for(i=0;i<5;i++)
printf("%d",a[i]);
}
如果有一个数组,想在被调用的函数中改变其元素的值,实参与形参的对应关系有以下四种:
(1).实参和形参都用数组名。
(2).实参用数组名, 形参用指针变量。
(3).实参用指针变量, 形参用数组名。
(4).实参和形参都用指针变量。
实质都是地址值的传递
【二级真题】对于函数声明 void fun(float array[], int *ptr); 以下叙述正确的是()。
A) 函数fun的参数array, ptr都是指针变量
B) 函数fun的参数array 是数组名,ptr是指针变量,它们有本质区别
C) 调用函数fun时,实参数组元素个数可以比形参array数组元素个数多
D) 调用函数fun时,传送给形参array的应是数组的所有元素
答案:A
(一)二维数组与指针
以a[2][3]为例
a→a[0]→a[0][0] *a=a[0]
a[0]+1→a[0][1]
a[0]+2→a[0][2]
a+1→a[1]→a[1][0] *(a+1)=a[1]
a[1]+1→a[1][1]
a[1]+2→a[1][2]
*(a+0)+1→a[0][1]
*(a+0)+2→a[0][2]
*(a+1)+1→a[1][1]
a[i]+j→a[i][j]
*(a+i)+j→a[i][j]
*(a[i]+j)=*( *(a+i)+j)=a[i][j]
(二)多维数组的指针变量
以二维数组为例,设二维数组a有3行4列。int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
a是数组名, a数组有3行, 即3个分数组:a[0],a[1],a[2]。
每个分数组又是含4个列元素的一维数组。
(1)指向二维数组的指针变量
若有以下定义语句:
int a[3][4],*p=a;
数组名a加1时,地址下移一行;指针变量p加1时,地址指针下移一个元素。
(2)指向分数组的指针(本质为指针)
定义形式: 数据类型 (*指针名)[一维数组维数];
int (*p)[4];
表示P是一个指针变量,指向包含4个元素的整型一维数组
注意:一维数组指针变量维数和二维数组列数必须相同。
int a[3][4];
int (*p)[4]=a;

(三)用多维数组名和指针变量作函数参数
(1) 参数为行列数全部说明的二维整型数组形式
int fun(int x[3][4])
{
……
}
其中,形参数组x的行和列的数量都是确定的。
(2) 参数为省略行数的二维整型数组形式
int fun(int x[][4])
{
……
}
其中,形参数组x的列的数量是确定的,但行的数量是不确定的。
(3) 参数为行列数全部说明的二维整型数组形式
int fun(int (*x)[4])
{
……
}
其中(*x)[4]的含义是:x是一个指向有四个元素的一维数组的指针,x加1时,地址移动4个元素。
(四)指针数组(本质为数组)
每个数组元素均为指针类型的变量,即数组元素的类型是指针类型,则称这样的数组为指针数组。
定义格式:基类型名 *数组名[ 数组长度 ]
int *p[4]; // p是数组名,数组元素为指针
通常用来指向若干个字符串

main()
{ char a[]="Program";
char b[]="Fortran";
char c[]="Basic";
char *p[4];
p[0]=a; p[1]=b;p[2]=c;p[3]=NULL;
}
或:
main()
{ char *p[4];
p[0]="Program";
p[1]="Fortran";
p[2]="Basic";
p[3]=NULL;
}
初始化:
main()
{ char *p[]={"Program", "Fortran", "Basic",NULL};
}

