我是一个相对较新的C程序员,我注意到其他更高级别的OOP语言的许多约定并不完全适用于C.
好吗使用短函数让您的编码保持井井有条(即使它可能只被调用一次)?例如,void init_file(void)
之类的10-15行,然后在main()
中首先调用它。
答案 0 :(得分:20)
我不得不说,不仅可以,而且通常也会受到鼓励。只是不要过度通过创建无数的 tiny 函数来破解思路。尝试确保每个函数执行单个内聚,良好的...... 函数,具有干净的界面(太多的参数可以暗示函数正在执行与其调用者不完全分离的工作)。
此外,命名良好的函数可用于替换原本需要的注释。除了提供重用之外,功能还可以(或替代地)提供组织代码并将其分解为更容易理解的更小单元的手段。以这种方式使用函数非常类似于创建包和类/模块,尽管处于更细粒度的级别。
答案 1 :(得分:15)
是。请。不要写长函数。写一些做一件事并做得好的短片。他们可能只被召唤一次的事实很好。一个好处是,如果您很好地命名您的函数,您可以避免编写将随着时间的推移与代码不同步的注释。
答案 2 :(得分:8)
如果我可以冒昧地引用Code Complete引用:
(这些原因的详细内容已经缩写,并且有点解释,完整的说明请参见完整的文字。)
创建例程的有效理由
请注意原因是重叠的,并不是相互独立的。
降低复杂性 - 创建例程的最重要原因是降低程序的复杂性(隐藏细节,这样您就不需要考虑它们了。)
引入一个中间的,可理解的抽象 - 将一段代码放在一个命名良好的例程中是记录其目的的最佳方法之一。
避免重复代码 - 创建例程的最常见原因。节省空间并且更易于维护(只需检查和/或修改一个地方)。
隐藏序列 - 隐藏处理事件的顺序是个好主意。
隐藏指针操作 - 指针操作往往难以阅读且容易出错。将它们分隔成例程将焦点转移到操作的意图而不是指针操作的机制。
提高可移植性 - 使用例程隔离不可移植的功能。
简化复杂的布尔测试 - 将复杂的布尔测试放入函数中会使代码更具可读性,因为测试的细节不在考虑之中,描述性的函数名称总结了测试。
提高效果 - 您可以在一个地方而不是几个地方优化代码。
确保所有例程都很小? - 否。由于有很多很好的理由将代码放入例程中,因此这是不必要的。 (这是列入名单的,以确保你注意!)
文本的最后引用(第7章:高质量例程)
最强大的心理障碍之一 创造有效的惯例是一种 不愿意创造一个简单的例程 出于简单的目的。构建一个 整个例程包含两个或三个 代码行似乎是 矫枉过正,但经验表明如何 有用的是一个很好的小例程。
答案 3 :(得分:5)
如果可以将一组陈述视为一种事物 - 那么将它们作为一种功能
答案 4 :(得分:5)
我认为这不仅仅是好的,我会推荐它!简单易于证明正确的函数与经过深思熟虑的名称导致代码比长期复杂函数更自我记录。
任何值得使用的编译器都能够内联这些调用,以便在需要时生成有效的代码。
答案 5 :(得分:4)
保持整洁有必要使用功能。您需要首先设计问题,然后根据您需要将它们分成函数所需的不同功能。多次使用的某些代码段可能需要在函数中编写。
我认为首先要考虑手头有什么问题,分解组件以及每个组件尝试编写一个函数。在编写函数时,查看是否有某些代码段执行相同的操作,然后将其分解为子函数,或者如果存在子模块,则它也是另一个函数的候选者。但是在某个时候这个突破性的工作应该停止,这取决于你。一般来说,不要做太多大功能而不是太多功能。
构造功能时,请考虑设计具有高内聚力和低耦合性。
<强> EDIT1:强>:
您可能还想考虑单独的模块。例如,如果您需要为某些应用程序使用堆栈或队列。使其成为可以从其他功能调用其功能的独立模块。这样,您可以通过将它们编程为一组单独存储的函数来保存重新编码的常用模块。
答案 6 :(得分:1)
我遵循一些指导原则:
这些原则中的每一个在某些时候都要求分解一个函数,尽管我认为#2可能意味着应该组合两个带有直线代码的函数。执行所谓的方法提取比实际将函数拆分为上半部分和下半部分更常见,因为通常的原因是提取不止一次调用的公共代码。
#1作为决策辅助非常有用。与我说的一样,“永远不会复制代码”。
即使没有重复的代码,#2也会给你一个很好的理由来分解函数。如果决策逻辑超过了某个复杂性阈值,我们会将其分解为更少的决策。
答案 7 :(得分:0)
将代码重构为函数确实是一种很好的做法,无论使用何种语言。即使你的代码很短,它也会使它更具可读性。 如果您的功能很短,您可以考虑将其内联。