指向函数的指针(续) C语言

欢迎访问我的新博客:http://www.milkcu.com/blog/

原文地址:http://www.milkcu.com/blog/archives/1370905680.html

标题:指向函数的指针(续) - C语言

内容:前面写过《指向函数的指针 - C语言》,本文将在数组指针的基础上对函数的指针探究。

作者:MilkCu

数组名与数组名取地址

我们先来做个关于数组的小实验:

# include <stdio.h>
int main(void)
{
	int a[2] = {3, 4};
	printf("a = %d\n", a);
	printf("&a = %d\n", &a);
	printf("a + 1 = %d\n", a + 1);
	printf("&a + 1 = %d\n", &a + 1);
	printf("*(a + 1) = %d\n", *(a + 1));
	printf("*(&a + 1) = %d\n", *(&a + 1));
	return 0;
}

得到的结果意料之中,如下所示:

a = 2686744
&a = 2686744
a + 1 = 2686748
&a + 1 = 2686752
*(a + 1) = 4
*(&a + 1) = 2686752

由此分析,a表示的是数组的第一个元素的指针,&a表示的是数组的指针,(a + 1)表示的是数组的第二个元素的指针,(&a + 1)表示的没有意义的值。

我们得到结论:对于数组a[2],&a指的是指向数组的指针,a指的是指向数组第一个元素的指针,在指针类型上是有区别的。

指向函数的指针

我们再做个关于函数指针的实验:

# include <stdio.h>
void fun(void)
{
	printf("Hello.\n");
}
int main(void)
{
	printf("fun = %d\n", fun);
	printf("&fun = %d\n", &fun);
	printf("*fun = %d\n", *fun);
	printf("*&fun = %d\n", *&fun);
	printf("&*fun = %d\n", &*fun);
	printf("****fun = %d\n", ****fun);
	//printf("&&&&fun = %d\n", &&&&fun);    //无法编译通过
	printf("fun + 1 = %d\n", fun + 1);
	printf("*fun + 1 = %d\n", *fun + 1);
	printf("&fun + 1 = %d\n", &fun + 1);
	//printf("sizeof(fun) = %d\n", sizeof(fun));    //无法编译通过 
	//printf("sizeof(*fun) = %d\n", sizeof(*fun));    //无法编译通过 
	printf("sizeof(&fun) = %d\n", sizeof(&fun));
	return 0;
}

编译过程中,会产生如下警告:

		E:\c\play\function.cpp	In function 'int main()':
15	33	E:\c\play\function.cpp	[Warning] pointer to a function used in arithmetic [-Wpointer-arith]
16	35	E:\c\play\function.cpp	[Warning] pointer to a function used in arithmetic [-Wpointer-arith]
17	35	E:\c\play\function.cpp	[Warning] pointer to a function used in arithmetic [-Wpointer-arith]

打印结果如下:

fun = 4199344
&fun = 4199344
*fun = 4199344
*&fun = 4199344
&*fun = 4199344
****fun = 4199344
fun + 1 = 4199345
*fun + 1 = 4199345
&fun + 1 = 4199345
sizeof(&fun) = 4

分析一下,发现&fun指的肯定是函数的指针,而对于fun和*fun则根据情况而定。产生的警告则说明,函数的指针与其他类型(如整型等)的指针不同,不能进行加减运算。
(只是通过代码,感性分析,纯属个人见解)

实际上,函数名就代表了函数的地址,因此fun就是一个地址。这个跟数组非常类似,其名字就是指针常量,也即一个地址。
对函数名取地址,即&fun产生指向函数的指针,也可以看做是函数的地址。 因此fun和&fun结果一致。
而 *fun代表指向函数的指针,指向的是函数的地址。所以可以得到*fun = fun。

即:*fun=*(fun) = *(&fun) = fun

小结

在C语言中,函数本身不是变量,但可以定义指向函数的指针。这种类型的指针可以被赋值、存放在数组中、传递给函数以及作为函数的返回值等等。

函数作为参数传递给函数时,因为它们是函数,前面不需要加取地址运算符&。同样的原因,数组名前面也不需要&运算符。

(全文完)

原文地址:https://www.cnblogs.com/milkcu/p/3808888.html