您曾经喜欢的编程习惯让您改变了主意?

时间:2009-07-06 21:36:49

标签: language-agnostic

在我们编程时,我们都开发了我们使用和依赖的实践和模式。然而,随着时间的推移,随着我们的理解,成熟度甚至技术使用的变化,我们逐渐意识到我们曾经认为很棒的一些实践并不(或不再适用)。

我曾经经常使用但最近几年改变的一种做法的例子是使用Singleton object pattern

通过我自己的经验和与同事的长时间辩论,我逐渐意识到singletons are not always desirable - 他们可以使测试更加困难(通过抑制模拟等技术)并且可以在系统的各个部分之间产生不希望的耦合。相反,我现在使用对象工厂(通常使用IoC容器)来隐藏系统中不关心或需要知道的部分单体的性质和存在。相反,他们依靠工厂(或服务定位器)来获取对这些对象的访问权。

我本着自我改善的精神向社会提出的问题是:

  • 您最近重新考虑了哪些编程模式或实践,现在尽量避免?
  • 您决定用什么来替换它们?

49 个答案:

答案 0 :(得分:159)


//Coming out of university, we were taught to ensure we always had an abundance 
//of commenting around our code. But applying that to the real world, made it 
//clear that over-commenting not only has the potential to confuse/complicate 
//things but can make the code hard to follow. Now I spend more time on 
//improving the simplicity and readability of the code and inserting fewer yet 
//relevant comments, instead of spending that time writing overly-descriptive 
//commentaries all throughout the code.


答案 1 :(得分:117)

单一返回点。

我曾经偏好每个方法的单个返回点,因为我可以确保不会忽略例程所需的任何清理。

从那以后,我转向了更小的例程 - 因此忽略了清理的可能性降低了,事实上,需要进行清理的工作减少了 - 并且发现早期的回报减少了明显的复杂性(代码的嵌套级别)。单个返回点的工件 - 保持“结果”变量,保留标志变量,未完成情况的条件子句 - 使代码看起来比实际复杂得多,使其更难以阅读和维护。早期出口和较小的方法是可行的方法。

答案 2 :(得分:111)

  • 第一次尝试完美地编写代码。
  • 在编码之前尝试创建完美的OO模型。
  • 为灵活性和未来改进设计一切。

一句话过度工程

答案 3 :(得分:78)

匈牙利表示法(表格和系统)。 我以前用过所有的前缀。 strSomeString或txtFoo。 现在我使用someString和textBoxFoo。对于新来的人来说,它更易读,更容易阅读。作为一个额外的奖励,保持它一致是微不足道的 - camelCase控件并附加一个有用/描述性的名称。形式匈牙利语的缺点是并不总是保持一致,而匈牙利语系统并没有真正为您带来多少收获。将所有变量组合在一起并不是很有用 - 特别是对于现代IDE。

答案 4 :(得分:67)

“完美”的架构

几年前我想出了 THE 架构。我尽可能地在技术上推动自己,因此有100%松散耦合的层,广泛使用委托和轻量级对象。这是技术天堂。

这是废话。该体系结构的技术纯度正在减慢我的开发团队的目标,以实现完美的结果,我几乎完全失败。

我们现在拥有更简单,技术更完美的架构,我们的交付率已经飙升。

答案 5 :(得分:57)

使用caffine。它曾经让我保持清醒,并且处于一种光荣的编程氛围中,代码从我的手指中流出,带着狂热的流动性。现在它什么也没做,如果我没有,我会头痛。

答案 6 :(得分:50)

评论代码。我曾经认为代码是珍贵的,你不能只删除你精心制作的那些美丽的宝石。我现在删除了我遇到的任何已注释掉的代码,除非附加了TODO或NOTE,因为将它留在其中太危险了。就是说,我遇到了带有大量注释部分的旧类,它真的让我困惑为什么他们在那里:他们最近评论过吗?这是一个开发环境变化吗?为什么会这样做无关?

认真考虑不要注释掉代码而只是删除代码。如果您需要它,它仍然在源代码管理中。 YAGNI虽然。

答案 7 :(得分:46)

#region指令的过度使用/滥用。这只是一件小事,但在C#中,我以前会在整个地方使用#region指令来组织我的课程。例如,我将所有类属性组合在一个区域中。

