New Problem C programming book

Discussion in 'Mac Programming' started by cybrscot, Feb 22, 2011.

  1. cybrscot, Feb 22, 2011
    Last edited: Feb 22, 2011

    cybrscot macrumors 6502

    cybrscot

    Joined:
    Dec 7, 2010
    Location:
    Somewhere in Southeast Asia
    #1
    Hello,
    My new problem is...
    "Rearrange the square3.c program (an example in the book) so that the for loop initializes i, tests i, and increments i. Don't rewrite the program, in particular, don't use any multiplications."

    I really don't understand what they want here. If I do what they ask, and do the above processes in the for loop, then what do I do with the stuff that's already in the for loop?

    I think they want for (i = 1 ; i <= n ; ++i ), as now I have i initialized in the loop, i is tested against n, and it's incremented. But what does this do for the program? The book said, don't rewrite the program??? What? How is changing the loop not rewriting the program?

    Anybody have a clearer understanding of what they want?

    EDIT: The code below is the example from the book, not my code.

    Code:
    #include <stdio.h>
    
    main ()
    
    int i, n, odd, square;
    
    	printf ("This program prints a table of squares. \n") ;
    	printf ("Enter number of entries in table: ") ;
    	scanf ("%d", &n) ;
    	
    	i = 1 ;
    	odd = 3 ;
    	for (square = 1 ; i <= n; odd += 2) {
    		printf ("%10d%10d\n", i, square) ;
    		++i;
    		square += odd ;
    		
    		}
    		
    		return 0 ;
    }		
    	
     
  2. mydogisbox, Feb 22, 2011
    Last edited: Feb 22, 2011

    mydogisbox macrumors member

    Joined:
    Jan 16, 2011
    #2
    I think it's saying that the lines are out of order and you need to rearrange them so the program works correctly. From briefly inspecting the program, I think you can do it without actually changing any of the code other than moving lines.

    Hint: Maybe instead of "lines" I should say "statements" because I think the intent is for you to move the stuff inside the for loop as well. i.e. odd += 2

    Edit:
    Heh, sorry. Just saw that you already were changing the stuff inside the for statement.
     
  3. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #3
    Your code looks good to me. I think the book was just saying don't loop 1 to n and print square and square*square. I think the point was to get you incrementing odd properly.

    -Lee
     
  4. mydogisbox macrumors member

    Joined:
    Jan 16, 2011
    #4
    I think the other point is to show you how to get around multiplying by doing two adds. Multiplication is an expensive operation.
     
  5. cybrscot thread starter macrumors 6502

    cybrscot

    Joined:
    Dec 7, 2010
    Location:
    Somewhere in Southeast Asia
    #5
    Hey Lee, the code (program) was the books code, square3.c program that they want me to change. I only wrote the single for loop that you see. Were you in fact referring to the books code, or my one line code when you said my code looks fine to you?
     
  6. SidBala macrumors 6502a

    Joined:
    Jun 27, 2010
    #6
    I believe the point that the book wants to make is that you can have a for loop with multiple statements . For example:

    for(statement1,statement2,...; condition; statement1,statement2,..)

    like:

    for(x =0, y =0 ; x< N; x++, y *= x)


    So now look at the book's code and see what you can do with the

    Code:
    i= 1;
    odd= 3;
    and the

    Code:
    ++i;
    square += odd; 
    See if you can move these into the for(_____)
     
  7. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #7
    Not these days, unless you're on a fairly puny processor. Single-cycle multiplication has been around for years. Even older PowerPCs had single-cycle multiply-accumulate, which did a multiply and an addition in a single cycle.
     
  8. SidBala macrumors 6502a

    Joined:
    Jun 27, 2010
    #8
    That is only for this specific example.

    If you want to just square one number say N, you would have to do N adds.

    So instead of just N*N, you would have to add N, N times in a for loop. Now that would be nasty looking and certainly more expensive.
     
  9. Bill McEnaney, Feb 23, 2011
    Last edited: Feb 23, 2011

    Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #9
    Someone, I forget who, told us that multiplication was expensive. Sure, integer addition is faster than integer multiplication. My iMac adds faster than it multiplies. But when does loop overhead make repeated addition pricier than a multiplication instruction?
     
  10. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #10
    For all intensive purposes multiplying and addition of a fixed size primitive type like int or double takes the same amount of time. Or more precisely, each takes a constant amount of time. So use whichever is conceptually or programmatically easier for you.

    If you were say building an opaque data type to handle 512 bit binary numbers for encryption or something you would have to think much more carefully about which basic math operations you would chose to implement quickly, and which ones would use the more basic math operations to provide their higher functionality.
     
  11. cybrscot thread starter macrumors 6502

    cybrscot

    Joined:
    Dec 7, 2010
    Location:
    Somewhere in Southeast Asia
    #11
    Okay, I changed the code to include the items in the for loop. But what's wrong?


    Code:
    #include <stdio.h>
    
    main ()
    
    int i, n, odd, square;
    
    	printf ("This program prints a table of squares. \n") ;
    	printf ("Enter number of entries in table: ") ;
    	scanf ("%d", &n) ;
    	
    	
    	for (square = 1, i = 1, odd = 3 ; i <= n; odd += 2, ++i) {
    		printf ("%10d%10d\n", i, square) ;
    		
    		square += odd ;
    		
    		}
    		
    		return 0 ;
    }	

    Terminal output: What is all this??? The original square3.c program in my original post didn't compile either, and looked something like the below as well.

    Code:
    Scott-Deans-MacBook-Pro:documents scottdean$ gcc ~/documents/ch_6_7forloop.c
    /Users/scottdean/documents/ch_6_7forloop.c: In function ‘main’:
    /Users/scottdean/documents/ch_6_7forloop.c:7: error: expected declaration specifiers before ‘printf’
    /Users/scottdean/documents/ch_6_7forloop.c:8: error: expected declaration specifiers before ‘printf’
    /Users/scottdean/documents/ch_6_7forloop.c:9: error: expected declaration specifiers before ‘scanf’
    /Users/scottdean/documents/ch_6_7forloop.c:12: error: expected declaration specifiers before ‘for’
    /Users/scottdean/documents/ch_6_7forloop.c:12: error: expected declaration specifiers before ‘i’
    /Users/scottdean/documents/ch_6_7forloop.c:12: error: expected declaration specifiers before ‘odd’
    /Users/scottdean/documents/ch_6_7forloop.c:19: error: expected declaration specifiers before ‘return’
    /Users/scottdean/documents/ch_6_7forloop.c:20: error: expected declaration specifiers before ‘}’ token
    /Users/scottdean/documents/ch_6_7forloop.c:5: error: declaration for parameter ‘square’ but no such parameter
    /Users/scottdean/documents/ch_6_7forloop.c:5: error: declaration for parameter ‘odd’ but no such parameter
    /Users/scottdean/documents/ch_6_7forloop.c:5: error: declaration for parameter ‘n’ but no such parameter
    /Users/scottdean/documents/ch_6_7forloop.c:5: error: declaration for parameter ‘i’ but no such parameter
    /Users/scottdean/documents/ch_6_7forloop.c:20: error: expected ‘{’ at end of input
    Scott-Deans-MacBook-Pro:documents scottdean$ 
    
     
  12. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #12
    Take a look at your main ()... is something missing?

    -Lee
     
  13. cybrscot, Feb 23, 2011
    Last edited: Feb 23, 2011

    cybrscot thread starter macrumors 6502

    cybrscot

    Joined:
    Dec 7, 2010
    Location:
    Somewhere in Southeast Asia
    #13
    Darn, I didn't notice it at all. Do less programming for the past couple days and look what happens! Was reading 1984 by George Orwell in case anybody is wondering what I was doing.

    Yeah, the program works, that was easy. But I don't yet understand why it works. I know I need, let's just say....a table of squares
    firstNumber 1 secondNumber 1
    firstNumber 2 secondNumber 4
    firstNumber 3 secondNumber 9

    But the code below, (while it works fine) I read it differently. What am I misreading? Of course the first row is 1 and 1, because i = 1 and square = 1. Then after incrementing, i =2 ( I have no problem with the i values, it's the square value that is confusing me) The second row needs to be 2 and 4. I have the 2. But since square += odd, I need to add odd to the square because of the += operator, right? Square started off as 1, and odd started out as 3, the third expression has odd adding 2 to itself, which makes it 5, then if I add the (odd 5) to the square (1), square now becomes 6. I need it to be 4.

    Or if I'm incorrect in modifying odd in that way, and let's say that odd just becomes 2, rather than adding 2 to its previous value, then adding 2 to square (which is 1) causes square to become 3, not 4.

    I can see that the original odd is 3, and if added to square, we get the 4 I'm looking for, but that disregards expr 3, where odd += 2

    Code:
    for (i = 1, square = 1, odd = 3 ; i <= n; odd += 2, ++i) {
    		printf ("%10d%10d\n", i, square) ;
    		
    		square += odd ;
    		
     
  14. jared_kipe, Feb 23, 2011
    Last edited: Feb 23, 2011

    jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #14
    The odd +=2; command will only call at the end of each loop, and before the i<=n; is evaluated.

    So If every line is a run through the loop at the line square += odd;
    square = 4 (odd = 3 , i = 1)
    square = 9 (odd = 5 , i = 2)
    square = 16 (odd = 7 , i = 2)

    etc.

    EDIT: This is probably the most confusing way of writing this snippit. Either just use one indexing variable "i" for the for loop or use a while loop.
    Code:
    int i = 1;
    int square = 1;
    int odd = 3;
    while ( i <= n ) {
    	printf ("%10d%10d\n", i, square) ;
    		
    	square += odd;
    	i++;
    	odd += 2;
    }
    
     
  15. cybrscot, Feb 23, 2011
    Last edited: Feb 23, 2011

    cybrscot thread starter macrumors 6502

    cybrscot

    Joined:
    Dec 7, 2010
    Location:
    Somewhere in Southeast Asia
    #15
    Thanks for the reply, I have to do this problem this way as it is what the book asked for.
    I still don't follow you. I don't see how you did the math in the above to get what you got. I know I need square to be 4 and 9 and 16. I assume that the first line you wrote above is the first row of squares? But when i = 1, it's square is also 1, not 4. I see how you got the odds, it started as 3, then 2 was added to it and it became 5, then 2 was added to that and it became 7. I don't understand how your third line can have i =2?? i was 2 in the previous line, then it would increment itself again and become 3. As you can see in the terminal output below 1 must go with 1, and the second line, i is 2 and square is 4, then in the 3rd line i is 3 (i was 2, then incremented to become 3)and square is 9.


    Code:
    This program prints a table of squares. 
    Enter number of entries in table: 12
             1         1
             2         4
             3         9
             4        16
             5        25
             6        36
             7        49
             8        64
             9        81
            10       100
            11       121
            12       144
    

    Code:
    for (i = 1, square = 1, odd = 3 ; i <= n; odd += 2, ++i) {
    		printf ("%10d%10d\n", i, square) ;
    		
    		square += odd ;
    		
    The only way I can get this to work in my mind is like this.

    first print is 1 and 1, they are both already given

    second print is 2 and 4, the only way I can come up with 4 is to add odd = 3 to the square = 1, which is 4, but I don't see anywhere in the code where I'm allowed to add only 3. After the first print odd adds 2 to itself and should become 5, but anyway, let's continue

    third print is 3 and 9, the way I got 9 was because square was 4 in the previous print, so to get 9, 5 must have been added to square. I can get 5 by FINALLY adding odd 2 to itself of 3, and odd becomes 5 which is added to square of 4 to get 9. BUT, at this point this step should have been done in the second print. Why would we ignore adding odd to itself in the second print, but not in the third? Odd should have been 5 already if we added 2 to itself in the second print of squares. So in this "third" print, it should now be 7.

    fourth print is 4 and 16. I can get 16 by taking the previous square of 9 and adding 7. Where did I get 7 from? Because odd was apparently 5 in the previous line, now if we add 2 more to odd, it becomes 7, then add odd 7 to square of 9, we get 16.

    So this can go on and on. It all makes sense, except for the fact that our 2nd row of squares seems to conveniently ignore the adding of 2 to odd somehow. I can understand this happening in the first line of 1 and 1, because they are given and nothing needs to be added or modified yet. Simply print i and print square for the first row. But the second row will have seen us go through the entire "for" loop after printing the first row of squares. After all, i is getting incremented after that first run through and it becomes 2. So why wouldn't odd get added to itself and become 5 after that first run through?
     
  16. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #16
    I'm putting what square evaluates to after the += bit. Sounds like maybe you should switch the order of your printf and square += lines. So that square is the value you want when you print it. If that is what you are wanting, honestly I'm not 100% sure what you are actually trying to achieve.
     
  17. angryboffin macrumors newbie

    Joined:
    May 7, 2008
    Location:
    London
    #17
    I think that you're correct in that they want the for loop to be for (i = 1 ; i <= n ; ++i ) . I also think that what they mean by not re-writing the program is that they want you to achieve this only by moving instructions around, not by changing the instructions - i.e. that i = 1 has to be taken from somewhere in the code, as does ++i, while the original occupants, square = 1 and odd +=2 have to be moved to other places in the code. Other code movements are allowed also.
    That's my understanding of it.
     
  18. chown33, Feb 23, 2011
    Last edited: Feb 23, 2011

    chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #18
    Your analysis is wrong because you're not breaking down the parts of the for-loop into the right sequence.

    When you have a for-loop like this:
    Code:
    for ( setup;  condition;  iteration )
    {  body;  }
    
    It transforms into this equivalent while-loop:
    Code:
     setup;
    while ( condition )
    {
      body;
      iteration;
    }
    
    So take your existing for-loop code and do the transformation. I don't mean "imagine doing it", I mean actually do it by writing each part in the proper place in the actual code. You should be able to confirm the correctness of your transformation by compiling it (it should compile) and running it (it should run) and checking the output (it should be identical to the for-loop version). Post the complete resulting code.

    Now, go back to your stated analysis:
    Walk through the transformed loop once and write out the values of odd and square after each statement (i.e. after each semicolon between the {}'s of the loop body). Show your work.

    Now, with the values written out, walk through the loop once more, writing out the values again. Show your work.

    If you encounter any unexpected value at any point in the step-by-step analysis, stop and show your work up to that point.


    Continuing on after getting an unexpected result isn't helping anything, it's just compounding the problem by distracting you from the point where the problem actually occurs. For example, suppose you had stopped at the underlined part above, instead of going on with this:
    This is just racing off into one faulty conclusion after another, instead of focusing on the first point where things didn't happen as expected. That first point of disparity between expectation and actuality is I don't see anywhere in the code where I'm allowed to add only 3. But if you transform the for-loop correctly, and step through the result, you should be able to see a point in the code where 3 is being added.

    At every step you should write down what you expect to happen and what actually happens. If there is a disparity, then something is wrong with either your expectation or your code (or both). If you haven't broken things down far enough, or you've broken them down incorrectly, then a string of faulty conclusions won't solve either of those problems.
     
  19. angryboffin, Feb 23, 2011
    Last edited: Feb 23, 2011

    angryboffin macrumors newbie

    Joined:
    May 7, 2008
    Location:
    London
    #19
    EDIT: Ignore code samples below - they weren't compiled and tested.


    I think this does the trick:

    (Warning - I haven't written C in years)

    Code:
    #include <stdio.h>
    
    main ()
    
    int i, n, odd, square;
    
    	printf ("This program prints a table of squares. \n") ;
    	printf ("Enter number of entries in table: ") ;
    	scanf ("%d", &n) ;
    	
    	square = 1 ;
    	odd = 3 ;
    	for (i=1 ; i <= n; ++i) {
    		printf ("%10d%10d\n", i, square) ;
    		odd += 2;
    		square += odd ;
    		
    		}
    		
    		return 0 ;
    }		
    	
    I haven't tested it.

    This should work because for all intents and purposes, the only important line of code is the printf line. It doesn't matter what happens to i, odd and square as long as they are correct when it is called. So, as long as i and square are initialised before the first printf is called (to 1 and 1 respectively), it doesn't matter what order they are in. Likewise, in-between printfs, it doesn't matter what order odd, square and i are updated - they are all interchangeable (EDIT 3: ignore this bit as well, have to set square before setting odd) - you just have to make sure that if square is set before odd then you use:
    Code:
     square += odd +2; 
    which is changing the code. (end of EDIT 3)
    In the code above, in between printfs, the variables are updated in the following order: odd, square, i.

    EDIT 2: Ignore everything between here ---------------------------

    You could rewrite it like this:


    Code:
    #include <stdio.h>
    
    main ()
    
    int i, n, odd, square;
    
    	printf ("This program prints a table of squares. \n") ;
    	printf ("Enter number of entries in table: ") ;
    	scanf ("%d", &n) ;
    	
    	square = 1 ;
    	odd = 3 ;
    	for (i=1 ; i <= n; square += odd) {
    		printf ("%10d%10d\n", i, square) ;
    		odd += 2;
    		 ++i;
    		
    		}
    		
    		return 0 ;
    }		
    	
    and it should still work.

    EDIT 2: and here ---------------------------------------, because it's wrong.


    The reason this all works is because of the expansion of (n+1)^2:


    If n^2 is a square of an integer, the next square of an integer must be (n+1)^2, as n+1 is the next integer after n.

    (n+1)^2 = n^2 + 2n + 1

    So the difference between one square of an integer and the next is

    (n+1)^2 - n^2 = 2n + 1

    This is the classic formula for an odd number - in other words, the increasing square numbers are separated by the increasing odd numbers.
    1^2 = 1
    2^2 = (1+1)^2 = (1)^2 + 3 = 4
    3^2 = (2+1)^2 = (2)^2 + 5 = 9
    4^2 = (3+1)^2 = (3)^2 + 7 = 16
    5^2 = (4+1)^2 = (4)^2 + 9 = 25
    and so on...

    It's quite a neat trick and there's a whole branch of mathematics behind it, but I don't recall its name.

    It replaces one multiplication and an addition with three additions. Which in the old days may have been worth it. It may still be worth it now.

    Probably the most important lesson here is that there are sometimes ways of doing things that are so brilliant that they appear stupid. And that I can't tell something stupid that's brilliant from something stupid that's stupid.

    I hope that helps, or is at least correct.
     
  20. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #20
    You should.

    First, there is a simple syntax error: it's missing a { after main().

    Second, you have a logic flaw. Actual output:
    Code:
    This program prints a table of squares. 
    Enter number of entries in table: 5
             1         1
             2         6
             3        13
             4        22
             5        33
    
    My basic suggestion is the same: break it down, write out what you expect at each step, and what you actually get at each step. If there's a disparity, stop. When you stop, ask whether you've got the correct expectation, or whether you've got the correct code (or whether both are incorrect).
     
  21. angryboffin macrumors newbie

    Joined:
    May 7, 2008
    Location:
    London
    #21
    I thought I didn't have access to a compiler - it turns out that posting untested code to macrumors is an excellent way of seeing the results :p .

    Then I also discovered this online compiler which I hope doesn't consist of a bloke behind a curtain ala The Wizard of Oz:

    http://codepad.org/

    That's pretty cool.

    Anyhow, now that chown33 has pointed out the smoking hole in my foot:

    Code:
    #include <stdio.h>
    
    main () {
    
    int i, n, odd, square;
    
    	printf ("This program prints a table of squares. \n") ;
    	printf ("Enter number of entries in table: ") ;
    	scanf ("%d", &n) ;
    	
    	square = 1 ;
    	odd = 3 ;
    	for (i=1 ; i <= n; ++i) {
    		printf ("%10d%10d\n", i, square) ;
    		square += odd ;
    		odd += 2;
    		}
    		
    		return 0 ;
    }
    
    is what I was aiming at (http://codepad.org/7wm9j9fa - with dodgy input n)

    Square needs to be calculated before odd is incremented (or alternatively odd should be initialised to 1, not 3). So ignore my second piece of code in my previous comment. Apologies for any confusion that's not mine.
     
  22. cybrscot, Feb 24, 2011
    Last edited: Feb 24, 2011

    cybrscot thread starter macrumors 6502

    cybrscot

    Joined:
    Dec 7, 2010
    Location:
    Somewhere in Southeast Asia
    #22
    Well, no need to re-write the while loop when it's right here. But I still don't understand what I'm doing wrong in the for loop yet. I can write my expectations below for the while loop, and what I expect the code to do is what it does, so that's good.

    In the above while loop example, i and square are already initialized at 1 respectively, so the first printf line is a given.

    i is 1 and square is 1,

    then, (in this order according to the code)
    square adds odd to itself, odd is currently 3 (because it hasn't been modified yet), so square becomes 4.

    then, i increments and becomes 2 (so here we already have our next printf line values ready to go as i is now 2 and square is now 4)

    then, lastly, odd adds 2 to itself and becomes 5. So we return to the top of the program, before the while statement and have the values,
    i =2
    square = 4
    odd = 5
    so the next printf is now i is 2 and square is 4
    then, (in this order according to the code again)
    square adds odd to itself, odd is currently 5 (because it hasn't been modified yet), so square becomes 9

    then, i increments and becomes 3 (so here we already have our next printf line values ready to go as i is now 3 and square is now 9)

    then, lastly, odd adds 2 to itself and becomes 7. So we return to the top of the program, before the while statement and have the values,
    i =3
    square =9
    odd = 7
    so the next printf is now i is 3 and square is 9
    then repeat the steps above until we have finished the output based on the number of squares the user entered.

    I will run back over to the for loop, and see if I can figure out a logical explanation for why it works also.

    Thanks!

    EDIT: Okay, I've compared the way I'm mentally evaluating the while loop vs. the for loop. The while loop I am doing right, and I can see why it works, it seems to me that the while loop is a bit more straightforward and logical in my opinion. (but my book wants me to do this with the for loop, so I must learn it) Basically, I'm printing the i and square values right off the bat, then AFTER that I'm adding odd to square, incrementing i, and adding 2 to odd, then returning to the top of the program with new values for each. Easy enough, no problem. It works everytime through on paper.

    But with the for loop

    Code:
    for (i = 1, square = 1, odd = 3 ; i <= n; odd += 2, ++i) {
    		printf ("%10d%10d\n", i, square) ;
    		
    		square += odd ;
    I'm printing i and square right off the bat too, like the while loop. So if I am pretending to be the compiler I'm looking at it like this (this is where I want someone to correct me and tell me why I'm wrong) First I (the compiler)look at the i value, then I look at the square value, (they are both 1 and I print the i and the square for each) then the 3rd step is I (the compiler) look at odd = 3, I don't print that value so odd remains 3 where it is. then I (the compiler) check to see if i <= n, (it is at this point so I continue), then I run into the odd +=2 statement. (I the compiler already have odd = 3 in my memory as I just read that line a second ago, so I add 2 to 3 and now make odd =5 (which I know is wrong, but why? why is this step wrong? I'm going in order from left to write reading the loops statements) then next I (the compiler) come across and read the ++i, so I increment i and make i = 2 now.

    I guess technically this is where the print actually happens, so it prints 1 for i and 1 for square..

    Then the next step I (the compiler) reads is that square adds odd to itself. Square was 1 (as I just printed it), (I (the compiler) already added 2 to odd as I was reading expr 3 in the for loop above, so I already have odd set to 5.) So or course when I add odd to square, or (5 to 1) I get square is now 6, which is wrong, it should be 4.

    Code:
    for (i = 1, square = 1, odd = 3 ; i <= n; odd += 2, ++i) {
    		printf ("%10d%10d\n", i, square) ;
    		
    		square += odd ;
    //////////I think it just hit me//////////////

    /////I've just stopped below, I think it hit me. After the printf completes, we don't go back to expr 3 above [odd +=2, ++i ] as I have been inclined to do, then move to the [square += odd] Which gives the wrong output.
    /////We (the compiler I mean) goes from the printf line of the loop to the [square += odd] segment, then the compiler moves back to the expr 3 in the for loop statement above. Because if the compiler goes to [square += odd] first, then odd is still 3 at this point, and square becomes 4. Then the compiler returns to expr 3 and adds 2 to odd, and increments i. Then if this path is followed over and over, it will be correct.

    I think this is what the problem was for me. I was thinking the compiler was reading like this.

    first: (i = 1, square = 1, odd = 3) then second: (i <= n) then third: compiler was printf'ing, then fourth: compiler reads (odd += 2, ++i) then fifth: compiler reads (square += odd), then sixth, all values have been modified by the compiler and we return to expr 1 to do it all over again, (which was always giving me the wrong result)

    I think the correct order for the compiler to do it's work is.
    first: (i = 1, square = 1, odd = 3) then second: (i <= n) then third: compiler was printf'ing, then fourth: compiler reads (square += odd) then fifth: compiler reads (odd += 2, ++i), then sixth, all values have been modified by the compiler and we return to expr 1 to do it all over again, (which now always gives the correct output)

    Have I got it?
    Instead of this:

    First: (i = 1, square = 1, odd = 3)
    Second: (i <= n)
    Third: compiler was printf'ing
    Fourth: compiler reads (odd += 2, ++i)
    Fifth: compiler reads (square += odd)
    Sixth: All values have been modified, return to expr 1.

    It's this...(basically swapping my order of steps 4 and 5)
    First: (i = 1, square = 1, odd = 3)
    Second: (i <= n)
    Third: compiler was printf'ing
    Fourth: compiler reads (square += odd)
    Fifth: compiler reads (odd += 2, ++i)
    Sixth: All values have been modified, return to expr 1.


    ///////////This is what I was writing before, "it hit me".///////////////////////
    ////you can ignore it if you like///////////
    I'm reading or computing this wrong.
    (i = 1, square =1, odd =3; i <= n; odd += 2, ++i)

    Reading from left to right

    I've got my i value
    I've got my square value.
    I've got my odd value of 3

    I check and i <= n is true, so I continue, I print the loop body now, because the controlling expression has been validated as true, i is in fact <=n.

    after printing the loop body, I return to expr 3 in the for loop statement above
    I add 2 to odd, odd is now 5
    I increment i, i is now 2
     
  23. mac2x macrumors 65816

    Joined:
    Sep 19, 2009
    #23
    The compiler isn't really doing any of that...all the operations are happening in the CPU.

    Also, I find putting tons of statements inside the parentheses (with commas) of the for statement hard to read. I think it looks better to just have the loop variable, condition, and increment/update in the parentheses and put everything else in the body of the loop, like so.

    Code:
    #include <stdio.h>
    
    main ()
    {
    
    int i, n, odd = 3, square = 1;
    
    	printf ("This program prints a table of squares. \n") ;
    	printf ("Enter number of entries in table: ") ;
    	scanf ("%d", &n) ;
    	
    
    	for (i = 1 ; i <= n ; ++i ) 
    	{
    		printf ("%10d%10d\n", i, square) ;
    		square += odd;
    		odd += 2;
    	}
    		
    		return 0 ;
    }
     
  24. cybrscot thread starter macrumors 6502

    cybrscot

    Joined:
    Dec 7, 2010
    Location:
    Somewhere in Southeast Asia
    #24
    Yeah, thanks that looks good. Ij'm still the many different ways there are to write this stuff.

    Where is everybody? Has anybody looked at my last post? And am I finally correct in my interpretation of the order of operations in the way the cpu (not compiler I guess I stand corrected) reads my for statement?
    expr1, expr2, then printf, then statement below the printf, than reads the expr3? It does work this way.

    I'm glad I had the answer to this one in the back of the book. I would've never solved this one. Reason: As I have the code from the back of the book, I've been spending the past few days trying to figure out why it works, I kept getting thrown off by the odd adding 2 to itself. I thought that the for loop read from left to right completely, then printf, then the last statement square += odd.
     

Share This Page