c - 打印 3、5 和两者的倍数的 C 程序,专业风格建议
问题描述
我编写了我的第一个简单的 C 程序,它打印 3 、 5 以及 3 和 5 的倍数,而不是数字,从 1 到 100。它有效。
我知道这个程序可以用数百万种不同的方式编写。专业的 C 程序员将如何实施最佳实践?作为一个完美主义者,我正在尝试实现最高的最佳标准,主要是指针和专业的函数实现和预处理器。
#include <stdio.h>
void findMultiples(int n);
int main() {
findMultiples(100);
return 0;
}
void findMultiples(int n){
for (int i = 1; i <= n; i++)
if (i % 15 == 0){
printf("Multiple of 3 and 5\n");
}
else if (i % 5 == 0){
printf("Multiple of 5\n");
}
else if (i % 3 == 0){
printf("Multiple of 3\n");
}
else{
printf("%d\n", i);
}
}
解决方案
这基本上是Fizzbuzz,如果它可被 5 和 3 整除,则应打印 FizzBuzz,如果可被 5 整除但不能被 3 整除,则应打印 Fizz,如果可被 3 但不能被 5 整除,则应打印 Buzz。
TL;博士
没有“正确”的方法可以做到这一点。不管你怎么做,你都会破坏一些最佳实践。
长解释
笔记!
我是那种喜欢灵活方法来实现最佳实践和代码标准的程序员。这没有对错,但下面的整个文字都被我的个性所着色。我几乎将此测试视为“您能理解何时跳过最佳实践”,而其他人则将其视为“即使在棘手的情况下,您也能弄清楚如何遵循最佳实践”。没有一个比另一个更正确。
这个问题旨在非常容易理解,但要“很好”地做到这一点非常棘手。在此示例中您经常会遇到的一件事是重复代码。您可以很容易地构建它,但通常以可读性为代价。
如果我要设计一个符合您要求的代码,我会对您提供的解决方案非常满意,然后继续处理下一个问题。真的不值得花很多时间在上面。这也是雇主在给您进行此测试时会考虑的事情。您是否花费数小时和数天来确保您的代码遵循所有“最佳实践”,即使收益微不足道,或者您是否创建了有效且可读的代码,并且一旦足够好就继续前进?
我见过的一些示例可以避免首先检查它是否可以被两个数字整除,然后分别检查它们是否连接字符串。像这样的伪:
string str = ""
if n % 5 = 0: str += "Fizz"
if n % 3 = 0: str += "Buzz"
print str
看起来不错,对吧?好吧,把它翻译成真正的 C 语言,字符串处理非常混乱。
char str[9] = "";
if(n%5 == 0) strcat(str, "Fizz");
if(n%3 == 0) strcat(str, "Buzz");
puts(str);
不过看起来也不算太糟糕。但这真的值得吗?如果您想将“Fizz”和“Buzz”更改为更长的名称怎么办?然后你需要确保它str
有更多的空间,这很容易忘记并且可能导致难以追踪的错误。我并不是说这段代码非常危险,但这里的底线是你的推理方式。这种风险真的非常值得为避免一些代码重复而付出努力吗?
有些人将条件重构为函数,例如bool dividable_by_15(int n)
因为“在单独的函数中分解功能很好”。有些人甚至会做到这一点:
bool dividable_by(int n, int d) { return (n%d) == 0; }
bool dividable_by_3(int n) { return dividable_by(n, 3); }
bool dividable_by_5(int n) { return dividable_by(n, 5); }
bool dividable_by_15(int n) { return dividable_by_3(n) && dividable_by_5(n); }
但在这种情况下真的需要吗?我不这么认为,但我不会说选择是 100% 显而易见的,而且它还取决于您使用的语言。但在大多数情况下,我会说这是一个非常明显的过度工程案例。
这个测试不是看你是否能遵循所有的最佳实践。这更像是一个性格测试。一些雇主希望你做各种各样的事情,而另一些雇主则更喜欢你可以在它应该做的时候让代码保持原样。
对于您的代码,我实际上只有一个反对意见,那就是您省略了 for 循环的大括号。我永远不会那样做,除非身体是一条简单的线。但是,我会省略 if 语句的大括号。有些人会同意最后一个,有些人不会。那些即使对于单个语句也总是使用大括号的人经常使用这样的论点,即如果您需要在正文中添加额外的语句,它会降低错误的风险。另一个论点是一致性,即你总是应该努力在任何地方做同样的事情。在我看来,这些因素不值得多加几行,但是嘿,那就是我。你做你。
for (int i = 1; i <= n; i++) {
if (i % 15 == 0)
printf("Multiple of 3 and 5\n");
else if (i % 5 == 0)
printf("Multiple of 5\n");
else if (i % 3 == 0)
printf("Multiple of 3\n");
else
printf("%d\n", i);
}
这对我来说看起来好多了。我什至会考虑将 if 作为一个衬垫:
if (i % 15 == 0) printf("Multiple of 3 and 5\n");
else if (i % 5 == 0) printf("Multiple of 5\n");
else if (i % 3 == 0) printf("Multiple of 3\n");
else printf("%d\n", i);
我也会考虑提取换行符,如下所示:
if (i % 15 == 0) printf("Multiple of 3 and 5");
else if (i % 5 == 0) printf("Multiple of 5");
else if (i % 3 == 0) printf("Multiple of 3");
else printf("%d", i);
printf("\n");
由于它只是一个新行,您可以更改printf("\n")
为 just puts("")
。
但是-事情就是这样-在我看来,我已经在这个问题上花费了很多精力。:)
作为一个完美主义者,我正在努力实现最高的最佳标准
我读到的一句话完美地回答了这个问题:“盲目遵循最佳实践不是最佳实践”
“最佳实践”旨在提供一种非常简单的方法来实现某些目标。如果您的代码在没有遵循最佳实践的情况下实现了该目的,为什么要更改它?特别是如果它更好地实现了这个目的。
推荐阅读
- jquery - 仅在首页 Wodpress 查询中排除类别
- vb.net - 将 LINQ 表达式结果返回到命名/强类型变量
- r - 为什么我不能在 ggplot 中的点和错误栏之间划一条线?
- c++ - 两条日志线在c++中与log4Cxx混合
- java - 类和对象之间的编码差异
- python - 在 BeautifulSoup (Python) 中找不到亚马逊重定向的 url。从哪里获得重定向网址的任何想法?
- html - Xslt在不同语言的不同规则的字符串之间获取文本
- c# - 如何在 Windows 窗体 C# 中一次将两个文件发布到 API
- javascript - XSS 黑名单/白名单
- grafana - 无法在 Grafana 4.5.2 中管道模板变量