C语言函数指针数组

C语言 函数指针数组

——————————————————————————————————————————————————————————————————————————————————————————————————————————————

函数指针数组的字面意思:

函数 指针 数组

首先 ,他是一个数组,数组的每个元素是函数指针。

他也就是 一群 函数指针的集合。也就是一个数组,用来存放指针,每个指针指向一个函数。

那么剖析下面的概念:

  1. 指针
  2. 指针数组
  3. 函数指针
  4. 函数指针数组

——————————————————————————————————————————————————————————————————————————————————————————————————————————————

1. 指针

指针 :存放地址的变量。指针指向的是地址,,,,巴拉巴拉一堆东西!!!!
使用 int 类型的变量进行举例子 :

 int main()
{
	int int_P = 10;
	int *P = NULL;
	
	printf("int_P = %d	", int_P);
	printf("int_P 存放的地址=%p	", &int_P);
	printf("int_P 的大小=%d\r\n", sizeof(int_P));
	
	P = &int_P;
	printf("*P = %d	", *P);
	printf("P = %X	", P);
	printf("P 存放的地址=%p	", &P);
	printf("P 的大小=%d\r\n", sizeof(P));
}

C语言函数指针数组_第1张图片

综上是可以看到的一些信息:
指针P 指向int类型的变量 int_P ;

指针变量本身的地址是 :0X0093F7C4 。指针变量的地址里面存储的是他指向的变量的地址 0X0093F7D0。

1.1指针的创建和声明

指针变量的创建:

指针类型* 指针名 = &变量

例如上附代码中的:

int int_P =10 ;
int*P =NULL;
P = &int_P ;

这是一种方法,这种方式我更加的喜欢。(我也不知道为啥)还可以使用下述的更加直接的方式:

int int_P =10 ;
int*P =&int_P;

p表示指针的名字,* 与p结合,表示这是一个指针变量,int是存放变量地址的类型。

我们将int_P 的地址存放到p中,就可以通过p来找到int_P 当中的内容。
p是一个指针变量,他里面存的是地址,通过地址来访问int_P 存储的数据,需要用到 * 号,
"*"表示解引用
*p解引用就可以找到int_P 中存储的数据,而p本身存储的是地址,所以上图显示将p以地址的形式打印出来,
显示的是a在内存中的地址。

2. 指针数组

中国人讲话很含蓄,不过关于软件方面的翻译工作做的还是很直白的,毕竟我们是新生代农民工啊!

指针数组,就是 一堆指针组成的组合。


int main()
{
	int Num1 = 10;
	int Num2 = 15;
	int Num3 = 20;
	int Num4 = 25;
	int *P[4] = {NULL};
	P[0] = &Num1;
	P[1] = &Num2;
	P[2] = &Num3;
	P[3] = &Num4;

	printf("Num1 =%d Num1的地址是:%p\r\n", Num1,&Num1);
	printf("Num2 =%d Num2的地址是:%p\r\n", Num2, &Num2);
	printf("Num3 =%d Num3的地址是:%p\r\n", Num3, &Num3);
	printf("Num4 =%d Num4的地址是:%p\r\n", Num4, &Num4);

	printf("P的地址是 :%p , P存放的地址 :%X\r\n", &P,P);
	printf("P[0]的地址是 :%p , P[0]存放的地址 :%X  *P[0] = %d\r\n", &P[0], P[0], *P[0]);
	printf("P[1]的地址是 :%p , P[1]存放的地址 :%X  *P[1] = %d\r\n", &P[1], P[1], *P[1]);
	printf("P[2]的地址是 :%p , P[2]存放的地址 :%X  *P[2] = %d\r\n", &P[2], P[2], *P[2]);
	printf("P[3]的地址是 :%p , P[3]存放的地址 :%X  *P[3] = %d\r\n", &P[3], P[3], *P[3]);
}

C语言函数指针数组_第2张图片

C语言函数指针数组_第3张图片

2.1 指针数组的创建和声明

这个是完全的非常的清晰的:

指针类型* 指针名[个数] ={ &变量,&变量,&变量 。。。 };

或者使用我上述的方式:
指针类型 * 指针名[个数] = {NULL};
我个人是非常的倾向于这样的创建方式的。
整型变量,指针变量,在创建的时候全部都是空,是0,或者是NULL 。想要赋值,你去函数里面赋值去,或者你去其他地方赋值去。反正就别在我创建变量的地方进行赋值。

3. 函数指针

函数指针,和上面来讲 应该是一脉相承的,指针结尾,那么说破天他也是个指针。
字面上理解,就是存放函数的指针。

指针可以存放的只有地址啊???
那么为啥可以存放函数呢???好神奇??

因为函数 有一个神奇的名字,叫做 函数入口地址,这个函数入口地址,不管你的函数名命名的有多长,他都是4个字节,刚好可以存放在指针里面。就这!!!

