Array address arithmetic

Discussion in 'C Programming' started by vjay, Dec 9, 2007.

  1. vjay

    vjay Guest

    Check the code below guys
    void main()
    {
    char a[5] = {1,2,3,4,5};
    char *ptr;
    ptr = (char*)(&a + 1);
    printf("%d",*(ptr-1));
    }

    The output of the program is 5

    But what i expected was 1.When i replace &a with a in the expression ptr =
    (char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
    and (a + 1) in the above mentioned expression.Help guys its confusing.





    --
    Message posted using http://www.talkaboutprogramming.com/group/comp.lang.c/
    More information at http://www.talkaboutprogramming.com/faq.html
    vjay, Dec 9, 2007
    #1
    1. Advertising

  2. "vjay" <> wrote in
    news:3948456199d9a241db54852adf077d63
    @localhost.talkaboutprogramming.com:

    > Check the code below guys
    > void main()




    int main(void)



    > {
    > char a[5] = {1,2,3,4,5};




    Unusual to store numbers in a char, but how and ever.


    > char *ptr;
    > ptr = (char*)(&a + 1);



    Here you take the address of the array "a", and add one to it. This will
    give you the address of the first byte after the fifth element in the
    array "a".


    > printf("%d",*(ptr-1));



    "ptr-1" leaves you with the address of the fifth element in "a".


    > The output of the program is 5
    >
    > But what i expected was 1.When i replace &a with a in the expression
    > ptr = (char*)(a + 1); i get output as 1.what is the difference between
    > (&a + 1) and (a + 1) in the above mentioned expression.Help guys its
    > confusing.




    Pointer arithmetic depends on the size of the "pointed to" type. The
    size of the "pointed to" type in &a is "sizeof(char[5])".


    --
    Tomás Ó hÉilidhe
    Tomás Ó hÉilidhe, Dec 9, 2007
    #2
    1. Advertising

  3. vjay

    James Fang Guest

    On 12ÔÂ9ÈÕ, ÏÂÎç10ʱ43·Ö, "vjay" <> wrote:
    > Check the code below guys
    > void main()
    > {
    > char a[5] = {1,2,3,4,5};
    > char *ptr;
    > ptr = (char*)(&a + 1);
    > printf("%d",*(ptr-1));
    >
    > }
    >
    > The output of the program is 5
    >
    > But what i expected was 1.When i replace &a with a in the expression ptr =
    > (char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
    > and (a + 1) in the above mentioned expression.Help guys its confusing.
    >
    > --
    > Message posted usinghttp://www.talkaboutprogramming.com/group/comp.lang.c/
    > More information athttp://www.talkaboutprogramming.com/faq.html


    try the following:
    int main()
    {
    char a[5] = {1,2,3,4,5};
    char *ptr;
    ptr = (char*)((char*)&a + 1);
    printf("%d",*(ptr-1));
    getchar();
    }
    James Fang, Dec 9, 2007
    #3
  4. vjay wrote:
    > Check the code below guys
    > void main()
    > {
    > char a[5] = {1,2,3,4,5};
    > char *ptr;
    > ptr = (char*)(&a + 1);


    Don't you mean this:
    ptr = (char *)(&a[0] + 1);

    Didn't you get some kind of warning? What compiler are you using?

    > printf("%d",*(ptr-1));
    > }
    >
    > The output of the program is 5
    >
    > But what i expected was 1.When i replace &a with a in the expression
    > ptr = (char*)(a + 1); i get output as 1.what is the difference
    > between (&a + 1) and (a + 1) in the above mentioned expression.Help
    > guys its confusing.
    Anthony Fremont, Dec 9, 2007
    #4
  5. vjay

    Noé Falzon Guest

    vjay a écrit :
    > Check the code below guys
    > void main()
    > {
    > char a[5] = {1,2,3,4,5};
    > char *ptr;
    > ptr = (char*)(&a + 1);
    > printf("%d",*(ptr-1));
    > }
    >
    > The output of the program is 5
    >
    > But what i expected was 1.When i replace &a with a in the expression ptr =
    > (char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
    > and (a + 1) in the above mentioned expression.Help guys its confusing.


    I would say it is because &a is a pointer to an array of 5 chars, and
    thus (&a + 1) add the size of one array of 5 chars. It brings you one
    char after the 5.
    Then ptr being a pointer to a char, doing (ptr-1) brings you one char
    back, right on the 5.

    I think you meant (a+1). This way, it would have worked. The name of the
    array is a pointer to its first element. So "a" is really a pointer to a
    char, and (a+1) points to the second element of your array.

    It's all due to the difference between a pointer to a char ("a"), and a
    pointer to an array of chars ("&a").

    Hope i'm not mistaken,
    Noé
    Noé Falzon, Dec 9, 2007
    #5
  6. vjay

    James Kuyper Guest

    vjay wrote:
    > Check the code below guys
    > void main()
    > {
    > char a[5] = {1,2,3,4,5};
    > char *ptr;
    > ptr = (char*)(&a + 1);
    > printf("%d",*(ptr-1));
    > }
    >
    > The output of the program is 5
    >
    > But what i expected was 1.When i replace &a with a in the expression ptr =
    > (char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
    > and (a + 1) in the above mentioned expression.Help guys its confusing.


    When you add an integer n to a pointer to a given type, the result is a
    new pointer pointing that n elements of that type farther down. The
    expression &a has the type char(*)[5], which means it points at an
    entire array of 5 chars. Therefore, when you add 1 to it, it points at
    the next array of 5 characters. Converting it to char* result in a
    pointer that would point at the first char of that next array. When you
    subtract 1, the behavior is undefined; however, on most real-world
    implementations, the actual behavior is to point at the last char of the
    previous array, which contained a 5.

    In the expression (a+1), the name of the array decays into a pointer to
    the first element of the array, and therefore has the type char*. When
    you add 1 to that pointer, it points at the next char. When you subtract
    1, it goes back to pointing at the first char, as you expected.
    James Kuyper, Dec 9, 2007
    #6
  7. vjay

    James Kuyper Guest

    Anthony Fremont wrote:
    > vjay wrote:
    >> Check the code below guys
    >> void main()
    >> {
    >> char a[5] = {1,2,3,4,5};
    >> char *ptr;
    >> ptr = (char*)(&a + 1);

    >
    > Don't you mean this:
    > ptr = (char *)(&a[0] + 1);
    >
    > Didn't you get some kind of warning? What compiler are you using?


    On what basis? If you were writing the text of the warning message, what
    would it say? As far as I can see, the only thing wrong with this code
    is vjay's incorrect understanding of what it does.
    James Kuyper, Dec 9, 2007
    #7
  8. James Kuyper wrote:
    > Anthony Fremont wrote:
    >> vjay wrote:
    >>> Check the code below guys
    >>> void main()
    >>> {
    >>> char a[5] = {1,2,3,4,5};
    >>> char *ptr;
    >>> ptr = (char*)(&a + 1);

    >>
    >> Don't you mean this:
    >> ptr = (char *)(&a[0] + 1);
    >>
    >> Didn't you get some kind of warning? What compiler are you using?

    >
    > On what basis? If you were writing the text of the warning message,
    > what would it say? As far as I can see, the only thing wrong with
    > this code is vjay's incorrect understanding of what it does.


    Thanks, I get it now, I guess I just never had a need to try such a thing
    before.
    Anthony Fremont, Dec 9, 2007
    #8
  9. vjay

    pete Guest

    vjay wrote:
    >
    > Check the code below guys
    > void main()
    > {
    > char a[5] = {1,2,3,4,5};
    > char *ptr;
    > ptr = (char*)(&a + 1);
    > printf("%d",*(ptr-1));
    > }
    >
    > The output of the program is 5
    >
    > But what i expected was 1.When i replace &a with a in the expression ptr =
    > (char*)(a + 1); i get output as 1.
    > what is the difference between (&a + 1)
    > and (a + 1) in the above mentioned expression.Help guys its confusing.


    ptr == a + 5
    (char*)(&a + 1) == a + 5
    &a + 1 == (char(*)[5])(a + 5)




    /* BEGIN new.c */

    #include <stdio.h>

    int main(void)
    {
    char a[5] = {1,2,3,4,5};
    char *ptr = (char*)(&a + 1);

    if ( ptr == a + 5) {
    puts("ptr == a + 5");
    }
    if ( (char*)(&a + 1) == a + 5) {
    puts("(char*)(&a + 1) == a + 5");
    }
    if ( &a + 1 == (char(*)[5])(a + 5)) {
    puts("&a + 1 == (char(*)[5])(a + 5)");
    }
    return 0;
    }

    /* END new.c */

    --
    pete
    pete, Dec 9, 2007
    #9
  10. vjay

    Joe Wright Guest

    vjay wrote:
    > Check the code below guys
    > void main()
    > {
    > char a[5] = {1,2,3,4,5};
    > char *ptr;
    > ptr = (char*)(&a + 1);
    > printf("%d",*(ptr-1));
    > }
    >
    > The output of the program is 5
    >
    > But what i expected was 1.When i replace &a with a in the expression ptr =
    > (char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
    > and (a + 1) in the above mentioned expression.Help guys its confusing.


    You've been hanging out here for a while now haven't you? Why do you not
    grasp what everybody is telling you? What you have posted is not
    compilable and also incorrect. Watch ..

    #include <stdio.h>

    int main(void)
    {
    char a[5] = {1, 2, 3, 4, 5};
    char *ptr;
    ptr = (char *) (&a + 1);
    printf("%d", *(ptr - 1));
    return 0;
    }

    Now it's compilable and correct.
    Expressing &a gives an address of type 'array 5 of char'. (&a + 1) gives
    the address of the 'next' array 5 of char. You cast this address to
    char* and store it in ptr. This effectively points one past the end of
    array a. ptr - 1 points to the end of a and *(ptr - 1) is a[4] with value 5.

    --
    Joe Wright
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
    Joe Wright, Dec 9, 2007
    #10
  11. vjay

    Bart C Guest

    "vjay" <> wrote in message
    news:...
    > Check the code below guys
    > void main()
    > {
    > char a[5] = {1,2,3,4,5};
    > char *ptr;
    > ptr = (char*)(&a + 1);
    > printf("%d",*(ptr-1));
    > }
    >
    > The output of the program is 5


    Thanks, your post and it's replies has clarified something that I hadn't
    fully grasped; in int a[5], then:

    &a is not the same thing as a, when considering Type.

    Apparently a is the same as &a[0] (pointer to int), &a means a pointer to
    the entire array (pointer to array of 5 ints). The values however are the
    same. (Although why &a doesn't decompose to &(&a[0]) is another mystery;
    maybe it only decomposes when there isn't an & in front)

    > void main()


    With quotes, this gives 5 times as many Google hits as "int main(void)".
    Looks like a lot of people can't get it right.

    Bart
    Bart C, Dec 10, 2007
    #11
  12. vjay

    pete Guest

    Bart C wrote:
    >
    > "vjay" <> wrote in message
    > news:...
    > > Check the code below guys
    > > void main()
    > > {
    > > char a[5] = {1,2,3,4,5};
    > > char *ptr;
    > > ptr = (char*)(&a + 1);
    > > printf("%d",*(ptr-1));
    > > }
    > >
    > > The output of the program is 5

    >
    > Thanks, your post and it's replies
    > has clarified something that I hadn't
    > fully grasped; in int a[5], then:
    >
    > &a is not the same thing as a, when considering Type.
    >
    > Apparently a is the same as &a[0] (pointer to int),
    > &a means a pointer to
    > the entire array (pointer to array of 5 ints).
    > The values however are the same.
    > (Although why &a doesn't decompose to &(&a[0]) is another mystery;
    > maybe it only decomposes when there isn't an & in front)


    That's very close to being correct.

    N869
    6.3.2 Other operands
    6.3.2.1 Lvalues and function designators

    [#3] Except when it is the operand of the sizeof operator or
    the unary & operator, or is a string literal used to
    initialize an array, an expression that has type ``array of
    type'' is converted to an expression with type ``pointer to
    type'' that points to the initial element of the array
    object and is not an lvalue.

    --
    pete
    pete, Dec 10, 2007
    #12
  13. vjay

    vjay Guest

    vjay, Dec 10, 2007
    #13
  14. "Tomás Ó hÉilidhe" <> wrote:
    > "vjay" <> wrote
    > > char a[5] = {1,2,3,4,5};

    >
    > Unusual to store numbers in a char, ...


    What else does one store in a char? ;)

    --
    Peter
    Peter Nilsson, Dec 10, 2007
    #14
  15. vjay wrote:
    >
    > Check the code below guys
    > void main()
    > {
    > char a[5] = {1,2,3,4,5};
    > char *ptr;
    > ptr = (char*)(&a + 1);
    > printf("%d",*(ptr-1));
    > }
    >
    > The output of the program is 5
    >
    > But what i expected was 1.When i replace &a with a in the expression ptr =
    > (char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
    > and (a + 1) in the above mentioned expression.Help guys its confusing.


    Consider:

    What does it mean when you say "&something + 1"?

    What is the value of "sizeof a"?

    If there were a "typeof" operator, what would be "typeof a"?

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
    Kenneth Brody, Dec 10, 2007
    #15
  16. "Bart C" <> writes:
    [...]
    > Apparently a is the same as &a[0] (pointer to int), &a means a pointer to
    > the entire array (pointer to array of 5 ints). The values however are the
    > same. (Although why &a doesn't decompose to &(&a[0]) is another mystery;
    > maybe it only decomposes when there isn't an & in front)

    [...]

    The answers to these and a number of similar questions can be found in
    section 6 of the comp.lang.c FAQ, <http://www.c-faq.com>.

    --
    Keith Thompson (The_Other_Keith) <>
    Looking for software development work in the San Diego area.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Dec 11, 2007
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Stephen Biggs

    Arithmetic on function address

    Stephen Biggs, Apr 23, 2004, in forum: C Programming
    Replies:
    21
    Views:
    702
    Dan Pop
    Apr 28, 2004
  2. joshc
    Replies:
    5
    Views:
    539
    Keith Thompson
    Mar 31, 2005
  3. joshc
    Replies:
    16
    Views:
    466
    Joe Wright
    Jun 15, 2006
  4. Address Arithmetic

    , Jul 6, 2006, in forum: C++
    Replies:
    14
    Views:
    692
    Old Wolf
    Jul 10, 2006
  5. Stanley Rice

    Address of array && address of pointer to array

    Stanley Rice, Sep 14, 2011, in forum: C Programming
    Replies:
    33
    Views:
    1,110
    Keith Thompson
    Sep 20, 2011
Loading...

Share This Page