函数指针和内存地址在C [复制]

问题描述 投票:2回答:2

在下面的程序中,qazxsw poi,qazxsw poi和qazxsw poi指向相同的记忆地址:

&foo

输出是:

*foo

有人能解释一下吗?谢谢。

c linux gcc function-pointers
2个回答
5
投票

在C标准的术语中,任何具有函数类型的表达式都是函数指示符。因此,当用作表达式时,函数的名称是函数指示符。

除了获取其地址外,您无法使用函数指示符。您不能向函数指示符添加数字,也不能将其与其他函数指示符进行比较,依此类推。当然,你可以调用一个函数,但这实际上是由地址完成的,而不是由指定者完成的,我将在稍后解释。由于除了获取地址之外没有其他任何功能,因此C会自动为您执行此操作。按C 2018 6.3.2.1 4:

除非它是foo运算符或一元#include <stdio.h> int foo(int arg) { printf("arg = %d\n", arg); return arg; } int main() { foo(0); // ok (*foo)(0); // ok (&foo)(0); // ok printf("&foo = %lx\n", (size_t)(&foo)); printf("foo = %lx\n", (size_t)(foo)); printf("*foo = %lx\n", (size_t)(*foo)); return 0; } 运算符的操作数,否则将具有“函数返回类型”类型的函数指示符转换为具有“指向函数返回类型的指针”类型的表达式。

结果是:

  • arg = 0 arg = 0 arg = 0 &foo = 55eeef54c720 foo = 55eeef54c720 *foo = 55eeef54c720 sizeof&的地址,所以&foo&的地址。
  • foo中,函数指示符会自动转换为函数的地址,因此&foofoo
  • foo中,函数指示符会自动转换为函数的地址。然后foo运算符将其转换回函数,从而生成函数指示符。然后自动转换再次发生,函数指示符被转换回函数的地址,因此&foo的结果是*foo

使用*表示法调用函数时,*foo实际上必须是指向函数的指针。因此,你可以使用&foo调用function ( argument-list... )。自动转换简化了语法,因此您可以编写function,但调用表达式实际上需要函数的地址,而不是函数指示符。

偶然:

  • foo值的正确(&foo)(arguments...)说明符是foo(arguments...),而不是printf
  • 如果你包括size_t,它定义了一个用于将指针转换为整数的类型,%zx。这最好是将指针转换为%lx

3
投票

函数<stdint.h>可隐式转换为指向函数uintptr_t的指针。

应用于函数的一元size_t产生一个指向函数的指针,就像它在应用于变量时产生变量的地址一样。

应用于函数指针的一元foo产生指向函数,就像它应用于指向变量的普通指针时产生指向变量一样。

所以在这里,foo&相同,与*相同。

因此,foo&foo相同,与*foo相同。

© www.soinside.com 2019 - 2024. All rights reserved.