现在我回顾一下旧代码,大多只是被他们烦恼了。我不认为它在大多数情况下确实让事情变得更清晰,有时它们只会让你失望。 所以我现在已经改变了主意,觉得布局合理的课程大多是更简洁的没有区域指令。

答案 8 :(得分:39)

瀑布式开发,一般而言,是编写完整而全面的功能和设计规范的实践,这些规范在某种程度上被认为是规范的,然后期望这些规范的实现是正确和可接受的。我已经看到它被Scrum取代了,并且很好地解决了它,我说。简单的事实是,客户需求和欲望的变化使得任何固定的规范都无济于事;真正正确解决问题的唯一方法是使用迭代方法。当然,并不是说Scrum是一颗银弹;我已经看到它滥用和滥用了很多次。但它击败了瀑布。

答案 9 :(得分:36)

永不崩溃。

这似乎是个好主意,不是吗?用户不喜欢崩溃的程序,所以让我们编写不会崩溃的程序,用户应该喜欢这个程序吧?这就是我开始的方式。

如今,我更倾向于认为如果它不起作用,它就不应该假装它正在发挥作用。尽快失败,并提供良好的错误消息。如果你不这样做,你的程序将在稍后的几个指令中更加崩溃,但是有一些非描述性的空指针错误,你需要一个小时来调试。

我最喜欢的“不要崩溃”模式是:

public User readUserFromDb(int id){
    User u = null;
    try {
        ResultSet rs = connection.execute("SELECT * FROM user WHERE id = " + id);
        if (rs.moveNext()){
            u = new User();
            u.setFirstName(rs.get("fname"));
            u.setSurname(rs.get("sname"));
            // etc
        }
    } catch (Exception e) {
        log.info(e);
    }
    if (u == null){
        u = new User();
        u.setFirstName("error communicating with database");
        u.setSurname("error communicating with database");
        // etc
    }
    u.setId(id);
    return u;
}

现在,您不必要求用户复制/粘贴错误消息并将其发送给您,而是必须深入了解尝试查找日志条目的日志。 (因为他们输入了无效的用户ID,所以没有日志条目。)

答案 10 :(得分:33)

我认为只要我认出它就应用设计模式是有意义的。

我很少知道我实际上是从外国编程语言中复制样式,而我正在使用的语言允许更优雅或更简单的解决方案。

使用多种(非常)不同的语言让我眼前一亮,让我意识到我不必将其他人的解决方案误用于不属于我的问题。当我看到用Ruby这样的语言应用工厂模式时,我感到不寒而栗。

答案 11 :(得分:27)

强迫测试。我曾经是测试优先开发的狂热支持者。对于某些项目来说,这很有道理,但我已经意识到,这不仅是不可行的,而且对许多项目而言是有害的,因为他们盲目地坚持为每一项功能编写单元测试的学说。

真的,盲目地坚持任何事情可能是有害的。

答案 12 :(得分:25)

这是一件小事,但是:关心大括号的位置(在同一行或下一行?),建议代码的最大行长度,变量的命名约定以及样式的其他元素。我发现每个人似乎都比我更关心这一点,所以我只想跟随我现在工作的人的流动。

编辑:当然,当我是最关心的人(或者是能够为团体设置风格的人)时,这是个例外。在那种情况下,我做我想做的事!

(请注意,这与没有一致的样式不同。我认为代码库中的一致样式对于可读性非常重要。)

答案 13 :(得分:24)

也许我改变主意的最重要的“编程实践”是我的代码比其他人更好的想法。这对于程序员(尤其是新手)来说很常见。

答案 14 :(得分:20)

设计超过我编码。 过了一会儿,它变成了分析瘫痪。

答案 15 :(得分:20)

实用程序库。我曾经带着各种辅助方法和类进行组装,其理论是我可以在其他地方使用它们。

实际上,我刚刚创建了一个巨大的命名空间,其中包含许多功能不良的功能。

现在,我将它们留在我创建它们的项目中。很可能我不需要它,如果我这样做,我总是可以将它们重构为以后可重用的东西。有时我会使用// TODO标记它们,以便可能提取到一个公共程序集中。

答案 16 :(得分:15)

使用DataSet执行业务逻辑。这会将代码与数据库紧密绑定,而DataSet通常也是从SQL创建的,这使得事情变得更加脆弱。如果SQL或数据库发生了变化,它往往会渗透到DataSet所触及的所有内容中。

