Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
打印3、5和两者的倍数的C程序,专业风格建议_C_Modulo - Fatal编程技术网

打印3、5和两者的倍数的C程序,专业风格建议

打印3、5和两者的倍数的C程序,专业风格建议,c,modulo,C,Modulo,我编写了我的第一个简单C程序,它打印3,5的倍数,以及3和5的倍数,而不是数字,从1到100。它起作用了 我知道这个程序可以用百万种不同的方式编写。专业的C程序员如何实现最佳实践?作为一个完美主义者,我试图实现最高的最佳标准,主要是指针和专业的函数实现和预处理器 #include <stdio.h> void findMultiples(int n); int main() { findMultiples(100); return 0; }

我编写了我的第一个简单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;如果FizzBuzz可以被5分割但不能被3分割,那么应该打印FizzBuzz;如果FizzBuzz可以被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);
不过看起来还不错。但这真的值得吗?如果你想把嘶嘶声和嗡嗡声改长一点呢?然后,您需要确保str有更多的空间,这很容易忘记,并且可能导致难以跟踪的bug。我并不是说这个代码非常危险,但这里的底线是你如何推理。这种风险真的,真的值得避免一些代码重复吗

有些人将条件重构为函数,比如bool dividable_by_15int 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      (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 put

但是,在我看来,我已经在这个问题上花费了相当多的精力

作为一个完美主义者,我正在努力实现最高的标准

我读到了一句名言,它完美地回答了这个问题:盲目地遵循最佳实践并不是最佳实践

最佳实践的目的是提供一种非常简单的方法来实现某些目标。如果您的代码在没有遵循最佳实践的情况下实现了这一目的,为什么要更改它?特别是如果它更好地实现了这个目的。

这是基本上你应该打印FizzBuzz的地方,如果FizzBuzz可以被5和3分开,如果FizzBuzz可以被5分开但不能被3分开,如果Buzz可以被3分开但不能被5分开

TL;博士 没有正确的方法可以做到这一点。无论你怎么做,你都会打破一些最佳做法

长篇大论 注意

我是那种喜欢 rs是一种灵活的最佳实践和代码标准方法。这不是对的,也不是错的,但是下面的整个文本是由我的个性决定的。我非常喜欢这个测试,因为你能理解什么时候跳过最佳实践,而其他人会认为,即使在棘手的情况下,你也能想出如何遵循最佳实践。没有一个比另一个更正确

这个问题本来很容易理解,但做得好却很棘手。在本例中,您经常会遇到重复的代码。您可以很容易地构建它,但通常会以可读性为代价

如果我要设计一个符合您要求的代码,我会非常满意您提供的解决方案,然后继续下一个问题。这真的不值得花很多时间。这也是雇主在给你做这个测试时要注意的一点。您是否花费数小时和数天的时间来确保您的代码遵循所有最佳实践(即使收益微乎其微),或者您是否创建了有效且可读的代码,并在足够好的情况下继续前进

我看到的一些例子是连接字符串,它们避免了首先检查它是否可以被两个数字除,然后分别检查它们。类似这样的东西:

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);
不过看起来还不错。但这真的值得吗?如果你想把嘶嘶声和嗡嗡声改长一点呢?然后,您需要确保str有更多的空间,这很容易忘记,并且可能导致难以跟踪的bug。我并不是说这个代码非常危险,但这里的底线是你如何推理。这种风险真的,真的值得避免一些代码重复吗

有些人将条件重构为函数,比如bool dividable_by_15int 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      (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 put

但是,在我看来,我已经在这个问题上花费了相当多的精力

作为一个完美主义者,我正在努力实现最高的标准

我读到了一句名言,它完美地回答了这个问题:盲目地遵循最佳实践并不是最佳实践


最佳实践的目的是提供一种非常简单的方法来实现某些目标。如果您的代码在没有遵循最佳实践的情况下实现了这一目的,为什么要更改它?尤其是如果它更好地实现了这个目的。

您假设有人在读取输出。此外,程序并没有按照你说的那样做。它不打印3和5的倍数,而是忽略它们

一般来说,我会阅读被询问的内容,然后确定程序将如何使用,然后编写程序。 在您的情况下,这将类似于:

#include <stdio.h>

void findMultiples(int n)
{
    for (int i = 1; i <= n; i++)
        if ((i % 3 == 0) || (i % 5 == 0)) {
            printf("%d\n", i);
        }
    }
}

int main()
{   
    findMultiples(100);

    return 0;
}
编码风格并不那么重要

现在我为什么要从关于人类的评论开始呢。嗯,小程序通常被设计成连锁逻辑。为什么非人类会对你打印的文本感兴趣


我不认为这个答案是您最初想到的,但我希望它能帮助您以稍微不同的方式思考您的程序。

您假设一个人正在阅读输出。此外,程序并没有按照你说的那样做。它不打印3和5的倍数,而是忽略它们

一般来说,我会阅读被询问的内容,然后确定程序将如何使用,然后编写程序。 在您的情况下,这将类似于:

#include <stdio.h>

void findMultiples(int n)
{
    for (int i = 1; i <= n; i++)
        if ((i % 3 == 0) || (i % 5 == 0)) {
            printf("%d\n", i);
        }
    }
}

int main()
{   
    findMultiples(100);

    return 0;
}
编码风格并不那么重要

现在,我为什么要从对一个问题的评论开始呢 人类嗯,小程序通常被设计成连锁逻辑。为什么非人类会对你打印的文本感兴趣


