【问题标题】:Are object-oriented concepts applicable to the C language?面向对象的概念是否适用于 C 语言?
【发布时间】:2014-02-11 12:04:49
【问题描述】:

在 C# 中,我们了解到当多个函数具有相同标识符但签名不同时,会发生函数重载。

虽然函数重载的概念是面向对象语言特有的,但根据以下观察,它是否也适用于C语言?

printf("%d", 3);

printf("%d + %d = %d", 1 , 2 , 3 );

第一个 printf 只传递两个参数。 第二个 printf 传递四个参数。

这是否意味着 printf 被重载了?

【问题讨论】:

  • 仅供参考,函数重载并非特定于面向对象的语言。也许您正在考虑覆盖? C++ 有函数重载:void foo(int)void foo(char) 可能都存在,调用哪一个取决于参数的类型。这独立于 C++ 的 OOP 工具,也可能存在于 C 中:)
  • 请将您的标题更改为更准确的名称。您的问题是关于重载而不是 OO 语言,不是吗?
  • C 函数可以声明为接受任意数量的参数。 printf* 是这些功能之一。它的声明类似于 printf( const char *format, ...) google C va_list 宏和 stdarg.h

标签: c# c oop overloading


【解决方案1】:

没有 printf 没有重载。 C 中没有函数重载或任何其他面向对象的优点。 printf 的工作方式是使用参数列表。看看这篇文章http://www.cprogramming.com/tutorial/c/lesson17.html

【讨论】:

  • 函数重载不是 OO 特性。我相信一些完全缺乏 OO 支持的语言具有函数重载(Ada?)。此外,您说 C 中没有 OO 特性是不正确的。C 支持 OO 设计的几个方面,例如私有封装。请参阅 SO 的C FAQ 了解更多信息。
  • 人们在讨论 OO 时经常犯的主要错误是没有理解 OO 是一种设计程序的方式,完全独立于所选的编程语言。完全可以用 Java、C++ 等编写非 OO 程序。
【解决方案2】:

printf 系列函数不使用重载,而是采用可变数量的参数。

C 不支持函数重载和覆盖(即 C# 中的虚方法),它甚至没有成员函数。

但是可以通过函数指针来模仿它们。例如,这是在 X Window System 的实现中采用的方法。

【讨论】:

  • 严格来说,C 确实有一些与成员函数等价的东西,尽管它远非优雅。如果您将“类”实现为不完整(不透明)类型的结构,则可以拥有一个带有函数的模块,该函数接受指向这种不完整类型的指针,并且您将拥有与公共成员函数相同的工作方式。模拟私有成员函数更容易:只需在与公共函数相同的模块中声明它们,但将它们设为静态。它很粗糙,但它具有 OO 类的所有属性。
  • 我们曾经称这些抽象数据类型,但我明白你的意思。
  • 确实如此,但 ADT 可能会也可能不会使用面向对象设计来实现:它是一个更广泛、更模糊的术语。
【解决方案3】:

了解variadic functions

printfscanf 函数族是可变参数函数。

有用的链接:

  1. Cprogramming.com

  2. Writing Variadic Functions

完成答案:C 不支持函数重载。

【讨论】:

  • 改进了链接,因为 Wiki 页面没有任何内容。
【解决方案4】:

不,printf 不是其他人已经说过的函数重载的例子,它使用了stdarg.h 的特性。但似乎很多人都不知道,C 有某种函数重载。

  • 因为 C99 C 在tgmath.h 中具有“类型通用数学函数” 例如计算 floatdouble sin 取决于 你正在传递的论点
  • 因为 C11 有 _Generic,这个特性比函数重载更强大,并且可以用来编写实现重载特性的类函数宏

而且,所有这些都与 OO 编程无关。

【讨论】:

    【解决方案5】:

    函数重载是完全独立于面向对象设计的语言特性。仅仅因为它往往存在于具有 OO 特性的语言中,并不能使它也成为 OO 特性。

    OO 设计的基石是:对外部世界具有有限依赖性的自治类(“松散耦合”)、数据/方法的私有封装和继承/多态性。

    与上述不符的所有其他功能都只是一些额外的绒毛。函数重载和操作符重载是两个这样蓬松的东西 - 有许多 OO 语言不支持这两个特性。

    至于printf,它使用了C语言的icky变量参数特性。我不会称该函数为重载,而是在 70 年代引入的一些旧的临时废话,只是为了让 C 可以吹嘘具有可变数量的参数。至少可以说,这是一个非常有用的功能。它不会用于任何理智的、生产质量的代码中。

    【讨论】:

    • 所以,澄清一下,printffprintfsnprintf 的任何使用都会导致任何代码库疯狂而不是生产质量?
    • @MagnusHoff 我的意思是,使用带有可变参数的用户定义函数的代码库并不合理。这是语言的一个完全多余的特性。至于在生产代码中使用 stdio 函数,我个人认为这是可以接受的做法,只要您知道自己在做什么。不是每个人都同意……引用一个广为人知的 C 编程权威:“输入/输出库 不得用于生产代码。” MISRA-C:2004 20.9.
    • 感谢您详细说明:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-05
    • 1970-01-01
    相关资源
    最近更新 更多