C语言的精髓啊!!!

3.1函数指针的创建方式:

他的模板是这样的:

返回值 (*指针名)(数据类型,数据类型)

举例子:

int*P)(int ,int) ; 

当然这个是非常灵活的:

void*P)(void); //这样的也是非常可以的。

注意点:

int (*P)(int ,int );

绝对是不可以写成 :

int * P (int ,int) ;
因为上面中小括号的优先级比较高。写成上面的 int(*P) ,这个是函数指针。
int * P ();这个是返回int *类型的函数。

下面举个大一点的例子:

int ADD(int Num1, int Num2)
{
	printf("传进来的 Num1 =%d ,Num2 =%d\r\n", Num1, Num2);
	return Num1 + Num2;
}

int(*P)(int, int);

int main()
{
	// P = &ADD;
	P = ADD;
	printf("%d\r\n" , P(2,3));
}

C语言函数指针数组_第4张图片

P中存放的是函数Add的地址,而函数名就是函数的入口地址。
我们使用Add函数的时候语法规范是这样的 Add(x,y);
直接调用这个函数就可以了!

那么既然函数名就是地址,而p中存放的是Add函数的地址,
所以p就代表了Add,所以我们可以将p看成Add,p(x,y)同样可以做到Add(x,y)的效果,
这两者在使用的时候没有任何差异。

4. 函数指针数组

好了,,到最后了 函数指针数组这缝合怪!!!

那么明确一点他是啥 , 数组,,,他必须是数组。

他是啥组成的数组???
函数指针组成的!!!

那么想一下,函数指针怎么写?

void(*P)(void);

想想怎么加上数组???

void(*P)(void)[];   ??? 
 void(*P)[](void); ???
void (*P[])(void);

不用想了上面的带问号的是不对的!!!
按我的想法!!!肯定是第一种啊!!
但是就是第三种!!!!

#include 

void test_01(){
	printf("This is test01\r\n");
}
void test_02() {
	printf("This is test02\r\n");
}
void test_03() {
	printf("This is test03\r\n");
}
int (*taskDriveFuncTable[3] ) (void) =
{
	test_01,
	test_01,
	test_03
};
int main()
{
	taskDriveFuncTable[0]();
	taskDriveFuncTable[1]();
	taskDriveFuncTable[2]();
}

C语言函数指针数组_第5张图片
C语言函数指针数组_第6张图片
没办法的啊!!!
人家就是这样的写的

int(*P[])(void);

这个顺序不可以乱!!!

下面借鉴一下别人的博客!

C语言函数指针数组_第7张图片
安静的看这段代码,使用了大量的 if else

C语言函数指针数组_第8张图片但是这一段代码就显得比较精简了!!!

可以看到,改造后的代码摒弃了switch语句,采用的是if判断,
一些繁琐的输出语句和选择也全部被优化掉,而今后不论是添加函数功能,还是删除,
只需要修改数组大小,删除数组元素即可,大大简化了代码,变得更好维护。

让我们来仔细分析一下改造后的代码:

先从函数指针数组开始分析,
函数指针数组的创建 返回值(*数组名[元素个数])(数据类型,数据类型)
例如 int (*p[4])(int ,int)
首先这是一个数组,所以p要和[]先结合,我们拿掉数组名后剩下的就是数组的元素类型

也就是: int (*)(int int) 函数指针

上面我们讲过,函数指针数组就是用来存放函数指针的,而函数指针存放的地址就是函数名,函数指针和函数的使用方法上除了名字没有区别,所以既然函数指针存放的是函数名,函数名就是函数地址,我们直接就将函数名(地址)存入数组中。

然后进入while循环,打印菜单,提示用户输入,进入if判断,0则退出。

我们用i来存储用户选择的功能,然后用i作为函数指针数组的下标,通过下标来访问数组的元素

比如arr[0],而数组的元素是函数指针,也就是函数的地址,我们知道函数名就是函数的地址,我们在初始化数组的时候,放入的就是函数名(函数的地址),所我们可以直接用数组的下标来使用函数:arri - 1。以此类推,如果用户输入的是1,2,3,4,我们就使用函数来实现算术功能,输入其他的数则继续循环,回到选择功能。输入0 ,break跳出循环,结束程序。

以上就是函数指针数组的详解,欢迎大家评论与指点!!!————————————————
版权声明:本文为CSDN博主「莱科宁是冠军」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Raikkonen_love/article/details/126483563

——————————————————————————————————————————————————————————————————————————————————————————————————

综上所有的想写的,已经写完了。

写一点自己的想法吧,多看多读多谢 代码这样的东西吧!!!

操千曲而后晓声,观千剑而后识器。——《文心雕龙·知音》

这东西 ,你要多想 ,你更要吃过见过!!!

你可能感兴趣的:(#,1.1-C语言,c语言,c++,算法)