数组指针:
数组的指针,重点强调指针,指的是指向数组的指针,这个指针指向的是一个数组。
int (*p)[4];//声明了一个指针,该指针指向一个有4个int型元素的数组
示例
#include<stdio.h>
int main(){
int b[8]={1,2,3,4,5,6,7,8};
int (*p)[4];
p=b;
printf("%d\n",**(++p));
return 0;
}
示例解读:p是定义的一个数组指针,它指向了一个包含有4个int型元素的数组,被初始化为指向数组b首地址,++p是把p所指向的地址向后移动4个int 型数据所占空间,此时++p指向数组{5,6,7,8},*(++p)表示指向元素{5,6,7,8},**(++p)表示第一个元素,即程序会输出5。
指针数组:
指针的数组,重点强调数组,指针数组表示定义了一个数组,而数组中的元素是指针。
int *p[4];//声明了一个指针数组,数组中存放的是4个指向int的指针
示例
#include<stdio.h>
int main(){
int i;
int *p[4];
int b[4]={1,2,3,4};
p[0]=&b[0];
p[1]=&b[1];
p[2]=&b[2];
p[3]=&b[3];
for(i=0;i<4;i++){
printf("%d ",*p[i]);
}
return 0;
}
输出结果:1 2 3 4
函数指针:
如果我们在程序中定义了一个函数,在编译时就会为该函数分配一段存储空间,这段存储空间的首地址称为这个函数的地址。函数名表示的就是这个地址,我们就可以定义一个指针变量来存放该地址,这个指针变量就叫函数指针变量,简称函数指针。
int(*p)(int,int);//定义了一个指针变量p,该指针变量可以指向有两个int型参数,返回值为int型的函数
示例
#include<stdio.h>
int Max(int,int);//函数声明
int main(){
int(*p)(int,int);//定义一个函数指针
int a,b,c;
p=Max; //把函数Max赋给指针变量p,p指向Max函数
printf("请输入a和b:\n") ;
scanf("%d%d",&a,&b);
c=(*p)(a,b);//通过函数指针调用Max函数
printf("a=%d\nb=%d\nmax=%d\n",a,b,c);
return 0;
}
int Max(int x,int y){
int z;
if(x>y){
z=x;
}
else{
z=y;
}
return z;
}
注意:指向函数的指针变量没有++和–运算。
指针函数:
指针函数重点强调它是一个函数,只不过这个函数的返回值是一个地址值,函数的返回值必须用同类型的指针变量来接收,也就是说指针函数一定有返回值。
int *pfun(int,int);//pfun为一个返回值为整型指针的函数
//*的优先级低于(),所以pfun首先和后面的()结合,也就是说pfun是一个函数
//然后再和*结合,说明这个函数的返回值是一个指针,因为前面还有int,所以
//说pfun为一个返回值为整型指针的函数
数组名和指针的区别
1.数据保存
指针保存的是地址(保存目标数据的地址,自身地址由编译器分配),内存访问偏移量为4个字节。
数组保存的数据,数组名表示第一个元素的地址,内存偏移量是保存数据类型的内存偏移量;只有对数组名取地址(&数组名)时数组名才表示整个数组,内存偏移量是整个数组的大小(sizeof(数组名))。
2.数据访问
指针对数据的访问方式是间接访问,需要用到解引用符号(*指针变量名)。
数组对数据的访问是直接访问,可以通过下标或数组名+元素偏移量的方式。
3.使用环境
指针多用于动态数据结构(如链表)和开辟动态内存。
数组多用于存储固定个数和类型统一的数据结构(如线性表)和隐式分配。