在对象构造函数中执行任何业务逻辑。继承和创建重载构造函数的能力往往会使维护变得困难。

答案 17 :(得分:15)

缩写变量/ method / table / ...名称

我曾经一直这样做,即使在没有强制限制名称长度的语言中工作(好吧它们可能是255或者其他东西)。其中一个副作用是在整个代码中散布了许多解释(非标准)缩写的评论。当然,如果名字因任何原因而改变......

现在我更喜欢用好的描述性名称来称呼它们的真实含义。仅包括标准缩写。无需包含无用的注释,代码更具可读性和易懂性。

答案 18 :(得分:14)

使用自定义的辅助方法层包装现有的数据访问组件,如企业库。

  • 这不会让任何人的生活更轻松
  • 它的更多代码可能有错误
  • 很多人都知道如何使用EntLib数据访问组件。除了本地团队之外,没有人知道如何使用内部数据访问解决方案

答案 19 :(得分:14)

我在1984年阅读有关Smalltalk时首次听说过面向对象的编程,但是在1992年我使用cfront C ++编译器之前我没有访问oo语言。我终于在1995年使用了Smalltalk。我有热切期待oo技术,并认为它可以节省软件开发。

现在,我只看到o-o作为一种具有一些优势的技术,但它只是工具箱中的一个工具。我在Python中完成大部分工作,而且我经常编写不是类成员的独立函数,而且我经常在元组或列表中收集数据组,过去我会创建一个类。我仍然在数据结构复杂时创建类,或者我需要与数据相关的行为,但我倾向于抵制它。

当我得到时间时,我真的很想在Clojure做一些工作,虽然如果我理解正确的话,它可以使用Java对象。我还没准备好说o-o已经死了,但我个人并不是以前的粉丝。

答案 20 :(得分:13)

在C#中,使用_notation作为私人成员。我现在认为这很难看。

然后我为私人成员更改为this.notation,但发现我在使用它时不一致,所以我放弃了它。

答案 21 :(得分:11)

在实施之前,我停止了大学推荐的设计方法。在一个混乱而复杂的系统中工作迫使我改变态度。

当然我仍然会进行代码研究,特别是当我要触摸我以前从未接触过的代码时,但通常我会尽量专注于尽可能小的实现,以便先获得一些东西。这是主要目标。然后逐渐完善逻辑,让设计自己出现。编程是一个迭代过程,并且在敏捷方法和大量重构方面非常有效。

代码不会查看您最初认为的样子。每次都发生:)

答案 22 :(得分:10)

我曾经在合同设计方面做得很好。这意味着在我的所有功能开始时进行大量错误检查。从关注点分离的角度来看,合同仍然很重要,但我不是试图强制执行我的代码不应该做的事情,而是尝试使用单元测试来验证它的作用。

答案 23 :(得分:10)

我会在很多方法/类中使用static,因为它更简洁。当我开始编写测试时,练习变化非常快。

答案 24 :(得分:10)

已检查的例外情况

纸上一个惊人的想法 - 明确定义合同,没有错误的余地或忘记检查某些异常情况。我第一次听到它的时候卖了。

当然,在实践中它变得如此混乱。到目前为止,像Spring JDBC一样拥有库,它将遗留的遗留检查异常作为其主要特征之一。

答案 25 :(得分:9)

任何有价值的东西只能用一种特定的语言编码。在我的情况下,我相信C是有史以来最好的语言,我从来没有任何理由用任何其他语言编码任何东西......永远。

我已经开始欣赏许多不同的语言以及它们提供的好处/功能。如果我想编写一些小的东西 - 很快 - 我会使用Python。如果我想处理大型项目,我会用C ++或C#编写代码。如果我想发展脑肿瘤,我会在Perl编码。

答案 26 :(得分:8)

当我需要进行一些重构时,我认为直接开始并实施新设计更快更干净,修复连接直到它们工作。然后我意识到最好做一系列的小型重构,以便慢慢但可靠地向新设计方向发展。

答案 27 :(得分:8)

在我的编码实践以及其他编码实践中,最重要的事情可能是接受从互联网下载的外部类和库作为应用程序中行为和功能的基础。在我上大学的时候,我们被鼓励想出如何通过我们自己的代码让事情变得更好,并依靠语言来解决我们的问题。随着用户界面和服务/数据消费各方面的进步,这不再是一个现实的概念。

