Thread: any other way you'd write this?

  1. #1
    Registered User
    Join Date
    Jun 2007
    Posts
    17

    any other way you'd write this?

    Hi everyone,

    I'm learning c right now and doing the exercises from the book. The exercise prompts to write
    a counting program that prompts the user for three inputs:
    - beginning number to start counting from
    - ending number
    - increment number

    I wrote this:

    Code:
    #include <stdio.h>
    
    main()
    {
    
      int ifrom = 0;
      int ito = 0;
      int iby = 0;
    
      scanf("%d%d%d", &ifrom, &ito, &iby);
    
      do {
    
        printf("\n%d\n", ifrom);
        ifrom = ifrom + iby;
      } while ( ifrom - iby < ito ); // end do while loop
        } // end main function
    ok it seems to work but there is one thing that bothers me: in the while statement I have "ifrom - iby < ito" because (ifom < ito) counted numbers from ifrom to ito minus the increment (iby) which was wrong. Here's the question, how this can be written to work using only conditional operators without the "minus thing"

    And another question is, whether you know a better way to write this little program and could you please share with me your wisdom.

    Thanks for all the help guys,

  2. #2
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Maybe a FOR loop?

    Code:
    int i;
    for(i=ifrom; i<=ito; i=i+iby)
    {
    }

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    ok it seems to work but there is one thing that bothers me: in the while statement I have "ifrom - iby < ito" because (ifom < ito) counted numbers from ifrom to ito minus the increment (iby) which was wrong. Here's the question, how this can be written to work using only conditional operators without the "minus thing"
    Comparing with "less-than-or-equal" may-be?

    And another question is, whether you know a better way to write this little program and could you please share with me your wisdom.
    A for-loop should do well too.

    I'm not sure if Hungarian notation is considered good style in C. "to", "from", "by" - or "first", "last", "increment" are normal variable names, "ito", "iby" etc looks like one step towards obfuscation.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    I think the correct behavior is to stop as soon as ifrom is greater than ito (BTW, this assumes the increment is positive - if it was negative, you would be counting downward and the criterion would be >=, not <=), which the do-while loop doesn't necessarily do since it always executes at least once. Use a for or while loop instead.

  5. #5
    Registered User
    Join Date
    Jun 2007
    Posts
    17
    // wait, while writing this several other posts were made so there already could be a response to the question here


    Thanks anon. 'Less than or equal too' apparently works, I tried this before and it didn't work. Now I know why :-) - I was using '=<' instead of '<='.

    Now I was trying to rewrite this as a 'for' loop but I didn't know how to build the proper expression into the for (...) statement, normally if asked to do increments by 2 for example I'd use (...; x++, x++) but here since the increment is uncertain trouble begins. How would you rewrite this for loop in yet a simpler way? - I'm not very fond of the comparison in the loop.
    It wouldn't work if for example istart = 7 and increment = 2
    Code:
    #include <stdio.h>
    
    main()
    {
      int x;
      int ifirst = 0;
      int ilast = 0;
      int increment = 0;
      scanf("&#37;d%d%d", &ifirst, &ilast, &increment);
    
      for ( x = ifirst; x <= ilast; x++ ) {
        if (x % increment != 0)
          continue;
        else printf("\n%d\n", x);
      }
    }
    Thanks again for all the help guys,
    Last edited by withoutn; 07-15-2007 at 05:54 PM.

  6. #6
    Registered User
    Join Date
    Jun 2007
    Posts
    17
    ok I got all the advices
    and rewrote the for loop:

    Code:
    #include <stdio.h>
    
    main()
    {
      int x;
      int ifirst = 0;
      int ilast = 0;
      int increment = 0;
      scanf("&#37;d%d%d", &ifirst, &ilast, &increment);
    
      for ( x = ifirst; x <= ilast; x = x + increment) {
        
      printf("\n%d\n", x);
      }
    }
    and it works almost fine, but whenever somebody chooses ilast such that ilast - ifirst != 0 (mod increment) the program doesn't output anything but terminates right away. How would you fix it?

  7. #7
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    and it works almost fine, but whenever somebody chooses ilast such that ilast - ifirst != 0 (mod increment) the program doesn't output anything but terminates right away. How would you fix it?
    Hum i don't see any reason why the condition of the for loop (x <= ilast) would be false on the first iteration in the special case that ilast - ifirst != 0 (mod increment).

    Except if the user provided incorrect entry. You aren't doing any checking to see if it's the case. It's always good to check if the user provided good entry. One way to do this would looks like this

    Code:
    #include <stdio.h>
    
    #define FPURGE() while(getchar() != '\n')
    
    int main()
    {
    	int x;
    	int ifirst = 0;
    	int ilast = 0;
    	int increment = 0;
    	int i;
    
    	do
    	{
    		printf("Enter first, last and increment numbers: ");
    		i = scanf("%d %d %d", &ifirst, &ilast, &increment);
    		FPURGE();
    	} while (i != 3);
    
    	for (x = ifirst; x <= ilast; x = x + increment)
    	{    
    		printf("\n%d\n", x);
    	}
    
    	return 0;
    }
    What else can i say... am i missing something heh ?

  8. #8
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I'd solve this problem in the following way:

    1. Prompt the user for some numbers.
    2. Check the input so that first is less than last and increment is not zero
    3. Ensure that [first, last] is within the range of a long int.
    4. If 2 and 3 are true, than a loop should do the work.

    At least then you shouldn't have problems with integer overflow. Other than that, not that difficult really. Involving mod is a bit unnecessary I think.

  9. #9
    Registered User
    Join Date
    Jun 2007
    Posts
    17
    Ok all works fine. Thanks everyone for help.
    By the way, where can I look up things like FPURGE() and other functions that I need or don't know, for definition and proper usage?

  10. #10
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    I'd solve this problem in the following way:

    1. Prompt the user for some numbers.
    2. Check the input so that first is less than last and increment is not zero
    3. Ensure that [first, last] is within the range of a long int.
    4. If 2 and 3 are true, than a loop should do the work.
    I agree totaly with point no 2, and i guess everyone will agree, except if they like having infinite loop in their programs . (that said, we should check if increment is bigger than 0)

    But... i'm not sure to understand what you mean by "Ensure that [first, last] is within the range of a long int". This is necessary true since the int type can represent number only between INT_MIN and INT_MAX. The only way you could have a potentially infinite loop would be if last + increment < last (that's it, the sum of last + increment cause an integer overflow). But it's somehow a really special case for this kind of program. And after all, this program is just an example.

    By the way, where can I look up things like FPURGE() and other functions that I need or don't know, for definition and proper usage?
    FPURGE() is not an fonction, it's a macro i added to the code (look back at my last post). If you need more information about macro and the #define instruction, i saw there's a lot of information out there.
    Personnaly, i'm using this site when i need documentation of the C library. http://www.cplusplus.com/reference/clibrary/

  11. #11
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    generally
    x = x + increment
    can be written as

    x += increment

    which is more commonly used idiom
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  12. #12
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by foxman View Post
    But... i'm not sure to understand what you mean by "Ensure that [first, last] is within the range of a long int". This is necessary true since the int type can represent number only between INT_MIN and INT_MAX. The only way you could have a potentially infinite loop would be if last + increment < last (that's it, the sum of last + increment cause an integer overflow).
    Despite what you've said, it's reasonable to expect people to count from INT_MIN to INT_MAX or 0 to LONG_MAX. In fact there's no real problem with a smart user expecting to wrap around, but it's wrong. It is important that you read correct numbers from the user and ensure that they fit within the representable range, otherwise, a simple condition like num <= last would be perpetually true.

    But it's somehow a really special case for this kind of program. And after all, this program is just an example.
    It's one of the only ways the program fails to work. Even for an example, that's a pretty important oversight and really demonstrates laziness.
    Last edited by whiteflags; 07-15-2007 at 10:36 PM.

  13. #13
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    I'm still not exactly sure what you mean by
    It is important that you read correct numbers from the user and ensure that they fit within the representable range, otherwise, a simple condition like num <= last would be perpetually true.
    I mean, could you give me an example of a number that wouldn't fit in the representable range of an int knowing that this number is an int ? The user might enter a number too big to be representable by an int so that scanf() will store a number smaller than this one in the variable (one representable one) and the results won't be as the user expected, still, there won't be an infite loop except, like i said, last + increment < last. (in the case increment is > 0)

  14. #14
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Heres another example of what can go wrong:
    Code:
    #include <stdio.h>
    int main()
    {
        unsigned char max=255; //maximum value containable
        unsigned char inc=128; 
        unsigned char i;
        for(i=0; i<max; i+=inc) printf("%i\n",i); 
    }
    For the sake of simplicity I replaced ints with unsigned chars. max=255 and inc=128 would both be valid input without validation.

  15. #15
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I can provide an example, sure. mike_g has presented one also.

    Code:
    #include <stdio.h>
    #include <limits.h>
    
    void count ( long first, long last )
    {
      long c;
      for ( c = first; c <= last; c++ )
        printf( " %d", c );
      putchar( '\n' );
    }
    
    int main( void )
    {
      /** Each of these counting examples probably has problems with integer overflow because
      * the last number that breaks the count will overflow the limits of a long integer,
      * resulting in a loop that is perpetually true.
      * As I've been saying, you need to make sure that [first, last] is within
      * the range of a long, or whatever integral you choose.
      */
      count( LONG_MIN, LONG_MAX );
      count( 0, LONG_MAX );
      count( INT_MIN, INT_MAX );  /** Also overflows if sizeof int == sizeof long **/
    
      return 0;
    }
    Last edited by whiteflags; 07-16-2007 at 11:28 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 03-18-2006, 11:25 AM
  2. program to make a floppy write protected
    By shrijeetp in forum C Programming
    Replies: 1
    Last Post: 10-03-2005, 06:00 AM
  3. Reroute where programs write to
    By willc0de4food in forum C Programming
    Replies: 7
    Last Post: 09-21-2005, 04:48 PM
  4. Function to write string 3 times
    By Giggs in forum C++ Programming
    Replies: 15
    Last Post: 12-24-2002, 04:00 PM
  5. write(), read()
    By RedRum in forum C++ Programming
    Replies: 5
    Last Post: 06-09-2002, 11:45 AM