我不认为这个答案是您最初想到的,但我希望它能帮助您以稍微不同的方式思考您的程序。

您的实现是可能的最佳实现

对许多程序员来说,两次检查模条件是不令人满意的,而且案例的实现感觉它们非常相似,可以折叠在一起。因此,我们中的许多人都会想方设法消除明显的冗余

然而,这些技巧总是增加代码的复杂性。事实是,正如你所写的,这四个案例很容易理解。而且,没有任何可以尝试消除明显冗余的技巧可以让它变得更简单

最后,简单胜过聪明。我们知道这就是吻的原则:保持简单,愚蠢。高质量的软件不追求智能,而是追求简单。这使得它更易于维护、扩展和使用。要优化的最重要变量是代码的简单性。最聪明的程序员会把他们的智慧牢牢地拴在绳子上,只有在需要的时候才会释放出来

也就是说,作为纯粹的文体评论,通常不建议在复杂循环体或if中省略大括号。我会将您的代码格式化为:

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);
        }
    }
}
否则,您总是冒着弄乱属于循环/如果的内容和不属于循环/如果的内容的风险


此外,函数的命名也是次优的。我想,我会把它叫做printDivisibilityList。由于该函数找不到倍数,因此它会打印所有数字,并用它们被3和5整除的情况对它们进行注释。

您的实现是可能的最佳实现

对许多程序员来说,两次检查模条件是不令人满意的,而且案例的实现感觉它们非常相似,可以折叠在一起。因此,我们中的许多人都会想方设法消除明显的冗余

然而,这些技巧总是增加代码的复杂性。事实是,正如你所写的,这四个案例很容易理解。而且,没有任何可以尝试消除明显冗余的技巧可以让它变得更简单

最后,简单胜过聪明。我们知道这就是吻的原则:保持简单,愚蠢。高质量的软件不追求智能,而是追求简单。这使得它更易于维护、扩展和使用。要优化的最重要变量是代码的简单性。最聪明的程序员会把他们的智慧牢牢地拴在绳子上,只有在需要的时候才会释放出来

也就是说,作为纯粹的文体评论,通常不建议在复杂循环体或if中省略大括号。我会将您的代码格式化为:

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);
        }
    }
}
否则,您总是冒着弄乱属于循环/如果的内容和不属于循环/如果的内容的风险


此外,函数的命名也是次优的。我想,我会把它叫做printDivisibilityList。因为函数找不到倍数,所以它会打印所有数字,并用它们的3和5整除性对它们进行注释。

您可以稍微修改缩进,通常{对于函数位于行之后,对于具有多行的for循环,建议将其括起来{}。另一件事,几乎是个人的偏好,是让函数返回值而不是无效假设代码工作,那么这个问题就在主题上,应该被问到。此外,边界线意见是基于太广泛的。虽然这个特殊的小算法是众所周知的Fizz Buzz算法。如果你搜索Fizz Buzz optimization和类似的功能,您可以在网上找到大量的示例。例如,这是一个针对Java on CR的示例:代码将对15个连续数字的序列执行39次模运算。您可以通过始终执行i%3==0和i%5==0运算并存储其结果,将其减少到30次模运算。除法和模运算离子相对昂贵。void findMultiplesint n;坏名称…函数不会在任何地方搜索find所暗示的任何内容。我将其命名为printMultiples。另外,传递计算倍数的基数…并返回打印的倍数数可能是一个好主意?int printMultiplesint limit,int*bases;此新版本可以d被称为int p=printMultiples100,int[]{3,5,0};您可以稍微修改缩进,通常{对于函数位于行之后,对于具有多行的for循环,建议将其封闭{}。另一件事,几乎是个人的偏好,是让函数返回值而不是无效假设代码工作,那么这个问题就在主题上,应该改为在上提问。因此,边界线意见是基于的,而且过于广泛。尽管如此
特别的小算法是著名的fizzbuzz算法。如果你搜索Fizz Buzz优化和类似的东西,你会在网上找到很多例子。例如,对于CR上的Java:代码将对15个连续数字的序列执行39个模运算。您可以通过始终执行i%3==0和i%5==0操作并存储其结果,将其减少到30个模运算。除法和模运算相对昂贵;坏名声。。。函数不会在find所暗示的任何地方搜索任何内容。我把它命名为“打印倍数”。此外,传递计算倍数所依据的基数也是一个好主意。。。和返回打印的倍数?整数打印倍数极限,整数*基数;这个新版本可以称为int p=printMultiples100,int[]{3,5,0};可能取决于雇主是否优先考虑质量或上市时间。@Lundin是的,我在这一点上加了一些强调。这可能取决于雇主是否优先考虑质量或上市时间。@Lundin是的,我在这一点上加了一些强调。我确实希望程序省略数字,只打印文本。我会研究你的代码。啊,我知道我犯了一个初学者的错误。在你编辑完问题后,我引用了你的话。幸运的是,每个人都能看到。我确实希望程序省略数字,只打印文本。我会研究你的代码。啊,我知道我犯了一个初学者的错误。在你编辑完问题后,我引用了你的话。幸运的是,每个人都能看到这一点。函数名确实是我在深入研究之前应该想到的东西。这种款式看起来干净多了。谢谢你给我的酒好分数。函数名确实是我在深入研究之前应该想到的东西。这种款式看起来干净多了。谢谢你的提示