某些东西在某种语言中永远不会改变,并且拥有一个将这个代码包装在一个更简单的事务中的库,而且我需要编写的代码行数更少,这是一种祝福。连接到数据库将始终是相同的。选择DOM中的元素不会改变。通过服务器端脚本发送电子邮件永远不会改变。不得不写这个时间又浪费了我可以用来改善应用程序核心逻辑的时间。

答案 28 :(得分:7)

初始化所有班级成员。

我曾经用某些东西显式初始化每个类成员,通常是NULL。我已经意识到这一点:

  • 通常意味着每个变量在被读取之前被初始化两次
  • 很愚蠢,因为在大多数语言中,自动将变量初始化为NULL。
  • 实际上在大多数语言中实施了轻微的性能提升
  • 可以在更大的项目上膨胀代码

答案 29 :(得分:6)

和您一样,我也采用了IoC模式来减少应用程序各个组件之间的耦合。只要我能够使每个组件尽可能独立,它使维护和部件交换变得更加简单。我也在使用更多的对象关系框架,比如NHibernate来简化数据库管理工作。

简而言之,我正在使用“迷你”框架来帮助更快速有效地构建软件。这些迷你框架可以节省大量时间,如果做得好,可以使应用程序变得非常简单,以便在路上维护。 Plug'n Play for the win!

答案 30 :(得分:3)

IDE中的原型。像所有新手一样,我了解到跳入代码是一个坏主意。现在我甚至在使用键盘之前就倾向于放弃愚蠢的想法。

答案 31 :(得分:3)

编写docblock方法描述,简单地重复了方法名称已经告诉您的内容。过去的糟糕日子:

/**
 * Returns the logger obj
 * @return log_Core
 */
public function getLogger() 
{ ... }

现在:

/**
 * @return log_Core
 */
public function getLogger() 
{ ... }

当然,有名的功能会有所帮助。

答案 32 :(得分:2)

