The program below correctly calculates factorials, until the limit for an unsigned long long integer is exceeded.My question has to do with loops and exiting loops. The program uses one infinite while loop and the break statement to exit 2 while loops.Do working, professional programmers handle loops this way? If not, how would they write and exit these loops?/* factorial.c   program to calculate factorials until the limit for an unsigned long long   integer is exceeded   20! =    2,432,902,008,176,640,000   limit = 18,446,744,073,709,551,615   21! =   51,090,942,171,709,440,000*/#include <stdio.h>#include <limits.h>unsigned long long int factorial (int i){    // function returns 0 when limit exceeded    int j;    unsigned long long int result;    if ( i == 0 )        result = 1;    else {        result = i;            j = i - 1;        while ( j >= 1 ) {            if ( result <= ULLONG_MAX / j )                    result *= j;            else {                result = 0;                break;            }            --j;            }    }        return result;}int main (void){    int i;    unsigned long long int number;    printf (\nTABLE OF FACTORIALS\n\n);    printf ( n            n!\n);    printf (-- ------------------------\n);    i = 0;    while ( 1 ) {        number = factorial (i);        if ( number == 0 )            break;               printf (%2i %24llu\n, i, number);        ++i;    }    return 0;}
Factorials, loops, break and professional code
c
I guess it's as much a matter of taste as it is of existing coding guidelines that you have to abide by.I'd be fine with early returns. Thus, I wouldn't have an else clause, just if (i == 0) { return 1; } followed by what's inside your else clause.Ditto for the case where result > ULLONG_MAX / j: just an early return.I guess early returns are easier to grok in short functions than in longer functions; and on the other hand, there is certainly an argument to be made to have just a single return point*.For the second while loop in main, I would perhaps replace it with a for loop, as I feel that states the intention a bit better.Arguably, the condition may need to be constant there, or perhaps the maximum allowed value for i.And you could shuffle a few lines around to have the check for number != 0 inside the loop (that does put an extra call to factorial just outside such a for loop).All in all, it largely feels like picking nits. Pick a coding style you're happy with, possibly abiding by some good standards that people have drafted, and stick with it (until people give you a good explanation why you should do something else).I would slightly worry about the implicit int to unsigned long long cast; I haven't bothered looking up casting rules, but you are casting a potentially negative value to an unsigned variable. Are there any compiler warnings?*) One case I could imagine, is when you want to do some clean-up before exiting the function: free allocated memory, close files etc. By always exiting at the end of the function, were this clean-up happens, you don't repeat the clean-up code elsewhere. This also involves one of the very few cases where goto serves a good purpose in C (well, not everyone will agree on that): it becomes the C equivalent of a defer or finally statement. Of course, here it's not needed.