为什么 C 中的函数声明需要知道指向函数的参数和返回值的类型?
c中的一个指针声明是这样写的:
returnType ( *funcPtrName ) ( paramTypes )
例如下面的foo
:
char my_func ( int x )
{
...
}
int main ()
{
char ( *foo ) ( int );
foo = my_func;
foo( 2 );
}
当声明一个指向值的指针时,类型用于确定一个元素的大小(以字节为单位)。例如在 int* p
中,int
告诉编译器 p
指向的元素是 sizeof( int )
分开。此信息用于指针运算。
但是,函数指针指向单个地址并且不允许进行指针运算。
那么为什么需要额外的信息呢? returnType
和 paramTypes
是否仅用于支持编译器的错误检查? (例如,当用户分配类型不匹配的函数时提醒用户)。
最佳答案
有几个原因。让我们先考虑返回值。
假设一个程序包含代码y = f(x);
。调用f
后,编译器需要获取它返回的值并将其赋值给y
。它从哪里获得这个值(value)?在某些系统中,整数返回值在通用寄存器中传递,浮点返回值在浮点寄存器中传递。所以编译器无法知道返回值在哪里,除非它知道类型。宽整数,例如 long long int
,可能会在多个寄存器中传递。小结构可能会在寄存器中返回,而大结构可能会在内存中返回,使用指向调用函数提供的空间的指针,并且需要将其作为隐藏参数传递给被调用函数。
同样,编译器在调用函数时需要知道将参数放在哪里。前几个整数参数可能在通用寄存器中传递,而前几个浮点参数可能在浮点寄存器中传递。任何一种类型的附加参数都可能被压入堆栈。
此外,有时程序员可能会在函数实际需要浮点参数的地方传递一个整数表达式,例如在 pow(x, 4)
中。当编译器知道参数必须是浮点参数时,它可以将其转换为预期的类型。
另一个好处是,当编译器知道类型时,如果参数与预期类型不匹配并且不能隐式转换为预期类型,它可以报告错误,如果返回类型同样可以报告错误不匹配。
关于c - 为什么函数指针声明需要知道参数和返回值的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57263009/