一些:

  • 开始在同一行而不是新行(if (... ) {
  • 上使用大括号
  • 使用camelCase而不是non_camel_case
  • 停止使用printf()进行调试
  • 开始依赖第三方库,而不是从头开始编写每一点

JRH

答案 33 :(得分:2)

永远不会评论代码,希望始终依赖代码应该描述自己的概念。

当我第一次开始编程时,我很快采纳了广泛的注释无用的想法,而代码应该以这样的方式编写,以便自我描述。然后我把它带到一个极端,我永远不会评论代码。对于代表业务域的代码,这种方法很有效,因为详细的文档需要在其他地方(如DSL或文档),并且类成员的含义是显而易见的。然而,当开发更多“框架”代码时,更难以推断出意义。我自己回顾自己的代码就是这样,而不是说需要使用它的其他人。我当然使用.NET Framework类和其他框架的注释,为什么我不应该为自己的框架编写它们?通常,我只评论类或方法,如果它们具有非显而易见的特征,或者对参数有某些依赖性,并且具有特殊类型的行为。

此外,我意识到评论某些类别的课程有助于我的思考过程。当我能够表达一个阶级的目的和特征时,我也可以重新考虑它的整个存在。

实际上,对于每个代码块的无评论与论文之间的频谱,我已经从无评论中走向了合理有效地使用它们。在将来,当语言本身允许声明更多规则,用例等(如DbC)时,更多地使用表达式而不是语句,评论的需求将进一步减少。与此同时,评论仍然有用。

答案 34 :(得分:2)

紧凑的代码。

我曾经喜欢将任何给定的函数归结为绝对要素,并且经常使用嵌套函数调用来减少行数。

在维护了几年的代码之后,我意识到减少行数只会使代码的可读性降低,而采用快捷方式只会导致轨道上的痛苦!

答案 35 :(得分:2)

一般来说,TDD和单元测试。在某些时候,我在我的工作场所是TDD的倡导者,但随着时间的推移,我知道它确实没有带来任何东西,至少使用静态类型的语言。

不要误解我的意思,我仍然认为自动化功能测试非常重要。

答案 36 :(得分:2)

作为软件开发人员,我在学校和大学里教过我的职业生涯中的两次改变。

像生活中的许多事情一样,这些变化来自经验和观察,而这两者是相互矛盾的(就像生活一样!)。

或多或少第一个描述了为什么/何时使用“大系统”而不是“小系统”,第二个描述了为什么有时“专有系统”优于“标准系统”。

我知道这是一个有点长/哲学的答案,但你可以跳到“结论”!


ONE:“Small / Indie”软件与“大名/标准”软件同样出色。

我一直想知道为什么公司会使用微软,SAP,甲骨文等大牌软件,这些软件需要花费很多钱来开发和许可。

我从一个为使用Oracle DBMS而不是MySQl而付出很多钱的人那里学到了宝贵的一课,这对于这个原因来说已经足够了,因为它只是存储在数据库中的非常少量的数据软件项目。

基本上,当您使用像SAP,Oracle或Microsoft这样的“大名/标准”软件时,您想要购买“安全性”,最好在“30年后总结”,我仍然会找到SAP的开发人员。

较小的公司可能会破产,您在维护软件系统方面遇到问题的时间较长。也许“小/独立”软件可以完成这项工作,但你不能确定明年它会得到支持。

我已经多次看到一家软件公司(甚至更大的软件公司)陷入困境,你突然遇到问题需要在软件系统市场上获得支持和/或开发人员(价格合理)。

总结:使用“大名/标准”软件有很好的理由,例如安全性或支持,即使它们价格昂贵且有自己的问题。


TWO:软件语言/概念/系统X是唯一正确的做事方式。

在我年轻的时候,我是一个纯粹主义者。一切都必须是这个或那个,中间没有灰色区域。例如。我用C ++(MS Windows,然后是Java(Windows / Web),然后是PHP(Linux / Web)等...甚至ColdFusion(Windows / Web)或ABAP(SAP)来完成所有工作。

现在我认为没有唯一的“正确方法”来做事。我现在更多的是通才而不是纯粹主义者。此外,我对Java等提供的大型库或PHP等软件层等系统持怀疑态度。

此外,我对所看似无处不在的OO咒语持怀疑态度。 OO以自己的方式很出色,但它不是解决每个问题的方法。我靠KISS(保持简单,愚蠢)的原则生活,我经常发现很难学习某种语言的所有类/功能,只为小型网站项目做简单的事情。例如。我总是想知道为什么JSP用于可以在很短的时间内用PHP完成的小型简单项目。

所以今天我对大型/慢速/开销软件系统持怀疑态度......通常情况下,自己为小型项目做更好的事情,而不是用大功能来解决所有问题,而这些功能又必须根据你的需要进行定制。需要。

大部分时间我从头开始建立一个具有数据库连接的网站(例如PHP),而不是使用(昂贵的?!)和复杂的巨型库(例如JSP)来实现它,因为大部分功能都不是'甚至有用。

例如:你想在你的网站上使用博客软件X,这是非常酷的,因为内置的功能,如RSS导出,网络服务等。 但是,在学习博客软件的所有库功能和惯例方面存在严重的开销...是的,当你最终理解它时,你可以使用所有甜蜜的功能和特性......但是大约一半的时间你可以从头开始构建您真正需要的10%的功能。

总结:保持简单,愚蠢有效。很多时候,一个简单的(即使是“更粗糙的”)解决方案比一个复杂的(但更好的)解决方案更好。使用最适合不是固定口头禅的情况的工具。

答案 37 :(得分:2)

我所做的最重大的改变是我对N层的态度。我一直相信逻辑在物理层上的分离以及构建中间层“应用服务器”。使用DCOM,MTS和COM +返回windows DNA,然后使用.NET Remoting。从安全性和可伸缩性的角度来看,以这种方式构建系统似乎是合理的。但是已经做了足够的时间来发现增加的复杂性(这是重要的),网络通信开销,部署问题,开发人员培训以及安全性从未增加的现实(因为我们从未真正锁定服务器之间的防火墙)导致我得出结论认为它很少有理由或有理由。

我仍然非常支持分层,并且这样做是为了允许分层,如果它成为一个要求,我将继续找到它,它很少。

答案 38 :(得分:2)

要求所有代码都是干净的代码,即使它已经在运行。

在学术环境中,如此关注清洁代码,以至于后来的诱惑很大,以便在遇到丑陋代码时始终清理它们。但是,清理工作代码有许多缺点:

  • 清理它所花费的时间并没有为产品增加任何价值,而在调试或进行功能开发的同一时间确实增加了价值。
  • 存在破坏已经运行的代码的风险。没有人是如此惊人,以至于他们在重构时从不会引入错误。 (当我的虫子运到顾客身上时,我不得不吃一些不起眼的馅饼。)

当然,一旦这段丑陋的代码需要新的功能,重构它通常不是一个坏主意。但重点是:重构和清理只应与功能开发相结合。

答案 39 :(得分:1)

没有重复/代码重用我失去了这么大的时间。如果整体创建的工作量少于删除重复所需的工作,则复制很好。在某些方面,这是一种过度架构。

答案 40 :(得分:1)

创建用于访问数据的存储过程。地狱要维护(特别是如果你在测试服务器上开发并且必须维护其他服务器),你最终会得到名为NewInsertStoredProcedureLines的大量存储过程,NewSelectStoredProcedureLines ...... 现在它很高兴地存放在应用程序中的硬编码,让我成为一个快乐的露营者。

答案 41 :(得分:1)

标头文件不得包含其他标头文件。

我曾经强烈反对包含其他标题的标题的想法 - 基于我工程职业生涯早期的糟糕经历。在源文件中明确包含所需顺序的标题似乎更好。

现在 - 总的来说 - 我的心态是每个头文件都应该是自给自足的,即不要求在源文件中包含其他.h文件。特别是在使用C ++进行开发时......

答案 42 :(得分:1)

匈牙利表示法 - 它只会增加噪音。使用现代IDE和编写良好的紧密代码,这是不必要的,至少在静态类型语言中是这样。不幸的是,我与之合作过的大多数团队仍然坚持以某种形式使用它。

答案 43 :(得分:1)

用西班牙语编写我的代码

答案 44 :(得分:1)

使用广泛的内联代码注释记录代码。现在我遵循Bob叔叔的观点,即代码应该自我记录:如果你觉得需要写一些关于某段代码的评论,你应该重构代码,使其更清晰。< / p>

此外,代码注释往往与它们应该描述的实际代码不同步。引用叔叔:“事实是在代码中,而不是评论”。

强烈推荐的书:Clean Code: A Handbook of Agile Software Craftsmanship

答案 45 :(得分:0)

思考ORMS一般只是一个坏主意。我发现对于CRUD应用程序来说,这是一路走来的路。将开发时间缩短一半,并且能够通过ORM将更改从数据库向上流动,只需更改代码。查看此链接以获取一些优秀的.Net文件:https://stackoverflow.com/q/3505/323548

答案 46 :(得分:0)

直接访问数据库 在我的旧代码中,我广泛使用查询和数据集。现在我在大多数事情上使用ORM。它为我提供了更清晰的代码和更好的可重用性。通常,我现在只在小程序中直接访问数据库,或者在性能需要时访问数据库。

答案 47 :(得分:0)

仅捕获高可用性服务中您知道的异常。

这是我不同意自己公司建议的地方。理论上说,你应该只捕捉你所知道的例外,因为你无法保证所发生的“坏”事情是什么。如果内存被破坏或者CLR本身被楔入,你就不会恢复。

但是,当我从事高可用性服务时,我发现通常情况下我想表达“尽可能多地收集错误并继续”。是的,从理论上讲,我们可以看到我们无法处理的异常,但是在您控制的环境中使用经过良好测试的代码(除了系统提供的内容,混合中的本机代码不多),结果证明这是更好的选项,而不仅仅是捕捉你知道的例外。

CLR团队对此的立场是“不要让你的线程在一个未知的状态下执行”,而我的立场是“如果你知道你的场景,这可能是好的”。如果您正在运营银行网站,可能不太好,但在大多数情况下,这会为您提供更好的可用性,而不会强迫您想知道您的应用为何频繁重启。

你可以在http://blogs.msdn.com/clrteam/archive/2009/02/19/why-catch-exception-empty-catch-is-bad.aspx

看到辩论的双方

答案 48 :(得分:0)

我曾经写过几个例程。每个例程都做了很多事情 现在我将任务分解为许多简短的例程,每个例程都会执行一个特定的事情(尽可能)。


此外,例程的参数声明样式,为长arg。清单:

int foo (char arg1, int arg2, float arg3, double arg4)

现在

int
foo (
  char arg1,
  int arg2,
  float arg3,
  double arg4  )

这当然是一种品味问题。

相关问题