Fizzbuzz program in C

馋奶兔 提交于 2019-12-11 01:29:17

问题


Okay, this really isn't as much a fizzbuzz question as it is a C question.

I wrote some simple code in C for printing out fizzbuzz as is required.

#include <stdio.h>

int main(void)
{
    int n = 30;
    int i;
    for (i = 1; i<=n; i++)
        printf("%s\n", (i % 15) == 0 ? "fizzbuzz" : (i % 5) == 0 ? "buzz" : (i % 3) == 0 ? "fizz" : i);
}

Now, the last else statement obviously doesn't work since printf is accepting a string whereas 'i' is an int. My question is, is there any sort of cast that I can apply to convert the 'i' into a string?

EDIT: I should mention, what I'm really asking is if this fizzbuzz test can be done using a single print statement. No particular reason why I want it to be a single print statement only other than curiosity of as to whether it can be done.

EDIT2: Question answered and here's my implementation:

#include <stdio.h>

int main(void)
{
    int i, n=30;        
    for (i = 1; i<=n; i++)
        printf((!(i%3) || !(i%5)) ? "%s\n" : "%d\n", !(i % 15) ? "fizzbuzz" : !(i % 5) ? "buzz" : !(i % 3) ? "fizz" : i);
}

http://codepad.org/DN7yBW99


回答1:


You've cornered yourself by the way you've tried to put all the logic inside of the printf call. It would be better to write it out the "slow" way first, then look for ways to optimize it afterward.

for (i = 1; i <= n; i++) {
    if (i % 15 == 0)
        printf("fizzbuzz\n");
    else if (i % 5 == 0)
        printf("buzz\n");
    else if (i % 3 == 0)
        printf("fizz\n");
    else
        printf("%d\n", i);
}

Addendum: Do it with just one printf...

/* The following code is NOT recommended... */

int isFizz     = (i % 3 == 0      ) ? 1 : 0;
int isBuzz     = (i % 5 == 0      ) ? 1 : 0;
int isFizzBuzz = (isFizz && isBuzz) ? 1 : 0;

printf(
    (isFizz || isBuzz) ? "%s\n" : "%d\n",
    (
        isFizzBuzz ? "fizzbuzz" :
        isFizz     ? "fizz"     :
        isBuzz     ? "buzz"     :
        i
    )
);

http://codepad.org/LMr5WdIm




回答2:


You can simplify the args to printf by passing the string literals as the format string, rather than using a %s to print them. This takes advantage of the fact that you know there are no % characters in "fizz" or "buzz". It's guaranteed to be safe to pass unused args to printf.

To make the source readable, pull the logic to select a format string out of the printf() itself, and store it in a local variable.

#include <stdio.h>
int main(void)
{
    int n=30;        
    for (int i = 1; i<=n; i++) {
        int fizzy = (i % 3 == 0);
        int buzzy = (i % 5 == 0);

        const char *fmt = (fizzy && buzzy) ? "fizzbuzz\n" :
                          fizzy            ? "fizz\n"     :
                          buzzy            ? "buzz\n"     :
                          "%d\n";
        printf(fmt, i);
    }
}

It can be good style, and possibly make better asm, to conditionally determine the args you're going to pass and then make one call, instead of writing out the same function call with different args. This can be good if most of the args you're going to pass are the same in different branches, which is not the case here.

Normally it's better to just use puts (implicit \n appended) or fputs to print constant strings that don't need formatting. Compilers know this, and even optimize printf("Hello World!\n"); or printf("%s\n", "Hello World!") to puts("Hello World!"); in trivial cases. This trick means that even the fixed-string prints still make a call to the more expensive printf. (Besides readability, this is one of the concrete reasons why it's not a great choice in this particular instance.)

gcc and clang compile this into asm that works the way the source does: printf always gets two args (in the rdi and rsi registers), but sometimes the format string doesn't use the 2nd arg. Change -O3 to -Os to make gcc use div instead of a multiplicative inverse.

They don't unroll the loop to match the modulo pattern, or strength-reduce the modulos to down-counters, or anything clever like you'd do in a hand-written asm FizzBuzz.

For a devious way to write a compact FizzBuzz, see CodeGolf.SE, where a %s%s%.d format string conditionally gets empty strings. The %.d is specifies a precision of 0. Non-zero integers print normally, but 0 prints as the empty string.




回答3:


EDIT Sorry... i just realized that this thread was for a C solution

Recursive implementation:

vector<string> FizzBuzz::execute(int n) {

    if(n == 0)
        return vector<string>();

    auto push = n % 15 == 0 ? "fizzbuzz" :
                n % 3 == 0 ? "fizz" :
                n % 5 == 0 ? "buzz" :
                to_string(n);

    auto execution = execute(n-1);
    execution.push_back(push);
    return execution;
}



回答4:


as suggested you could use itoa();. Sample code below.

#include <stdio.h>
#include <stdlib.h>
int main(){
int num=23;
char snum[3];
itoa(num,snum,10);
printf("%s",snum);
}

itoa is used to convert an int to a string, the parameters are as follows.

itoa(int num, char string [], int base);

The first parameter is the number you are converting. The second parameter is the string/char array you want to store the converted strong into. Lastly, the third parameter is the base the number to be converted is in.



来源:https://stackoverflow.com/questions/29574784/fizzbuzz-program-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!