我想知道在C(89/90)中是否可以链接函数调用,以及它在C spec中的定义。我认为这是不可能的,因为谷歌搜索没有提及它。
我之所以这么想是因为与我的一位朋友进行了相关的谈话,他告诉我,如果函数返回一个struct,你就不能在同一个语句中对所述struct执行任何操作;相反,您必须将函数的结果赋给变量,然后通过变量而不是直接从函数结果本身操作结构。这让我相信你也不能链接函数,但我似乎无法找到规范中讨论的这些限制。
编辑:对不起,我应该具体了解返回值。假设函数返回一个函数指针,是否可以取消引用并以流畅的方式在同一语句中调用结果?
例如,假设getFunc
返回一个函数指针:
(*getFunc(getFuncParam))(otherFuncParam)
或在struct
案例中,假设struct
的{{1}}成员名为int
:
count
答案 0 :(得分:6)
这是C中的链接功能:
post_process(process(pre_process(data)));
显然,你的朋友错了。只要函数通过接受和返回相同类型的值进行协作,您就可以将所有调用链接起来。
将此与
等对比data.pre_process().process().post_process();
最大的区别在于C(没有封装,因此没有类)函数具有中心舞台,而在更现代的OO语言中它是对象得到更多的关注。
更新:无论每个功能可能返回什么,都可以链接。例如:
int increase(int x) {
return x + 1;
}
typedef int (*increase_fp)(int);
increase_fp get_increase() {
return increase;
}
int main(void) {
printf("%d", get_increase()(1));
return 0;
}
答案 1 :(得分:3)
我的一个朋友,他告诉我,给定一个返回结构的函数,你不能在同一个语句中对所述结构执行任何操作
你的朋友是正确的,因为函数的返回值不能是赋值的目标(它不是左值)。 IOW,你不能做像
这样的事情int foo(void) { int x = 5; return x; }
...
foo() = 6;
但是,如果函数的返回类型是结构或联合,则可以将组件选择运算符应用于返回值,例如
int x = foo().memb;
类似地,如果函数的返回类型是指向struct或union的指针,则可以编写
int x = foo()->memb;
如果返回值是指向另一个函数的指针,则可以调用其他函数,如下所示:
int bar(int x) { ... }
int (*foo)(int x) { return bar; }
int x = foo(x)(y); // or (*foo(x))(y) -- the result of foo(x) is
// called with the argument y
尽管任何需要维护或调试代码的人都可能会严重打败你。
无法做的事情就像是
foo().memb= ...;
foo()->memb = ...;
无论如何都没有意义,因为foo
返回的值的生命周期在语句结束时结束 - 您将无法检索该修改后的值。
答案 2 :(得分:2)
你的朋友错了。
如果我们有:
struct Point3
{
float x, y, z;
};
const Point3 * point3_get_origin(void);
那么你当然可以这样做:
printf("the origin's y coordinate is %f\n", point3_get_origin()->y);
该函数返回给定类型的值,因此只要表达式中需要这样的值,就可以使用函数的调用。
答案 3 :(得分:1)
你的意思是这样吗?
typedef void (*CALLBACK)(void);
CALLBACK getCallback();
void test()
{
getCallback()();
}
在GCC 4.6.1(默认标准版)中编译没有警告。
答案 4 :(得分:0)
回答这个问题要比在这里发布更快更容易:尝试一下。
#include <stdio.h>
struct s {
int a;
} s;
struct s * getS() {
s.a = 13;
return &s;
}
int main(int argc, char * const argv[]) {
printf("%d\n", getS()->a);
return 0;
}
% gcc test.c -o test -Wall -pedantic
% ./test
13
%
与迂腐警告不同。预期产出。看起来很完美。但是,正如已经指出的那样,最好存储返回值并检查错误。