首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >FizzBuzz挑战

FizzBuzz挑战
EN

Code Review用户
提问于 2015-02-02 20:31:05
回答 2查看 455关注 0票数 12

这段代码是一个很小的游戏,可以看你玩了多长时间的FizzBuzz游戏而不搞砸。

代码:

代码

的顶部

代码语言:javascript
运行
复制
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef enum {false, true} boolean;
typedef enum {FIZZ, BUZZ, FIZZBUZZ} FB;

int n = 0; // the number that is being incremented
char input[256];

boolean user_turn(void);
FB n_fizz_buzz_fizzbuzz(void); // is n or fizz or buzz or fizzbuzz

main函数

代码语言:javascript
运行
复制
int main(void) {
    boolean should_loop = true;
    while(should_loop) {
        n++;
        printf("Number: %d\n", n);
        should_loop = user_turn();
    }
    return 0;
}

user_turn函数

代码语言:javascript
运行
复制
/*
Prompts the user for the answer
*/
boolean user_turn(void) {
    FB correct = n_fizz_buzz_fizzbuzz();
    scanf("%s", input);
    if(!((strcmp(input, "fizzbuzz") == 0 && correct == FIZZBUZZ) || (strcmp(input, "fizz") == 0 && correct == FIZZ) || (strcmp(input, "buzz") == 0 && correct == BUZZ) || (atoi(input) == n && correct == n))) {
        printf("Sorry! That is incorrect.\nScore: %d\n", n - 1);
        return false;
    }
    return true;
}

n_fizz_buzz_fizzbuzz函数

代码语言:javascript
运行
复制
/*
Returns the correct answer either:
FIZZBUZZ(2)
BUZZ(1)
FIZZ(0)
n
*/
FB n_fizz_buzz_fizzbuzz(void) {
    if(n % 15 == 0)
        return FIZZBUZZ;
    if(n % 5 == 0)
        return BUZZ;
    if(n % 3 == 0)
        return FIZZ;
    return n;
}

的工作方式:

  1. 该号码被记录到控制台。
  2. 用户输入他们的答案,或者是FizzBuzz,Fizz,Buzz,或者是被记录的号码。
  3. 如果他们不正确,游戏就结束了。
  4. 如果它们是正确的,则数字递增1,此过程返回到步骤1。

我的主要关注点:

  • 这可能只适用于Java,但是单独的(非主)函数应该使用输入和输出吗?
  • 枚举类型合适吗?还是它们造成了太多的麻烦?
  • 有什么重复的吗?
  • 有效率低下吗?
  • 有不一致之处吗?
  • 是否有遗漏的不良做法或做法?

任何其他建议都受到欢迎和鼓励。

EN

回答 2

Code Review用户

回答已采纳

发布于 2015-02-06 01:33:45

我的建议:

  • 使用fgets代替不安全的scanf("%s",...)
  • user_turn()中的长行拆分为几行。
  • 不要使用局部变量和函数参数可以轻松完成任务的全局变量。
  • 如果您需要使用文件范围全局文件,请声明它们为static,以避免链接时的麻烦。
  • 我建议使用for循环而不是while循环: for (n=1;should_loop;n++) {

我很抱歉地说,我不同意你的自我代码审查的三点,关于这个特定的程序。

  1. C (Kernighan,Ritchie,Thompson,Pike,et.al)的创建者和核心循环不使用单个语句的大括号。虽然这确实是新手的陷阱,但我建议有经验的程序员最好遵循K&R“标准”编码风格。例如,Linux源代码似乎倾向于没有块的单一语句。至于我,我做了一个C前处理器,自动添加大括号,使两个世界的最佳国际海事组织。代码示例:sam.nipl.net/例如/谱

Linux源代码示例: github.com/torvalds/linux/blob/master/kernel/events/core.c Linus给出了一些关于编码风格的非常好的建议,它的幽默和智慧值得一读。一些最好的部分:

首先,我建议打印一份GNU编码标准的副本,而不是阅读它。烧掉它们,这是一个伟大的象征姿态。如果你需要超过3个等级的缩进,你无论如何都会失败,并且应该修复你的程序。“

  1. 同样,我认为K&R风格倾向于将一个简短的enum放在一行中,就像您最初做的那样。好吧,我本来打算引用Plan 9的源代码,但是他们似乎更喜欢按你的方式做,把最短的enum分割成四行!我检查了“编程的实践”,在这个例子中,Kernighan和Pike似乎同意我的观点,他们用一个简短的enum一行行,然后用注释将事情分割成一个更长的enum (这很有道理)。
  2. 在这种情况下,我认为n++printf中可能会被忽略。我会使用一个for循环,把所有的循环控制都放在一个地方是很好的。
票数 4
EN

Code Review用户

发布于 2015-02-02 21:15:34

Braces

在您的n_fizz_buzz_fizzbuzz函数中,我注意到在if/and语句之前和/或之后没有{s或}s。您应该始终拥有这些,因为bug可能会引起如果它们不存在。

这个函数应该写成这样:

代码语言:javascript
运行
复制
FB n_fizz_buzz_fizzbuzz(void) {
    if(n % 15 == 0) {
        return FIZZBUZZ;
    }
    if(n % 5 == 0) {
        return BUZZ;
    }
    if(n % 3 == 0) {
        return FIZZ;
    }
    return n;
}

压痕

这是没有必要的,但有时缩进会使事情看起来更好。

例如,您的枚举可以缩进:

代码语言:javascript
运行
复制
typedef enum {
    FIZZ, 
    BUZZ, 
    FIZZBUZZ
} FB;

唯一的缺点是,如果这让你感到困扰的话,这件事现在占用了更多的空间。

组合线

这也不是完全必要的,但它从您的main功能中删除了一行。

这是:

代码语言:javascript
运行
复制
n++;
printf("Number: %d\n", n);

会变成这样:

代码语言:javascript
运行
复制
printf("Number: %d\n", ++n);

注意,n++变成了++n。一定是这样写的。

n++n递增1,并在其增量之前返回n的值。

++nn递增1,并返回n的新值。

例如,

代码语言:javascript
运行
复制
int n = 7;
printf("%d\n", n++); // ==> 7
// n = 8
printf("%d\n", ++n); // ==> 9
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/79389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档