Thread: Loop syntax battle!

  1. #1
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489

    Smile Loop syntax battle!

    Today, I have a collection of simple incremental loops to generate numbers between 0 to 9.

    A. "for" statement

    1. A common way to make a loop
    Code:
    for(i=0; i<10; i++)
    {
        printf("%d", i);
    }
    2. Strip the initialization
    Code:
    i = 0;
    
    for(;i<10; i++)
    {
        printf("%d", i);
    }
    3. Use ++ inside conditional statement
    Code:
    i = 0;
    
    for( ; i++<10; )
    {
        printf("%d", (i - 1));
    }
    4. Use ++ inside the loop
    Code:
    i = 0;
    
    for( ; i<10; )
    {
        printf("%d", i++);
    }

    B. "while" statement

    1.
    Code:
    i = 0;
    
    while(i<10)
    {
        printf("%d", i);
        i++;
    }
    2.
    Code:
    i = 0;
    
    while(i++<10)
    {
        printf("%d", (i - 1));
    }
    3.
    Code:
    i = 0;
    
    while(i<10)
    {
        printf("%d", i++);
    }

    C. "do-while" statement

    1.
    Code:
    i = 0;
    
    do
    {
        printf("%d", i);
        i++;
    }
    while(i<10);
    2.
    Code:
    i = 0;
    
    do
    {
        printf("%d", i);
    }
    while(++i<10);
    3.
    Code:
    i = 0;
    
    do
    {
        printf("%d", i++);
    }
    while(i<10);

    D. linear style

    1.
    Code:
    i = 0;
    
    loop:
    
        printf("%d", i);
        i++;
    
    if(i<10)
        goto loop;
    2.
    Code:
    i = 0;
    
    loop2:
    
        printf("%d", i);
    
    if(++i<10)
        goto loop2;
    3.
    Code:
    i = 0;
    
    loop3:
    
        printf("%d", i++);
    
    if(i<10)
        goto loop3;
    Btw, I need your suggestion...

    Which is nicest syntax for you? Why?
    Would you like to guess which is (type and run)faster after all?

    Is there another syntax? (maybe inline assembly, but I know nothing about this *sob*)

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Use for/next when the exact number of iterations is known in advance.

    Use while loop when the loop *may* not be entered into at all, and you need to test this before entering even the first loop iteration, and the exact number of iterations to be done is not known.

    Use do/while when the loop *must* be entered into and one iteration done, but the exact number of iterations is not known.

    Forget the rest, they're dumb.

  3. #3
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489
    Forget the rest, they're dumb.
    Do you mean linear style? Why dumb???

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Because goto is hated since it can jump all over the code and create mess.
    Stay away from goto.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    When there is a better standard loop style, it should be used. The "linear style" was needed in languages way back when the modern and standard loops of today, didn't exist.

    But no more. Goto's are unneeded except to escape from inside multiple loops and a few other rare situations.

    Don't use goto's otherwise, and that includes the "linear style" of looping. It looks like BASIC, from 20 years ago. I couldn't abide that style on any program, period.

  6. #6
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489
    How about the second question?

  7. #7
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    The first one is the best for me.
    Using ++ inside a conditional statement, or inside printf, might cause confusion, since it might not be that clear in a big code.
    Using for is preferred when the number of iterations are known.
    Initializing i makes the for loop more readable, since you don't have to search where i was initialized.

    The first one is like the "standard" way to do it. Since the example is very simple, standard methods would look nicer. Give us a more complicated example!

  8. #8
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217
    Quote Originally Posted by audinue View Post
    How about the second question?
    I suppose you could do it in an inefficient and limited way like this:

    Code:
    void DoCount(int start, int end)
    {
      if(start < end)
      {
        printf("&#37;i\n", start);
        DoCount(start + 1, end);
      }
    }
    
    int main()
    {
      DoCount(0, 10);
      return 0;
    }
    Last edited by 39ster; 07-16-2008 at 03:02 AM.

  9. #9
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Using inline assembly wouldn't make it "nicer". Probably neither faster, since it is too simple not to be optimized by the compiler.
    Though assembly code could be used if somebody wanted to use it.

    EDIT: Or for optimal results (:P)
    Code:
    printf("1");
    printf("2");
    printf("3");
    printf("4");
    printf("5");
    printf("6");
    printf("7");
    printf("8");
    printf("9");
    printf("10");
    Last edited by C_ntua; 07-16-2008 at 03:12 AM.

  10. #10
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    The common way is the best, nothing worse when someone tries to be smart and "invent" their own loop.

    Code:
    i = 0;
    for(;;)
    {
        if(i >= 10)
            break;
    
        ++i;
    }
    just because they can...

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Have you actually studied the difference in the code generated by the compile for those different bits of code?

    Using the two most extremely different cases in GCC as this:
    Code:
    #include <stdio.h>
    
    int main()
    {
      int i;
    #ifdef ALT1
      for(i=0; i<10; i++)
        {
          printf("%d", i);
        }
    #endif
    
    #ifdef ALT2
      i = 0;
    
     loop3:
      
      printf("%d", i++);
    
      if(i<10)
        goto loop3;
    #endif
     
      return 0;
    }
    we get from gcc -O2 -S and diff the two ALTx solutions:
    Code:
    *** a_alt1.s    2008-07-16 11:02:58.640347100 +0100
    --- a_alt2.s    2008-07-16 11:02:32.728512500 +0100
    ***************
    *** 18,30 ****
            call    ___main
            xorl    %ebx, %ebx
            .p2align 4,,15
    ! L5:
            movl    %ebx, 4(%esp)
            incl    %ebx
            movl    $LC0, (%esp)
            call    _printf
            cmpl    $9, %ebx
    !       jle     L5
            movl    -4(%ebp), %ebx
            xorl    %eax, %eax
            leave
    --- 18,30 ----
            call    ___main
            xorl    %ebx, %ebx
            .p2align 4,,15
    ! L2:
            movl    %ebx, 4(%esp)
            incl    %ebx
            movl    $LC0, (%esp)
            call    _printf
            cmpl    $9, %ebx
    !       jle     L2
            movl    -4(%ebp), %ebx
            xorl    %eax, %eax
            leave
    So the only difference is that the label has a different name.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by zacs7 View Post
    The common way is the best, nothing worse when someone tries to be smart and "invent" their own loop.

    Code:
    i = 0;
    for(;;)
    {
        if(i >= 10)
            break;
    
        ++i;
    }
    just because they can...
    And the likely scenario is that the compiler is better at optimizing the "basic" or "traditional" loop setup, and thus any deviance from the loop construction will reduce the chances of getting good code out of the compiler.

    Keep it simple and stupid, and let the compiler vendor worry about how to do things.

    By the way, I'd say it's fine to use a loop where the number of iterations are varaible. The condition for using a for-loop vs. while-loop is that a for-loop has the same initialization for all loops, a contion, and a proceed to next step. For example, a for-loop can be used to traverse a linked list:
    Code:
       node *p;
       for(p = head; p != NULL; p = p->next) ...
    But if something doesn't quite fit in a for-loop (e.g. there's no initialization or no proceed to next portions), then you PROBABLY should use a while-loop (or do-while, if you should always perform the loop at least once).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489
    Quote Originally Posted by 39ster View Post
    I suppose you could do it in an inefficient and limited way like this:

    Code:
    void DoCount(int start, int end)
    {
      if(start < end)
      {
        printf("%i\n", start);
        DoCount(start + 1, end);
      }
    }
    
    int main()
    {
      DoCount(0, 10);
      return 0;
    }
    Psstt... that's a recursion not iteration (loop)...

  14. #14
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    It's still a loop anyway

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by audinue View Post
    Psstt... that's a recursion not iteration (loop)...
    gcc actually understands that the tail recursion means the same thing as a traditional loop in this case, and generates code that just loops around like a for-loop, rather than recursion.

    I couldn't make the compiler inline DoCount, otherwise, I'd expect it to be very marginally different from the original code posted - after some further playing around, it appears that the problem is that it FIRST decides whether to inline the function or not, then decides to resolve the recursion as a loop.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. An error is driving me nuts!
    By ulillillia in forum C Programming
    Replies: 5
    Last Post: 04-04-2009, 09:15 PM
  2. Visual Studio Express / Windows SDK?
    By cyberfish in forum C++ Programming
    Replies: 23
    Last Post: 01-22-2009, 02:13 AM
  3. more then 100errors in header
    By hallo007 in forum Windows Programming
    Replies: 20
    Last Post: 05-13-2007, 08:26 AM
  4. Personal Program that is making me go wtf?
    By Submeg in forum C Programming
    Replies: 20
    Last Post: 06-27-2006, 12:13 AM
  5. loop issues
    By kristy in forum C Programming
    Replies: 3
    Last Post: 03-05-2005, 09:14 AM