详解指针数组、数组指针、函数指针

目录

指针数组

数组指针

函数指针

总结


指针数组

首先要明确指针数组是数组而不是指针,是一个存放指针的数组。

数组里面存放的都是地址

声明一个指针数组的方式是

int* arr1[5]; //整形指针的数组
char* arr2[4]; //一级字符指针的数组
char** arr3[5];//二级字符指针的数组

int* arr1[5]表明arr1这个数组里面存的成员是int*类型的,最多可以存放5个int*类型的指针,所以他是一个存放整型指针的数组。

 

 举一些例子:

int main()
{
	int a = 10, b = 20, c = 30;
	int* arr1[3] = { &a,&b,&c };

	char str1[] = "abc", str2[] = "bcd", str3[] = "cde";
	char* arr2[] = { str1,str2,str3 };

	printf("%p %p %p\n", arr1[0], arr1[1], arr1[2]);
	printf("%d %d %d\n", *arr1[0], *arr1[1], *arr1[2]);
	printf("%p %p %p\n", arr2[0], arr2[1], arr2[2]);
	printf("%s %s %s\n", arr2[0], arr2[1], arr2[2]);
	return 0;
}


数组指针

和指针数组相反,数组指针不是数组,而是一个指向数组的指针。

int (*p)[10]; *先和p结合,说明p是一个指针变量,然后指向一个大小为10的数组,该数组成员的类型为int类型。int *p[10],[]的优先级大于*,所以要保证*首先和p结合,就得加上括号,否则就成为了一个指针数组。

	int arr[] = { 1,2,3 };
	int(*p)[3] = &arr;

在此之前有必要说明一下是arr与&arr的区别

arr是数组中首元素地址,&arr是整个数组的地址,他两的值相同,但是表达的意思天差地别  

arr+1是下一个元素的地址;&arr+1直接跨过整个数组,是数组最后一个元素下一个空间的地址。

上面代码的意思(*p)说明p是指针,这个指针指向数组arr有3个元素。int代表指向元素的类型是

整型。

int* arr[3] = { 0 };
int* (*p)[3] = &arr;

同理,这段代码,(*p)说明p是指针,[3]说明指向的数组的元素总共3个,int* 说明的是指向每个元素的类型。

数组指针如何用

int main()
{
	int arr[] = { 1,2,3 };
	int(*p)[3] = &arr;
	for (int i = 0; i < 3; i++)
	{
		printf("%d ", (*p)[i]);
	}
	return 0;
}

其实*p==arr,输出还可以这样写 *(*p+i)也是对的。

一般在二维数组中用的多

例如int arr[3][3]={{1,2,3},{2,3,4},{3,4,5}};arr是首元素地址,此地址也是第一行的地址,也就是说*(arr+1)并不是arr[0][1],而是arr[1][0],arr+1横跨第一行,是第二行的地址

所以二维数组任意一个元素可以表示成( *(arr+i) )[ j ]或者*(*(arr+i)+j)。

所以在函数传参的时候,当需要将二维数组作为形参时,可以传递数组指针void fuc(int (*p)[3]);

为了加深理解,可以看一下这几个例子

	int arr[5];
	int *parr1[10];
	int(*parr2)[10];
	int(*parr3[10])[5];

第一个为简单的数组,里面元素类型为int;

第二个为指针数组,元素类型为int*;

第三个数组指针,指向的数组空间大小为10个int类型;

第四个从里往外理解,首先parr3和[ ]结合,说明是一个数组大小为10个元素,每个元素类型为指针;这个数组里面的指针又和[5]结合,说明数组里面每个指针都指向含有5个int类型成员的数组。 


函数指针

任何一个函数int fuc(int x, int y){};都有他自己的地址。fuc或者&fuc就是他的地址。

如何定义一个函数指针

int (*pa)(int, int)=fuc;

第一个int为函数的返回值,括号里面的int为函数形参的类型。

(*pa)(x, y);或者pa(x, y);都可以调用函数。但是*pa(x, y);是错误的方式,注意符号优先级。

如何理解(*(void(* )( ))0)( );

(void(* )( ))是一个函数指针类型,将0强制类型转换为函数指针,也就是把0作为函数的地址,通过*解引用调用0地址处的该函数

如何理解void(*signal(int, void(*)(int)))(int);

首先它是由两部分组成void(*  )(int)和signal(int, void(*)(int)),后者是函数,前者是指针类型,组合起来signal函数的返回值为函数指针,他的形参一个为int,一个为函数指针

前面讲过指针数组,数组指针,那么函数同样有自己的函数指针数组指向函数指针数组的指针

函数指针数组

存函数地址的数组

定义

int (*arr[5])(int, int)={  }; 前提是这几个函数的类型都一样

用途:转移表,可以将相同类型的函数合在一起,减少代码的冗余度和可读性

指向函数指针数组的指针

定义

int(*(*parr)[5])(int, int);

parr一个数组指针,指针指向的数组有5个元素,每个元素的类型是一个函数指针


总结

这一部分的东西有一点绕,得自己去敲代码调试加以理解效果更好。

  • 33
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
C语言中的指针函数是指返回值为指针类型的函数,它们在函数的定义和调用上与普通函数有所不同。 指针函数的定义需要在函数名前加上返回类型为指针的声明,并在函数体内返回一个指针类型的值。例如,我们可以定义一个返回整型指针的函数如下: ```c int* allocateIntArray(int size) { int* array = (int*)malloc(size * sizeof(int)); return array; } ``` 在调用指针函数时,需要用一个与返回类型相匹配的指针变量接收返回值。例如,调用上述函数并将返回值存储在指针变量中: ```c int* myArray = allocateIntArray(5); ``` 上述代码中,myArray是一个整型指针变量,它用于存储allocateIntArray函数的返回值。这个返回值是一个指向分配的整型数组指针指针函数的调用过程中,我们还需要注意以下几点: 1. 为了避免内存泄漏,我们通常需要在不使用指针的时候手动释放内存,可以使用free函数来释放通过malloc分配的内存。 2. 在函数内部分配的内存空间返回给调用者后,我们应该确保在使用这块内存之前不会被其他操作修改或释放掉,否则可能导致程序运行时错误。 3. 指针函数也可以作为参数传递给其他函数,使得我们可以更方便地使用和操作指针类型的数据。 总结来说,指针函数是具有返回值为指针类型的函数,其定义和调用方式与普通函数有所区别。使用指针函数可以更灵活地操作和传递指针类型的数据,但在使用时需要注意内存的释放和确保指针的有效性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值