1

我想知道是否可以在 C (89/90) 中链接函数调用,以及它在C 规范中定义的位置。我认为这是不可能的,因为谷歌搜索没有提到它。

我之所以想到这一点,是因为与我的一位朋友进行了一次相关的对话,他告诉我,给定一个返回结构的函数,您不能在同一语句中对所述结构执行任何操作;相反,您必须将函数的结果分配给变量,然后通过变量而不是直接从函数结果本身来操作结构。这让我相信你也不能链接函数,但我似乎找不到规范中讨论的这些限制。

编辑:对不起,我应该具体说明返回值。假设函数返回一个函数指针,是否可以在同一语句中以流畅的方式取消引用和调用结果?

例如,假设getFunc返回一个函数指针:

(*getFunc(getFuncParam))(otherFuncParam)

或者在这种struct情况下,假设 astruct有一个int名为 的成员count

funcReturnsStruct(param).count++
4

5 回答 5

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;
}

看到它在行动

于 2012-05-07T14:40:33.377 回答
3

我的一个朋友告诉我,给定一个返回结构的函数,您不能在同一语句中对所述结构执行任何操作

你的朋友是正确的,因为函数的返回值不能成为赋值的目标(它不是左值)。IOW,你不能做类似的事情

int foo(void) { int x = 5; return x; }
...
foo() = 6;

但是,如果函数的返回类型是结构或联合,则可以将组件选择运算符应用于返回值,例如

int x = foo().memb;

类似地,如果函数的返回类型是一个指向结构体或联合体的指针,你可以这样写

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语句结束时返回的值的生命周期结束 - 您将无法检索该修改后的值。

于 2012-05-07T15:56:05.750 回答
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);

该函数返回给定类型的值,因此可以在表达式中需要此类值的任何地方使用该函数的调用。

于 2012-05-07T14:56:42.340 回答
1

你的意思是这样的吗?

typedef void (*CALLBACK)(void);

CALLBACK getCallback();

void test()
{
    getCallback()();
}

它在 GCC 4.6.1(默认标准)中编译时没有警告。

于 2012-05-07T14:46:41.550 回答
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
%

与其说是迂腐的警告。预期输出。看起来完全没问题。但是,正如已经指出的那样,最好存储返回值并检查错误。

于 2012-05-07T14:56:22.433 回答