Question about pointers and multi-dimension arrays

Discussion in 'C Programming' started by DiAvOl, Dec 27, 2007.

  1. DiAvOl

    DiAvOl Guest

    Hello everyone, merry christmas!

    I have some questions about the following program:

    arrtest.c
    ------------

    #include <stdio.h>

    int main(int agc, char *argv[]) {
    int array2d[2][2] = { {1,2} , {3,4} };
    int (* arrp)[2] = array2d;

    printf("&array2d = %p\tarray2d = %p\t*array2d = %p\n", &array2d,
    array2d, *array2d);
    printf("&arrp = %p\tarp = %p\t*arrp = %p\t**arp = %d\n", &arrp,
    arrp, *arrp, **arrp);

    return 0;
    }

    When I compile and run the program I get the following results:

    &array2d = 0xbfd9e880 array2d = 0xbfd9e880 *array2d = 0xbfd9e880
    &arrp = 0xbfd9e890 arrp = 0xbfd9e880 *arrp =
    0xbfd9e880 **arrp = 1

    My questions are:

    Why is the address of array2d (&array2d), the value (array2d) and the
    contents of that value (*array2d) all the same ? (0xbfd9e880)

    array2d contains the value: 0xbfd9e880. When dereferenced (*array2d)
    it gives the same value, 0xbfd9e880
    But when the same address is dereferenced again (**array2d) it gives
    an integer (1) and not an address like above.

    How does the compiler "understands" if it should return a pointer or
    the value stored in that address?

    How does the compiler stores array variables so that &array == array ?

    Thanks for your time, I hope you will understand my questions
    DiAvOl, Dec 27, 2007
    #1
    1. Advertising

  2. DiAvOl said:

    <snip>

    > int array2d[2][2] = { {1,2} , {3,4} };


    <snip>

    > Why is the address of array2d (&array2d), the value (array2d) and the
    > contents of that value (*array2d) all the same ?


    They aren't the same, because they have different types. &array2d has type
    int (*)[2][2], array2d has type int[2][2] (which is converted into a value
    of type int(*)[2] when used in value contexts), and *array2d has type
    int[2] (which is converted into a value of type int * when used in value
    contexts).

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
    Richard Heathfield, Dec 27, 2007
    #2
    1. Advertising

  3. "DiAvOl" <> wrote in message news:06ce14cb-

    > int main(int agc, char *argv[]) {
    > int array2d[2][2] = { {1,2} , {3,4} };
    > int (* arrp)[2] = array2d;
    >
    > printf("&array2d = %p\tarray2d = %p\t*array2d = %p\n", &array2d,
    > array2d, *array2d);
    > printf("&arrp = %p\tarp = %p\t*arrp = %p\t**arp = %d\n", &arrp,
    > arrp, *arrp, **arrp);
    >
    > return 0;
    > }
    >

    The important thing to know about multidimensional arrays in C 89 is that
    they are effectively broken. Whilst they can be declared and used, the
    syntax needed to do anything much with them, like pass them to other
    functions, is too complicated. They also cannot be resized at runtime.

    So just forget about them until you are familiar with most of the rest of
    the language. Any multi-dimensional array can easily be emulated with a
    single dimension.

    --
    Free games and programming goodies.
    http://www.personal.leeds.ac.uk/~bgy1mm
    Malcolm McLean, Dec 27, 2007
    #3
  4. DiAvOl

    DiAvOl Guest

    0xbfd9e880 <=== Memory address
    ------------
    | 1 | <=== Contents
    ------------

    My point is, how can the address 0xbfd9e880 hold both an address and a
    number ?

    When array2d is dereferenced (*array2d) it should return the contents
    of it's value (contents of memory location 0xbfd9e880) but it returns
    the same address.

    When array2d is double dereferenced (**array2d) it's the same as
    *(*array2d), *array2d as we saw before is the address 0xbfd9e880 so
    when it is dereferenced this time, it returns an integer.

    How can the compiler determine when to return an integer and when to
    return the address?

    Thanks for your fast reply
    DiAvOl, Dec 27, 2007
    #4
  5. Malcolm McLean said:

    <snip>

    > The important thing to know about multidimensional arrays in C 89 is that
    > they are effectively broken.


    I disagree. They work just fine if you treat them right.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
    Richard Heathfield, Dec 27, 2007
    #5
  6. DiAvOl said:

    > 0xbfd9e880 <=== Memory address
    > ------------
    > | 1 | <=== Contents
    > ------------
    >
    > My point is, how can the address 0xbfd9e880 hold both an address and a
    > number ?


    Please switch, if necessary, to a non-proportional font such as Courier. It
    will make the following diagram clearer.

    | M |
    | a +-----+-----+-----+-----+---
    | i | 1 | 3 | 5 | 7 |
    | n X-----+-----+-----+-----+--
    | High Street
    | R +-----+-----+-----+-----+---
    | o | 2 | 4 | 6 | 8 |
    | a +-----+-----+-----+-----+-
    | d |

    See the X? It represents a single point on the Earth's surface. We can
    think of this point as "1 High Street" if we like - so in that sense it
    can be thought of as an address. On the other hand, it's also the corner
    of a living room. On the other other hand, it's also a brick. On the other
    other other hand, it's also a Carbon atom. The question "what will we find
    at X?" depends on the level at which we're asking the question.


    > When array2d is dereferenced (*array2d) it should return the contents
    > of it's value (contents of memory location 0xbfd9e880) but it returns
    > the same address.


    Crank up the magnification on your binoculars, and what you see at X will
    change - but it's still at the same place, isn't it?

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
    Richard Heathfield, Dec 27, 2007
    #6
  7. DiAvOl

    DiAvOl Guest

    I perfectly understand what you are saying. I'll try to describe my
    question better.

    Suppose I am the C compiler and I see the following constructs:

    1) printf("%d", *p); // p is an int pointer

    I should fetch the address which p contains and find an int value
    there.

    All fine with this one

    2)
    Having:

    int array2d[2][2] = { {1,2} , {3,4} };

    &array2d = 0xbfd9e880 array2d = 0xbfd9e880 *array2d = 0xbfd9e880

    I (the compiler) see the construct: printf("%p", *array2d); .

    I should fetch the address which array2d contains (0xbfd9e880) and
    find an int pointer there. This returns 0xbfd9e880, so the address
    0xbfd9e880 contains the int pointer 0xbfd9e880.

    Then I see the construct: printf("%d", **array2d);

    I should fetch the address which *array2d contains (0xbfd9e880 as we
    saw above) and find an int value there

    But I saw before that 0xbfd9e880 contains the int pointer 0xbfd9e880
    not an int number... I am confused





    Thanks very much for your time and example and sorry for my bad
    english.
    DiAvOl, Dec 27, 2007
    #7
  8. "DiAvOl" <> wrote in message
    news:...
    > Hello everyone, merry christmas!
    >
    > I have some questions about the following program:
    >
    > arrtest.c
    > ------------
    >
    > #include <stdio.h>
    >
    > int main(int agc, char *argv[]) {
    > int array2d[2][2] = { {1,2} , {3,4} };
    > int (* arrp)[2] = array2d;
    >
    > printf("&array2d = %p\tarray2d = %p\t*array2d = %p\n", &array2d,
    > array2d, *array2d);
    > printf("&arrp = %p\tarp = %p\t*arrp = %p\t**arp = %d\n", &arrp,
    > arrp, *arrp, **arrp);
    >
    > return 0;
    > }
    >
    > When I compile and run the program I get the following results:
    >
    > &array2d = 0xbfd9e880 array2d = 0xbfd9e880 *array2d = 0xbfd9e880
    > &arrp = 0xbfd9e890 arrp = 0xbfd9e880 *arrp =
    > 0xbfd9e880 **arrp = 1
    >
    > My questions are:
    >
    > Why is the address of array2d (&array2d), the value (array2d) and the
    > contents of that value (*array2d) all the same ? (0xbfd9e880)


    Here is what I can think of (subject to correction of the experts..)

    the typeof(array2d) = "pointer to an array of 2 ints". But array2d is an
    r-value , not an l-value. This may be the reason why
    &array2d evaluates to the same address even though the typeof(&array2d) ==
    "pointer to a pointer to array of 2 ints".
    Finally *array2d has the type "array of 2 ints". But in C array is not first
    class type and *array2d is not a "lvalue". Thus *array2d evaluates
    to the same as array2d.
    A case where the expressions have different types , but same values..!

    >
    > array2d contains the value: 0xbfd9e880. When dereferenced (*array2d)

    array2d does not "contain" the value 0xbfd9e880 but rather evaluates to that
    value but having the type "pointer to an array of 2 ints".



    > it gives the same value, 0xbfd9e880
    > But when the same address is dereferenced again (**array2d) it gives
    > an integer (1) and not an address like above.

    I am not sure how the compiler understands **array2d. Perhaps someone could
    help here..

    >
    > How does the compiler "understands" if it should return a pointer or
    > the value stored in that address?
    >
    > How does the compiler stores array variables so that &array == array ?
    >
    > Thanks for your time, I hope you will understand my questions


    You have to read the C FAQ by Steve Summit on Arrays and Pointers for
    clarity on "pointers to arrays". I dont have the link handy though..
    Ravishankar S, Dec 27, 2007
    #8
  9. DiAvOl

    army1987 Guest

    DiAvOl wrote:

    > I perfectly understand what you are saying. I'll try to describe my
    > question better.

    You should quote relevant parts of the post you're replying to, to make
    context clear.
    > Suppose I am the C compiler and I see the following constructs:
    >
    > 1) printf("%d", *p); // p is an int pointer
    >
    > I should fetch the address which p contains and find an int value
    > there.
    >
    > All fine with this one

    Right.
    > 2)
    > Having:
    >
    > int array2d[2][2] = { {1,2} , {3,4} };
    >
    > &array2d = 0xbfd9e880 array2d = 0xbfd9e880 *array2d = 0xbfd9e880
    >
    > I (the compiler) see the construct: printf("%p", *array2d); .
    >
    > I should fetch the address which array2d contains (0xbfd9e880) and
    > find an int pointer there. This returns 0xbfd9e880, so the address
    > 0xbfd9e880 contains the int pointer 0xbfd9e880.
    >
    > Then I see the construct: printf("%d", **array2d);
    >
    > I should fetch the address which *array2d contains (0xbfd9e880 as we
    > saw above) and find an int value there
    >
    > But I saw before that 0xbfd9e880 contains the int pointer 0xbfd9e880
    > not an int number... I am confused


    A pointer corresponds both to an address and a type. The type determines
    how much stuff the address refers to, and how to interpret it.
    Supposing an int is four bytes:
    +-----------+
    |00 00 00 01| 0xbfd9e880
    +-----------+
    |00 00 00 02| 0xbfd9e884
    +-----------+
    |00 00 00 03| 0xbfd9e888
    +-----------+
    |00 00 00 04| 0xbfd9e88c
    +-----------+

    Now the object declared `int array2d[2][2] = { {1,2} , {3,4} };` is an
    array of arrays of ints, and spans 16 bytes. Thus, &array2d has type
    "pointer to array of two arrays of two ints", and value 0xbfd9e880. Now,
    an array, when is not used as the operand of & (or sizeof, or, in the case
    of a string literal, as the initializer of an array of char), evaluates to
    a pointer to its first element. Now, the first element of array2d is still
    an array, but this time it is an array of ints.
    So, array2d evaluates to &array2d[0], which is a pointer equal to &array2d,
    except for its type: the former is a pointer to array of arrays of ints,
    whereas the latter is a pointer to array of ints.
    Now, *array2d what &array2d[0] points to, that is an array of two ints
    starting at 0xbfd9e880. Since it is itself an array, it evaluates to a
    pointer to its first element. This pointer still has value 0xbfd9e880, but
    its type is pointer to int. Dereference it another time and you get the
    int contained at that location, i.e. 1.

    Resuming: &array2d, array2d, and *array2d all are (or evaluate to)
    pointers to objects starting at that address. But the first points to the
    whole 2d array (16 bytes), the second points to its first row (8 bytes),
    and the third points to its first element (4 bytes, the int 1).
    I hope I've been clear.

    Nitpick: printf expects "%p" to correspond a pointer to void, that is a
    pointer with no type information. You can convert a pointer of another
    type to a pointer to void with a cast:
    printf("%p\n", (void *)&array2d);
    On most modern machines this makes no difference, as all pointers are the
    same size. But on older machines pointers to void are larger, so on those
    printf("%p\n", &array2d);
    tries to read more data it was passed to. According to the C standard, the
    latter has undefined behavior, that is the standard allows a program with
    it to behave whatever the implementation likes most. Even if nowadays that
    is almost always the same thing as the former, the cost of adding the cast
    to be safe is so low that there is no reason not to do that.

    --
    Army1987 (Replace "NOSPAM" with "email")
    army1987, Dec 27, 2007
    #9
  10. DiAvOl

    Guest

    On Dec 27, 10:54 pm, army1987 <> wrote:
    > DiAvOl wrote:
    > > I perfectly understand what you are saying. I'll try to describe my
    > > question better.

    >
    > You should quote relevant parts of the post you're replying to, to make
    > context clear.
    >
    >
    >
    > > Suppose I am the C compiler and I see the following constructs:

    >
    > > 1) printf("%d", *p); // p is an int pointer

    >
    > > I should fetch the address which p contains and find an int value
    > > there.

    >
    > > All fine with this one

    > Right.
    > > 2)
    > > Having:

    >
    > > int array2d[2][2] = { {1,2} , {3,4} };

    >
    > > &array2d = 0xbfd9e880 array2d = 0xbfd9e880 *array2d = 0xbfd9e880

    >
    > > I (the compiler) see the construct: printf("%p", *array2d); .

    >
    > > I should fetch the address which array2d contains (0xbfd9e880) and
    > > find an int pointer there. This returns 0xbfd9e880, so the address
    > > 0xbfd9e880 contains the int pointer 0xbfd9e880.

    >
    > > Then I see the construct: printf("%d", **array2d);

    >
    > > I should fetch the address which *array2d contains (0xbfd9e880 as we
    > > saw above) and find an int value there

    >
    > > But I saw before that 0xbfd9e880 contains the int pointer 0xbfd9e880
    > > not an int number... I am confused

    >
    > A pointer corresponds both to an address and a type. The type determines
    > how much stuff the address refers to, and how to interpret it.
    > Supposing an int is four bytes:
    > +-----------+
    > |00 00 00 01| 0xbfd9e880
    > +-----------+
    > |00 00 00 02| 0xbfd9e884
    > +-----------+
    > |00 00 00 03| 0xbfd9e888
    > +-----------+
    > |00 00 00 04| 0xbfd9e88c
    > +-----------+
    >
    > Now the object declared `int array2d[2][2] = { {1,2} , {3,4} };` is an
    > array of arrays of ints, and spans 16 bytes. Thus, &array2d has type
    > "pointer to array of two arrays of two ints", and value 0xbfd9e880. Now,
    > an array, when is not used as the operand of & (or sizeof, or, in the case
    > of a string literal, as the initializer of an array of char), evaluates to
    > a pointer to its first element. Now, the first element of array2d is still
    > an array, but this time it is an array of ints.
    > So, array2d evaluates to &array2d[0], which is a pointer equal to &array2d,
    > except for its type: the former is a pointer to array of arrays of ints,
    > whereas the latter is a pointer to array of ints.
    > Now, *array2d what &array2d[0] points to, that is an array of two ints
    > starting at 0xbfd9e880. Since it is itself an array, it evaluates to a
    > pointer to its first element. This pointer still has value 0xbfd9e880, but
    > its type is pointer to int. Dereference it another time and you get the
    > int contained at that location, i.e. 1.
    >
    > Resuming: &array2d, array2d, and *array2d all are (or evaluate to)
    > pointers to objects starting at that address. But the first points to the
    > whole 2d array (16 bytes), the second points to its first row (8 bytes),
    > and the third points to its first element (4 bytes, the int 1).
    > I hope I've been clear.
    >
    > Nitpick: printf expects "%p" to correspond a pointer to void, that is a
    > pointer with no type information. You can convert a pointer of another
    > type to a pointer to void with a cast:
    > printf("%p\n", (void *)&array2d);
    > On most modern machines this makes no difference, as all pointers are the
    > same size. But on older machines pointers to void are larger, so on those
    > printf("%p\n", &array2d);
    > tries to read more data it was passed to. According to the C standard, the
    > latter has undefined behavior, that is the standard allows a program with
    > it to behave whatever the implementation likes most. Even if nowadays that
    > is almost always the same thing as the former, the cost of adding the cast
    > to be safe is so low that there is no reason not to do that.
    >
    > --
    > Army1987 (Replace "NOSPAM" with "email")


    Hi ,

    I just want to give a small clue to make you understand your problem.

    Since, array2d is an double dimension array, If you want to access
    array2d you need to deference it double time.
    If you deference it once you will get the address.

    Its just a clue for you. I hope you can easily analyse the problem.

    bye
    MMK
    , Dec 27, 2007
    #10
  11. DiAvOl <> writes:

    > I perfectly understand what you are saying. I'll try to describe my
    > question better.

    <snip>
    > 2)
    > Having:
    >
    > int array2d[2][2] = { {1,2} , {3,4} };
    >
    > &array2d = 0xbfd9e880 array2d = 0xbfd9e880 *array2d = 0xbfd9e880
    >
    > I (the compiler) see the construct: printf("%p", *array2d); .
    >
    > I should fetch the address which array2d contains (0xbfd9e880) and
    > find an int pointer there.


    No. array2d is an array of two arrays (type int [2][2]). When used
    in most contexts it is converted to a pointer to it's first element
    (type int(*)[2]). But note, this "first element" is an array so
    *array2d denotes an array, not a single int (the type is int [2]).
    How is this expression treated when it is passed to printf? Like any
    other array-valued expression, it is converted to a pointer to its
    first element. Of course, numerically, this looks the same as
    array2d, but you could see the difference if you printed the size as
    well:

    printf("Pointer: %p, size: %zu\n", (void *)array2d, sizeof array2d);
    printf("Pointer: %p, size: %zu\n", (void *)*array2d, sizeof *array2d);

    [If %zu does not work for you -- it is C99 -- replace with %lu and
    cast the sizeof expressions to (unsigned long). I have cast the
    pointers to (void *) because that is what %p requires -- it does not
    have any impact on the argument above.]

    sizeof is one of the special places where the conversion from array to
    pointer does *not* happen, so sizeof *array2d is the size of the
    (sub-)array and not just the size of a pointer on your system.

    --
    Ben.
    Ben Bacarisse, Dec 27, 2007
    #11
  12. DiAvOl

    DiAvOl Guest

    so if I'm not mistaken *array2d does NOT fetch (dereference) any
    value, it just changes the type of the pointer. Only **array2d really
    fetches the value. Is this correct?

    Thanks
    DiAvOl, Dec 27, 2007
    #12
  13. DiAvOl <> writes:

    In the context of:

    int array2d[2][2];

    [Snipping is good, but pleas keep enough context for each message to
    stand alone if need be.]

    > so if I'm not mistaken *array2d does NOT fetch (dereference) any
    > value, it just changes the type of the pointer. Only **array2d really
    > fetches the value. Is this correct?


    Not quite. The trouble is that "fetch" is not the same as
    "dereference". array2d (in most expressions) is converted to a
    pointer to an array. The * in *array2d removes the "pointer" part.
    I.e. it does do a dereference, but nothing is fetched from anywhere.

    It helps to think at the level of the so-called C "abstract machine".
    This is not the level of machine addresses and load and stores, but
    the level of values and types. At this level, a * always turns a
    pointer into the thing to which it points, but if that thing is an
    array which needs to be turned into a pointer right away you will not
    see any "fetching" associated with the *.

    --
    Ben.
    Ben Bacarisse, Dec 27, 2007
    #13
  14. On Thu, 27 Dec 2007 17:56:43 +0530, "Ravishankar S"
    <> wrote:

    >
    >"DiAvOl" <> wrote in message
    >news:...
    >> Hello everyone, merry christmas!
    >>
    >> I have some questions about the following program:
    >>
    >> arrtest.c
    >> ------------
    >>
    >> #include <stdio.h>
    >>
    >> int main(int agc, char *argv[]) {
    >> int array2d[2][2] = { {1,2} , {3,4} };
    >> int (* arrp)[2] = array2d;
    >>
    >> printf("&array2d = %p\tarray2d = %p\t*array2d = %p\n", &array2d,
    >> array2d, *array2d);
    >> printf("&arrp = %p\tarp = %p\t*arrp = %p\t**arp = %d\n", &arrp,
    >> arrp, *arrp, **arrp);
    >>
    >> return 0;
    >> }
    >>
    >> When I compile and run the program I get the following results:
    >>
    >> &array2d = 0xbfd9e880 array2d = 0xbfd9e880 *array2d = 0xbfd9e880
    >> &arrp = 0xbfd9e890 arrp = 0xbfd9e880 *arrp =
    >> 0xbfd9e880 **arrp = 1
    >>
    >> My questions are:
    >>
    >> Why is the address of array2d (&array2d), the value (array2d) and the
    >> contents of that value (*array2d) all the same ? (0xbfd9e880)

    >
    >Here is what I can think of (subject to correction of the experts..)
    >
    >the typeof(array2d) = "pointer to an array of 2 ints". But array2d is an


    The type of array2d is array of 2 arrays of 2 int. In syntax form, it
    is exactly as in the original post, int [2][2]

    >r-value , not an l-value. This may be the reason why
    >&array2d evaluates to the same address even though the typeof(&array2d) ==
    >"pointer to a pointer to array of 2 ints".


    The type of &array2d is pointer to array of 2 array of 2 int. In
    syntax form, int(*)[2][2].

    >Finally *array2d has the type "array of 2 ints". But in C array is not first
    >class type and *array2d is not a "lvalue". Thus *array2d evaluates
    >to the same as array2d.


    No they don't. While they do evaluate to the same address, each has a
    distinct type (as you note below). In situations other than the three
    exceptions which don't apply here, an expression of array type is
    converted to a pointer to the first element of the array with type
    pointer to element type. Therefore:

    *array2d (which is by definition exactly the same as
    array2d[0]) evaluates to &array2d[0][0] with type pointer to int
    (int*).

    array2d evaluates to &array2d[0] with type pointer to array of
    2 int (int(*)[2]).

    >A case where the expressions have different types , but same values..!


    Only in the conceptual sense similar to a double of 1.0 and an int of
    1 having the same value.

    >
    >>
    >> array2d contains the value: 0xbfd9e880. When dereferenced (*array2d)

    >array2d does not "contain" the value 0xbfd9e880 but rather evaluates to that
    >value but having the type "pointer to an array of 2 ints".


    Pointer to array of 2 array of 2 int.

    >
    >
    >
    >> it gives the same value, 0xbfd9e880
    >> But when the same address is dereferenced again (**array2d) it gives
    >> an integer (1) and not an address like above.

    >I am not sure how the compiler understands **array2d. Perhaps someone could
    >help here..


    **array2d is by definition exactly the same as array2d[0][0].

    >
    >>
    >> How does the compiler "understands" if it should return a pointer or
    >> the value stored in that address?
    >>
    >> How does the compiler stores array variables so that &array == array ?
    >>
    >> Thanks for your time, I hope you will understand my questions

    >
    >You have to read the C FAQ by Steve Summit on Arrays and Pointers for
    >clarity on "pointers to arrays". I dont have the link handy though..
    >


    www.c-faq.com


    Remove del for email
    Barry Schwarz, Dec 31, 2007
    #14
  15. On Thu, 27 Dec 2007 17:56:43 +0530, "Ravishankar S"
    <> wrote:

    >
    > "DiAvOl" <> wrote in message
    > news:...

    <snip: Q about 2-dim array>
    > You have to read the C FAQ by Steve Summit on Arrays and Pointers for
    > clarity on "pointers to arrays". I dont have the link handy though..
    >

    I wouldn't say you absolutely _must_ but it does often help.

    Web at http://c-faq.com or the usual places for (big8) FAQs:
    news:comp.answers,$group ftp://rtfm.mit.edu http://faqs.org

    Chris Torek's http://web.torek.net/c is also good for the particular
    topics it covers, which are fewer but does include this one.

    - formerly david.thompson1 || achar(64) || worldnet.att.net
    David Thompson, Jan 7, 2008
    #15
  16. David Thompson <> writes:
    [...]
    > Web at http://c-faq.com or the usual places for (big8) FAQs:
    > news:comp.answers,$group ftp://rtfm.mit.edu http://faqs.org


    I find faqs.org to be much more difficult to navigate than c-faq.com.

    > Chris Torek's http://web.torek.net/c is also good for the particular
    > topics it covers, which are fewer but does include this one.


    I'm sure it would be excellent if it actually existed.

    Try <http://www.torek.net/torek/c/>.

    --
    Keith Thompson (The_Other_Keith) <>
    [...]
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jan 7, 2008
    #16
  17. "David Thompson" <> wrote in message
    news:...
    > On Thu, 27 Dec 2007 17:56:43 +0530, "Ravishankar S"
    > <> wrote:
    >
    > >
    > > "DiAvOl" <> wrote in message
    > >

    news:...
    > <snip: Q about 2-dim array>
    > > You have to read the C FAQ by Steve Summit on Arrays and Pointers for
    > > clarity on "pointers to arrays". I dont have the link handy though..
    > >

    > I wouldn't say you absolutely _must_ but it does often help.

    I'd say it helps a lot, especially the printed version. For me it put the
    array pointer relation in the right prespective
    >
    > Web at http://c-faq.com or the usual places for (big8) FAQs:
    > news:comp.answers,$group ftp://rtfm.mit.edu http://faqs.org
    >
    > Chris Torek's http://web.torek.net/c is also good for the particular
    > topics it covers, which are fewer but does include this one.
    >
    > - formerly david.thompson1 || achar(64) || worldnet.att.net
    Ravishankar S, Jan 7, 2008
    #17
  18. DiAvOl

    John Bode Guest

    On Dec 27 2007, 2:51 am, DiAvOl <> wrote:
    > Hello everyone, merry christmas!
    >


    [snip]

    > How does the compiler stores array variables so that &array == array ?


    It's not about how the array variables are stored, but about how
    they're treated in various contexts.

    In most contexts, when the compiler sees an array identifier or an
    expression that evaluates to an array, it implicitly converts the type
    of the identifier or expression from "array of T" to "pointer to T",
    and converts the value to a pointer to the first element of the array.

    So, given the following:

    int arr1[N];

    wherever the compiler sees "arr1" in the code, it will convert the
    type of arr from "N-element array of int" to "pointer to int", and
    will set the value to be a pointer to the first element of arr (for
    illustration's sake, call it 0x8000).

    The exceptions to this rule are when arr1 is an operand of either the
    address-of (&) operator or the sizeof operator; instead of returning a
    pointer to the first element of the array, the & operator returns a
    pointer to the whole array. However, given how C arrays work, these
    two things (the pointer to the first element of the array and the
    pointer to the array) turn out to be the same *value*. IOW, the
    address of "arr1" is the same as the address of "arr1[0]"; the value
    is just interpreted differently. So, assuming that the base address
    of our array is 0x8000:

    &arr == arr

    in terms of the *value* of the pointer. However, the *types* are not
    equivalent:

    typeof &arr1 == int (*)[N] // pointer to N-element array of int
    typeof arr1 == int *

    Since this is a 1-d array,

    typeof *arr1 == int

    Bumping this up to multiple dimensions, assume we have the following:

    int arr2[N][M];

    Again, &arr2 evaluates to a pointer to the whole array and arr2
    evaluates to a pointer to the first element of the array. But now,
    the type of arr2[0] is no longer an int, but an M-element array of
    int. Since the expression *arr2 evaluates to an array type, the same
    rules that applied to the identifier arr1 apply to the expression
    *arr2; namely, the type of *arr2 is converted from "M-element array of
    int" to "pointer to int", and the value of the expression is set to
    point to the first element of the array (&arr2[0][0]). Again, the
    address of arr2 is the same as the address of arr2[0] which is the
    same as the address of arr2[0][0]. It's the types of each expression
    that change:

    typeof &arr2 == int (*)[N][M]
    typeof arr2 == int (*)[M]
    typeof *arr2 == int *

    Hope that helps (and was minimally correct).
    John Bode, Jan 7, 2008
    #18
    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. Replies:
    2
    Views:
    8,655
    Jim Lewis
    Mar 21, 2006
  2. Robert

    multi dimension arrays

    Robert, Feb 18, 2004, in forum: C Programming
    Replies:
    2
    Views:
    508
    Peter Pichler
    Feb 20, 2004
  3. Replies:
    12
    Views:
    586
    Thad Smith
    Oct 10, 2005
  4. Replies:
    123
    Views:
    2,045
    Tim Rentsch
    Oct 9, 2008
  5. Luuk
    Replies:
    15
    Views:
    822
    Nobody
    Feb 11, 2010
Loading...

Share This Page