【问题标题】:Why does a function in C(or Objective C) with no listed arguments allow inputting one argument?为什么没有列出参数的 C(或 Objective C)中的函数允许输入一个参数?
【发布时间】:2022-10-04 03:16:20
【问题描述】:

C 中,当一个函数被声明为void main(); 时,尝试向它输入一个参数(作为第一个也是唯一的参数)不会导致编译错误,为了防止它,函数可以声明为@987654324 @。顺便说一句,我认为这也适用于Objective C 而不适用于C++Objective C 我指的是类外的函数。为什么是这样?感谢您伸出援手。我想这类似于Fortran 变量,其名称以 i、j、k、l、m 或 n 开头的变量隐含为 integer 类型(除非您添加 implicit none)。

编辑:Objective C 允许这样做是因为与 C 更好的兼容性,还是类似于 C 拥有这个的原因?

注意:我保留了问题中的错误,因此不需要更改答案和 cmets。

另一个注意事项:正如@Steve Summit 和@matt (here) 所指出的,Objective-C 是 C 的严格超集,这意味着所有 C 代码也是有效的 Objective-C 代码,因此必须显示这种行为关于功能。

【问题讨论】:

  • 对于“为什么?”您需要询问以这种方式决定的人。可能是为了避免破坏旧的 C 源代码。无论如何,C允许任何如果您不提供参数列表,则为数字。或者你真的有另一个答案?

标签: c objective-c function-declaration


【解决方案1】:

因为函数原型不是预标准 C 的一部分,所以函数只能用空括号声明:

extern double sin();

所有现有代码都使用这种表示法。如果这样的代码无效,或者意味着“零参数”,该标准就会失败。

因此,在标准 C 中,这样的函数声明意味着“接受零个或多个参数的未定义列表”。该标准确实规定所有具有可变参数列表的函数必须在范围内具有原型,并且原型将以, ...) 结尾。因此,使用空参数列表声明的函数不是可变参数函数(而printf() 是可变参数)。

因为编译器没有被告知参数的数量和类型,所以无论调用中的参数如何,它都不会在调用函数时抱怨。

【讨论】:

    【解决方案2】:

    在早期(ANSI 之前)C 中,函数定义与其调用之间函数参数的正确匹配没有被编译器检查.

    我相信这样做有两个原因:

    1. 它使编译器变得相当简单
    2. C 一直是为单独编译而设计的,检查翻译单元(即跨多个源文件)的一致性是一个更难的问题。

      因此,在早期,确保函数调用与其定义相匹配是程序员或单独程序lint 的责任。

      对函数参数的不严格检查也使得 varargsprintf 这样的函数成为可能。

      无论如何,在原来的 C 中,当你写

      extern int f();
      

      , 你之前是不是说“f 是一个不接受任何参数并返回 int 的函数”。您只是在说“f 是一个返回int 的函数”。你没有说任何关于争论的事情。

      基本上,早期 C 的类型系统甚至没有记录函数预期参数的方法。当单独编译开始发挥作用时尤其如此,因为链接器几乎仅根据它们的名称解析外部符号。

      当然,C++ 通过引入function prototypes 改变了这一点。在 C++ 中,当你说 extern int f(); 时,你声明一个显式接受 0 个参数的函数。 (还设计了一个“name mangling”方案,其中包括让链接器在链接时进行一些一致性检查。)

      现在,这在旧 C 中有点不足,ANSI C 引入的最大变化是在 C 中采用 C++ 的函数原型表示法。不过,它略有不同:为了保持兼容性,在 C 中说 extern int f(); 必须被解释为“函数返回int 并采用未指定的参数”。如果你想明确地说一个函数不带参数,你必须(并且仍然必须)说extern int f(void);

      还有一个新的... 表示法将函数显式标记为采用可变参数,例如printf,并且开始了在声明中去除“隐式int”的过程。

      总而言之,这是一个显着的改进,尽管仍有一些漏洞。特别是,程序员仍有一些责任,即确保准确的函数原型始终在范围内,以便编译器可以检查它们。另见this question


      另外两个说明:您询问了Objective C,但我对该语言一无所知,因此我无法解决这一点。您说对于没有原型的函数,“尝试向其输入参数(作为第一个也是唯一的参数)不会导致编译错误”,但实际上,您可以将任何数字或参数传递给此类一个函数,没有错误。

    【讨论】:

    • 我可以专门针对这个问题的目标 C 部分提出另一个问题吗?另外,我保留了问题中的错误,以便不需要更改答案和 cmets。
    • 我不认为那会是个问题。我只会将其标记为objective-c,并包含指向此问题的链接。
    • @markoj对不起,我想我给了你不好的建议,那里。 (我不知道,或者完全忘记了,与 C++ 不同,Objective-C 是 C 的严格超集。)
    猜你喜欢
    • 2023-03-11
    • 2020-08-15
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-20
    相关资源
    最近更新 更多