【问题标题】:How Do I Read "int (*functionFactory(int n))(int, int) { ... }"?如何阅读“int (*functionFactory(int n))(int, int) { ... }”?
【发布时间】:2014-03-07 12:02:55
【问题描述】:

这是一个语法问题。我强调我想了解如何阅读下面的代码。

我在试图理解以下代码 (1) 如何转换为它下面的代码 (2) 时遇到了巨大的麻烦:

代码零:

int addInt(int n, int m) {
    return n+m;
}

代码一:

// this is a function called functionFactory which receives parameter n
// and returns a pointer to another function which receives two ints
// and it returns another int
int (*functionFactory(int n))(int, int) {
    printf("Got parameter %d", n);
    int (*functionPtr)(int,int) = &addInt;
    return functionPtr;
}

代码二:

typedef int (*myFuncDef)(int, int);
// note that the typedef name is indeed myFuncDef

myFuncDef functionFactory(int n) {
    printf("Got parameter %d", n);
    myFuncDef functionPtr = &addInt;
    return functionPtr;
}

我正在为两件事情苦苦挣扎,这就是原因。我已将上面的代码修改为我认为它们应该的样子。

没有Typedef的显式函数定义(应该与标题相同:

代码 4:

int (*myFuncDef)(int, int) functionFactory(int n) {
    printf("Got parameter %d", n);
    int (*functionPtr)(int,int) = &addInt;
    return functionPtr;
}

代码 5: typedef 本身(用于简化代码 2):

typedef int (*myFuncDef)(int, int) myFuncDef;

请注意,这些规定了基本规则:返回类型、标识符、参数。

我非常感谢一个链接,我可以在其中阅读有关这一切如何运作的严格规则。概述解释会很好,因为spec 不提供类似“教程”的课程。 非常感谢!

[编辑]另外,

注意,这些摘自:How do function pointers in C work?

【问题讨论】:

  • 我使用了那个网站,但我不想依赖它。我希望自己能够阅读。但我找不到严格描述它如何工作的规范。
  • 重复,一个可能永远不应该问的问题,因为这样的代码的读者只会有同样的问题。此外,如果您希望能够在 C 中解析 anything,请参阅 the current standard

标签: c


【解决方案1】:

int (*functionFactory(int n))(int, int) { … }?

Remember these rules for C declares
And precedence never will be in doubt
Start with the Suffix, Proceed with the Prefix
And read both sets from the inside out

(当然,除了括号说“先做这个”。)

所以:functionFactory 是

[open paren] 
[suffix (int n)]     a function taking an `int` argument called `n` that returns
[prefix *]           a pointer to
[close paren]
[suffix (int, int)]  a function taking two `int` arguments and returning
[prefix int]         an integer

它后面的{...} 给出了functionFactory 行为的定义。

(我们可能已经能够从名称 functionFactory 中猜到它会返回一个指向函数的指针。我们还可以查看它的逻辑以查看它返回的类型。)

Typedef 使用与变量声明完全相同的语法,用新的类型名称替换变量名称和(当然)它们前面的 typedef 关键字。此工厂返回的类型的函数指针将具有类型

int (*functionFromFactory)(int,int); /* oops, forgot parens the first time */

所以这种指针的 typedef 应该是

typedef int (*PtrToFunctionFromFactory)(int,int);

请注意,一旦您有了该类型,functionFactory 的声明就可以简化为

PtrToFunctionFromFactory functionFactory(int n) {...}

(对于此类函数,可能存在比“来自工厂的函数”更好的名称,并且该名称确实应该在 typedef 和工厂方法的名称中都使用,但是由于您没有给我们任何东西更好地与我一起工作,我有点被过于抽象的名字所困扰。)

希望对您有所帮助。

【讨论】:

  • 那会是更好的英语,@Potatoswatter ...但它不会扫描得那么好,也不会那么容易记住。我在构建那个助记符上做了很多工作(是的,它是我的,从大约 20 年前的 C FORUM 时代开始),我认为它已经达到了它可能会达到的程度。如果您想做出贡献,我很想找到一种优雅的方式来将有关括号的警告纳入其中...
  • 非常棒的链接! (是你把它当作重复的吗?)如果可以的话,一个问题:这就是在 C 中定义声明和定义的方式吗?我会在规范中的哪里找到这个?
  • 我开始认为我应该清理旧的cex 工具(C EXplainer),这是一个简单的 C 声明解析器,可以将它们翻译成英文。上帝只知道我把代码放在哪里...可以说,任何如此复杂的东西都应该使用 typedef 分阶段构建,但有时代码只是“增长一些”,直到变得令人毛骨悚然。
  • 哦,这首诗也不错:P。我强烈倾向于删除这个问题,因为那个副本实际上正是我正在寻找的,但我给了你正确的答案来帮助你。非常感谢
  • @user2316667 现在我很抱歉建议重​​复,因为这个很好的答案。让我们保留它。
【解决方案2】:

“由内而外,从右到左。”

从声明的名称来看,从右到左在该级别是“函数采用一个返回指针的 int ...”,再往下一层是“...到一个采用两个 int 返回一个 int 的函数”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 2019-05-02
    • 2015-09-02
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多