​ ​

入门视角:函数指针,指针函数等指针类型的区分

正文

一、指针函数

定义:是一个返回指针的函数,其本质是一个函数,而该函数的返回值是一个指针。
声明格式:*类型标识符 函数名(参数表)
例如:int *strcpy(char *s1,char *s2);//将s2指向的字符串复制到s1中

int *strcpy(char *s1,char *s2){
	char *tmp=s1;
	while(*s2){
		*s1=*s2;
		s1++;
		s2++;
	}	
	return tmp;
} 

注意:在调用指针函数时,需要一个同类型的指针来接收其函数的返回值(如代码中的*tmp)。

int main(void){
char a[]="abc";
char b[128];
printf("%s",strcpy(b,a));
return 0;//结果为输出"abc"
}

二、函数指针

定义其本质是一个指针变量,该指针指向这个函数。总结来说,函数指针就是指向函数的指针。
声明格式:类型说明符 (*函数名) (参数)
例如int (*fun)(int x,int y);

int add(int x,int y){
	return x+y;
}
int (*fun)(int x,int y);

int main(void){
int result;
fun=&add;
result=(*fun)(2,2);
printf("%d",result);//结果为4	
}

注意
函数指针是需要把一个函数的地址赋值给它。fun=&add;
调用函数指针的方式:result=(*fun)();

三、数组指针

定义:数组指针(也称行指针),这种声明表示它是一个指针
声明格式int (*p)[n];
()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n。
例如

int main(void){
int arr[2][3]={{1,2,3},{4,5,6}};
int (*p)[3];
p=arr;
printf("%d",*p[0]);//结果输出1
printf("%d",*p[1]);//结果输出4
}
int main(void){
int arr[2][3]={{1,2,3},{4,5,6}};
int (*p)[2];
p=arr;
printf("%d",*p[0]);//结果输出1
printf("%d",*p[1]);//结果输出3

可以看出,这个一维数组的长度定义不同2或3,也可以说是p的步长。执行时p[0]和p[1]时,p要跨过2或3个整型数据的长度。而导致输出结果不同。

四、指针数组

定义:指针数组,其实质相当于声明了一个数组,数组内的每一个元素均为一个指针。
声明格式int *p[n];
[ ]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。
例如

int main(void){
	char *month[]={
	"january","february","march",
	"april","may","june","july"};
	printf("%s\n",month[0]);
}
int main()
{
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int *p[3]={a[0],a[1], a[2]};//p[0],p[1],p[2]都是属于指针
p={a[0],a[1], a[2], a[3]};
printf("%d\n%d\n%d\n%d\n",*(*(p + 1) + 3),*(p[1]+3),(*(p+1))[3],p[1][3]);
//输出结果都为8
return 0;
}

注意
我之前这样写在*p[3]中放入数组{1,2,3},这是错误的,无法输出结果,原因是指针要传入地址,p[1]是一个指针不能直接输入1!

int main()
{
//int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int *p[3]={0,1,2};
//int i=0;
//p={a[0],a[1], a[2], a[3]};
printf("%d\n",*(*(p + 1) + 3));
return 0;
}

总之,数组指针只是一个指针变量,似乎是C语言里专门用来指向二维数组的,它占有内存中一个指针的存储空间。指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。

五、指向指针的指针

定义:如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。
声明格式char **p;
例如

int main(){
int a[5]={1,3,5,7,9};
int *num[5]={&a[0],&a[1],&a[2],&a[3],&a[4]};//指针数组存放数组a地址
int **p,i,**t;
p=num;//数组a的地址存放在指向指针的指针变量p的地址上
for(i=0;i<5;i++)
{
 printf("%d\t",**p);p++;
}//**p要双重解引用,才能读取最上面的值
return 0;
}

与二维数组的对比↓结果都为1,3,5,7,9

int main(){
int b[][1]={1,3,5,7,9};
int *num2[5]={b[0],b[1],b[2],b[3],b[4]};
int **p,i,**t;
t=num2;
for(i=0;i<5;i++)
{
 printf("%d\t",**t);t++;
}
return 0;
}

对于什么时候用“指针”还是“指向指针的指针”,要根据情况而定。

六、补充

多维数组的表示
以二维数组为例:

上述内容如有不对请指正,附上相关文章
文章一
文章二
文章三
文章四

posted @ 2020-03-12 22:24  Adeleeeeee  阅读(424)  评论(0)    收藏  举报