函数指针和函数的地址

所以我觉得在制作函数指针时,不需要operator &来获取初始函数的地址:

 #include <stdio.h> double foo (double x){ return x*x; } int main () { double (*fun1)(double) = &foo; double (*fun2)(double) = foo; printf("%f\n",fun1(10)); printf("%f\n",fun2(10)); printf("fun1 = %p \t &foo = %p\n",fun1, &foo); printf("fun2 = %p \t foo = %p\n",fun2, foo); int a[10]; printf(" a = %p \n &a = %p \n",a,&a); return 0; } 

输出:

 >./a.out 100.000000 100.000000 fun1 = 0x4004f4 &foo = 0x4004f4 fun2 = 0x4004f4 foo = 0x4004f4 a = 0x7fff26804470 &a = 0x7fff26804470 

然后我意识到这对于数组也是如此,这意味着如果int a[10] &a指向相同的位置。 为什么数组和函数? 是否将地址保存在与保存的值(地址)具有相同地址的内存位置?

int a[10]a&a产生相同的地址,是的,但是它们的types是不同的。

aint[10]types的int[10] 。 当它隐式转换为指针types时,指针的types为int*并指向数组的初始元素。 &a的types是int (*)[10] (也就是指向十个整数数组的指针)。 因为数组中不能有填充,所以它们都会产生具有相同的指针,但指针的types是不同的。

函数与数组类似,但不完全相同。 你的函数foo的types是double(double) 。 每当在expression式中使用foo而不是一元&运算符的操作数时,它将被隐式转换为一个指向自身的指针,该指针的types是double(*)(double)

所以,对于所有的实际目的,一个函数的名字和一个指向同一个函数的指针是可以互换的。 有一些微妙之处,所有这些我都在回答“为什么所有这些疯狂的函数指针定义都起作用了?实际上是怎么回事? (这个问题被问及C ++的问题,但C ++中的非成员函数的规则与C中的函数相同)

不,没有专门用于指向函数/数组的额外存储空间。

对于大多数variablesvariable_name除了获取该variables的地址之外,还需要使用&variable来获取地址。

对于一个函数或数组, function_name (本身不包含括号)没有任何其他含义,因此将其解释为函数的地址没有任何问题。

反过来也是如此:一个普通的指针需要被明确的解引用,但是指向一个函数的指针不会(再次,因为没有其他合理的解释),所以给一个函数指针就像:

 int (*func)(param_list); 

以下是相互等价的 – 都调用任何函数func点:

 (*func)(params); func(params); 

基本上,由于函数名称是“已知”的函数,因此&并不是必须的。 这个行为对于数组是一样的。 回想一下,一个函数本身不是一个variables,所以它的行为有点不同于你所期望的。 如果你有K&R的第二版,你可以查看第5.11节的函数指针或者最后的参考手册,

A7.1节指针生成:如果某个expression式或子expression式的types是某个Ttypes的“T的数组”,那么expression式的值就是一个指向数组中第一个对象的指针,expression式的types是改为“指向T”。 这个转换并不是expression式是一元运算符的操作数,…类似地,除了用作&运算符的操作数之外,types“返回T的函数”的expression式被转换为“指向函数返回T“。

A7.4.2节地址操作符:一元操作符&操作符取其操作数的地址….结果是指向由左值引用的对象或函数的指针。 如果操作数的types是T,那么结果的types是“指向T的指针”。

据我所知,C99是一样的。

printf(“fun1 =%p \ t&foo =%p \ n”,fun1,foo);

在这里你通过传递函数指针来pass by value foo

printf(“fun2 =%p \ t foo =%p \ n”,fun2,&foo)

在这里,您通过传递函数指针来pass by reference &foo

在这两种情况下,你只是用函数指针调用printf

记住foo本身就是function pointer value而不是一个variables。

数组也是一样。 int arr[10]翻译成10个整数的连续块,第一个元素的地址存入arr。 所以arr也是一个指针。

fun&fun是完全一样的(除了sizeof(f)是非法的)。 sizeof(*a) == sizeof(int) (其中sizeof(*a) == sizeof(int) )是一样的。