Thread: combined conditions in For loop

  1. #1
    Registered User
    Join Date
    Jul 2012
    Posts
    55

    combined conditions in For loop

    For the for loop below each outputs 4,3,2,1,0 - how does this work exactly?

    the first loop:
    for (p=a+4, i=0; i<=4; i++) PRD(p[-i]);

    is this just that we start at p[4] and keep going down until i = 4 which leaves us at p[0]? can someone please walk me through how it is being interpreted?

    the second loop:
    for (p=a+4; p>=a; p--) PRD(a[p-a]);

    the first pass of this look p = 4, a = 0? is output here "a[4-0,3-0,2-0,1-0,0-0]"?

    Code:
    #define PRD(a) printf("%d", (a) )#define NL printf("\n");
    
    
    // Create and initialse array
    int a[]={0, 1, 2, 3, 4};
    
    int main()
    {
        int i;
        int* p;
        for (p=a+4, i=0; i<=4; i++) PRD(p[-i]);
        for (p=a+4; p>=a; p--) PRD(a[p-a]);
    }

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    This looks like a "test your knowledge of obscure, useless C constructs" exercise. It helps to know that a[i] is equivalent to *(a + i) and *(i + a) and i[a]. That is why you can do crazy things like "abcdef"[2] (which results in 'c'). Not that you should do that in real code.


    Code:
    for (p=a+4, i=0; i<=4; i++) PRD(p[-i]);
    You're basically right on this.
    That sets p to the address of a[4], and sets i to 0. Then it loops, continuing while i <=4. Each time, it calls the macro PRD, passing it p[-i] to print out, and incrementing i. Since p[-i] is equal to *(p + -i), and p = a+4, p[-i] can be seen as *(a + 4 - i), so it prints out values of *(a + 4 - 0), then *(a + 4 - 1), ..., *(a + 4 - 4). Or, a[4], a[3], ..., a[0].


    Code:
    for (p=a+4; p>=a; p--) PRD(a[p-a]);
    You seem a little more confused on this one. It involves a bit more pointer arithmetic.
    This also starts with p pointing to the address of a[4], however, it decrements p each time through the loop, continuing while p is >= a. Two little notes here. First, a (the name of the array) is interpreted as a pointer to the first element, i.e. a is equivalent to &a[0] or (a + 0). Second, when you add or subtract pointers, it is automatically scaled by the size of the thing pointed to. That is, if an int is 4 bytes, &a[1] - &a[0] is still only 1 (1 element apart) instead of 4 (4 bytes apart). So assuming a starts at some address like 0x1000, and ints are 4 bytes, you have


    &a[0] = 0x1000
    &a[1] = 0x1004
    ...
    &a[4] = 0x1010


    That means p starts at 0x1010 (and a is always &a[0] or 0x1000). So you print a[0x1010 - 0x1000] which is a[0x10] or a[16], but remember, it gets scaled down by the size of an int (4 bytes), so you end up with a[4]. Then p is decremented by 1 (subtracting sizeof(*p) or sizeof(int)), so next iteration p = 0x100c. Thus, you print a[0x100c - 0x1000] == a[12], scaled down gives a[3].


    Hope that makes sense.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    The first loop is doing just what you have posted, above. Remember that as you increase i, the index number for the array will go DOWN, instead of up, since i is being subtracted.

    In the second loop, a is the address of the array's first element, so p-a is just a rather unintuitive way of writing [4-0], [3-0], [2-0], but using the pointer p, instead of an index number.

    It's essential to know the relationship between a[number] and *(a+number), but in practice, the a[number] style is FAR more intuitive, and will result in FAR fewer errors.

  4. #4
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    p is a pointer to int.a is an array of int.So how does an array works(well pretty much)?You have a pointer(here the pointer of the array is a) and you say your system the offset you want and the pointer will go at the requested offset and give you access there.e.g. if i write a[3] then then the pointer a which located by default at the start of the array will move to the fourth cell(because we start counting from zero).
    Also mind that a[3] is equivalent to *(a+3).
    Code:
    a
    |
    |
    V
    +-----+-----+-------+-----+-----+
    |data |data|data2|data|data|
    +-----+-----+-------+-----+-----+
    so if i write *(a+2) the pointer will be transferred to data2
    Code:
    #include <stdio.h>
     
      
    int main(void) {
      int a[]={0, 1, 2, 3, 4};
      
      printf("%d\n",a[3]);
      printf("%d\n",*(a+3));
      
      return 0;
    }
    So at your code line 11 sets pointer p to the fifth element of the array(because offset is +4 and we count from zero).So counter i is decreased in order to traverse the array in reverse.But because of the equivalent expressions i mentioned before p is now set back to the start of a.

    Then in the second loop,we set pointer p again at the end of array a,because we move it four positions,starting from the zero.
    Then p>=a means that the loop body is going to be executed as long as the pointer is at a cell which is in 'bigger' position(e.g. second element is at bigger position in comparisson with the first) or if the pointer p points where pointer a points.
    Then it will make the pointer p point to a position with a smaller number(e.g from fifth cell to the fourth cell).

    And when it says a[p-a] it means that p-a is resolved at an int .I run the program with this line
    Code:
    for (p=a+4; p>=a; p--) printf("%d %d %d %d\n",a[p-a],p,a,p-a);
    output
    Code:
    4 4202512 4202496 4
    3 4202508 4202496 3
    2 4202504 4202496 2
    1 4202500 4202496 1
    0 4202496 4202496 0
    the big numbers are addresses of course,because p and are pointers,so when writing *p we refer to where p points to ,but writing simple p we refer to it's own block of memory which contains it's address.
    But if you do 4202512 - 4202496 you will find 16.Then p is decreased to point to a smaller position cell.So 4202508 - 4202496 =12 etc.
    Notice that 4202496 remains as it was because a is not modified at all.
    So why we find 16 but p-a gives as 4?
    Why we find 12 but p-a gives as 3?
    Well,in many systems int has size of 4.4 what?4 bytes .So every int is saved at a 4 bytes .An int is placed in an integer(you can imagine it as an array that holds the value of the number in binary).
    So 4*4 requires 16 bits space to fit,3*4 12 bits to fit etc...

    Edit->i am too slow,when starting writting no responses where here
    Last edited by std10093; 08-22-2012 at 02:41 PM.

  5. #5
    Registered User
    Join Date
    Jul 2012
    Posts
    55
    Thank you very much. you explanations are very helpful. I understand much better now.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by anduril462 View Post
    That is why you can do crazy things like "abcdef"[2] (which results in 'c').
    Actually, that usage is obvious if you think about it. The index is inside the square brackets.

    I would suggest it is crazier that 2["abcdef"] does the same thing (results in 'c'). Anyone who uses such a construct outside an obfuscated C context (almost) deserves to be summarily shot.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Store combined data types into string?
    By 843 in forum C Programming
    Replies: 5
    Last Post: 12-01-2010, 11:56 AM
  2. How to declare array with combined data types?
    By 843 in forum C Programming
    Replies: 2
    Last Post: 12-01-2010, 09:44 AM
  3. combined keyPresses
    By C_ntua in forum C# Programming
    Replies: 2
    Last Post: 12-05-2008, 06:20 AM
  4. Multiple conditions for the while loop?
    By Olidivera in forum C++ Programming
    Replies: 6
    Last Post: 04-24-2005, 03:47 AM
  5. While Loop Conditions?
    By ted_smith in forum C Programming
    Replies: 8
    Last Post: 01-17-2005, 10:20 PM

Tags for this Thread