在C(以及许多其他“低级”语言)中,函数具有类型。您可以使用与函数匹配的类型声明变量,并可以为此类变量分配函数,但人们坚持认为函数不是C中的一等公民。
使用指向函数的指针并将函数作为参数传递给其他函数是C中几个标准函数的关键;例如, function setPrint(callback) {
var obj = setInterval(function () {
var frame = $('#WindowFadeiFrame').get(0).contentDocument;
var btn = $('#btn', frame);
if (btn.length == 0) {
console.log('not found');
}
else {
btn.click();
console.log('found now');
clearInterval(obj);
callback();
}
}, 100);
}
setPrint(callback)
function callback() {
// write all your code here which need to be executed after finding the control from iframe
alert('');
}
要求要传递比较函数,否则它无法执行任何操作。
通过使用函数类型声明带有多个变量的qsort
,在C中看到“面向对象”编程并不罕见。回调可以并且通常是(如果不总是 - 我无法想象其他任何方式)使用带有函数类型的变量实现,或struct
使用带有函数类型的成员实现回调。
那么,为什么C中的函数不被视为一等公民?
(我确定这是重复的,但我似乎无法在这里找到任何类似的问题)
答案 0 :(得分:6)
Scala问题上有really good answer by Andreas Rossberg(近似重复),这恰好解释了为什么C / C ++中的函数不是一等函数。引用:
“一流”不是一个正式定义的概念,但它通常意味着一个实体有三个属性:
它可以无限制地用于“普通”值,即从函数传递和返回,放入容器等的任何地方。
它可以在没有限制的情况下构建,只要“普通”值可以,即在本地,在表达式等中。
- 醇>
它可以用类似于“普通”值的方式输入,即,有一个类型分配给这样的实体,它可以与其他类型自由组合。
对于函数,(2)特别暗示局部函数可以使用范围内的所有名称,即你有词法闭包。它通常还带有一个用于构造的匿名表单(例如匿名函数),但这并不是严格要求的(例如,如果语言具有足够通用的let表达式)。在无类型语言中,Point(3)非常简单。
...
- C / C ++中的函数不是一流的。 虽然(1)和(3)可以通过函数指针获得,但(2)不适用于正常的函数。 (这一点经常被忽视。)
强调我的
答案 1 :(得分:4)
在hnefatl的理论解释中添加一个例子。在 C 中,int 值是一流的。我们可以添加两个 int 值,创建一个新的 int 值:
int add(int a, int b)
{
return a + b;
}
类似在 Haskell 中,我们可以组合两个函数(适当类型的)来创建一个新函数:
compose f g = f . g
h = compose f g 是满足 h(x) = f(g(x)) 的函数。
据我所知,这样的操作不能在 C 中完成。当然在C中通过其他方式也可以达到同样的效果。但是我们无法像计算数字那样轻松自然地计算新函数。