为什么函数被设计为指针?

时间:2017-05-11 02:50:42

标签: c++ c

在C语言的所有情况下,函数基本上都被视为指向函数的指针,几乎所有函数都在C ++中。

我想知道为什么它是这样设计的?如果它只是一个函数类型,就像在int或任何其他原语中的变量一样,那不是很好吗?

typedef void(int) func_t
void foo(int);
void bar(int);
func_t fp = foo;  // What's wrong with this?
fp = bar;  // Acts like any other primitive

据我所知,函数就像指针而不是原语一样,只会让他们模仿它们的地狱般的错误:P

作为旁注,许多语言将功能视为一种。比如golang

func foo(int) {}
var fn func(int)
fn = foo

编辑被删除,因为它写得很糟糕。

EDIT2内存中函数的表示与它们在一种语言中的呈现方式无关。该语言旨在弥合硬件和逻辑之间的差距,因此,它将硬件内容包装成更容易理解的概念。

例如,作为地址的数字非常容易出错且难以思考,C提出了给它指针语义的解决方案。现在很明显,指针不应该成倍增加,并且与数字不同。指针实际上形成affine space

我做了相同的论点,事实上,函数指针应该被认为是指针,尽管它在内存中被表示为一个。

3 个答案:

答案 0 :(得分:3)

我会用另一个问题回答你的问题:你如何将一个函数表示为一个值?

一个函数基本上是一个代码块,对吧?而这段代码可以是一个可变长度,对吧?那么,我们如何引用可变长度块呢?我们引用一个指向块开头的指针。

我确定其他答案会更详细,但这对于如何有效地掌握它是完美的。

对于看起来函数是值类型的任何语言,我向你保证在内部表示中有一个指针(或者它只是语法糖)。

答案 1 :(得分:1)

  

如果它只是一个函数类型,就像在一个类似于int或任何其他原语的变量中那样,那不是很完美吗?

单一函数类型是不可能的,因为语言需要区分采用不同类型参数的函数,获取不同数量的参数,以及返回不同类型的值。

您可以为给定的参数集和特定的返回类型定义函数类型,如下所示:

typedef void func_t(int);

在声明该类型的变量时,您需要使用指针语法:

func_t *fp = foo;

然而,这是与指针相关的语法结束的地方:在声明之后,你完全按照操作基元的方式操作指针:

void foo(int x) { printf("foo says: x=%d\n", x);}
void bar(int x) { printf("bar says: x=%d\n", x);}

int main(void) {
    func_t *fp = foo;
    fp(5);
    fp = bar;
    fp(3);
    return 0;
}

请注意该语言如何让您bar完全按照fp的方式分配int,即不使用&运算符。另请注意fp的呼叫如何不需要星号。

Demo.

答案 2 :(得分:0)

首先,让我们回想一下指针究竟是什么:指针是内存中某些东西的地址。随着数字存储和高级编程语言的出现,我们得到的结论是代码的数字表示与存储器的数字表示(即存储中的二进制)相同。

旁注:这是现代世界中许多安全问题的原因。例如,SQL注入是一个被视为代码的内存实例,因为计算机无法区分它。

那么,为什么函数指针?因为函数只是计算机视为代码的一块内存。当你调用一个函数时,你所做的只是告诉处理器将其执行移动到该函数在内存中的位置。

你能设计出一种特定于功能的类型吗?当然,但在一天结束时,所有类型都是内存中函数的地址,我们已经有了一个描述内存地址的类型。

相关问题