About multidimensional array

Discussion in 'C Programming' started by drazet, Aug 20, 2007.

  1. drazet

    drazet Guest

    hi,all

    i have a question about multidimensional array.

    int w[2][3],(*pw)[3];
    pw=w;

    is *(pw+1)[2] wrong?why?
    and *(w[0]+2),pw[0][0] and *(pw[1]+2) mean?

    Regards,
    Drazet
     
    drazet, Aug 20, 2007
    #1
    1. Advertising

  2. drazet

    pete Guest

    drazet wrote:
    >
    > hi,all
    >
    > i have a question about multidimensional array.
    >
    > int w[2][3],(*pw)[3];
    > pw=w;
    >
    > is *(pw+1)[2] wrong?why?
    > and *(w[0]+2),pw[0][0] and *(pw[1]+2) mean?


    (A[X]) means the exact same thing as (*((A) + (X)))

    --
    pete
     
    pete, Aug 20, 2007
    #2
    1. Advertising

  3. drazet

    CBFalconer Guest

    drazet wrote:
    >
    > i have a question about multidimensional array.
    >
    > int w[2][3],(*pw)[3];
    > pw=w;
    >
    > is *(pw+1)[2] wrong?why?
    > and *(w[0]+2),pw[0][0] and *(pw[1]+2) mean?


    Consider the following display:

    [1] c:\c\dispbase>explain int w[2][3]
    declare w as array 2 of array 3 of int

    [1] c:\c\dispbase>explain int (*pw)[3]
    declare pw as pointer to array 3 of int

    [1] c:\c\dispbase>alias explain
    cdecl explain %1&

    a pw probably can't hold any w. Use legitimate code first.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>


    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Aug 20, 2007
    #3
  4. drazet

    Army1987 Guest

    On Mon, 20 Aug 2007 14:55:40 -0400, CBFalconer wrote:

    > drazet wrote:
    >>
    >> i have a question about multidimensional array.
    >>
    >> int w[2][3],(*pw)[3];
    >> pw=w;
    >>
    >> is *(pw+1)[2] wrong?why?
    >> and *(w[0]+2),pw[0][0] and *(pw[1]+2) mean?

    >
    > Consider the following display:
    >
    > [1] c:\c\dispbase>explain int w[2][3]
    > declare w as array 2 of array 3 of int
    >
    > [1] c:\c\dispbase>explain int (*pw)[3]
    > declare pw as pointer to array 3 of int
    >
    > [1] c:\c\dispbase>alias explain
    > cdecl explain %1&
    >
    > a pw probably can't hold any w. Use legitimate code first.

    w evaluates to &w[0], which is a pointer to array 3 of int. So
    what's wrong with pw = w?
    --
    Army1987 (Replace "NOSPAM" with "email")
    No-one ever won a game by resigning. -- S. Tartakower
     
    Army1987, Aug 20, 2007
    #4
  5. drazet

    CBFalconer Guest

    Army1987 wrote:
    > On Mon, 20 Aug 2007 14:55:40 -0400, CBFalconer wrote:
    >

    .... snip ...
    >
    >> a pw probably can't hold any w. Use legitimate code first.

    >
    > w evaluates to &w[0], which is a pointer to array 3 of int.
    > So what's wrong with pw = w?


    It should be &w.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Aug 20, 2007
    #5
  6. drazet

    pete Guest

    CBFalconer wrote:
    >
    > Army1987 wrote:
    > > On Mon, 20 Aug 2007 14:55:40 -0400, CBFalconer wrote:
    > >

    > ... snip ...
    > >
    > >> a pw probably can't hold any w. Use legitimate code first.

    > >
    > > w evaluates to &w[0], which is a pointer to array 3 of int.
    > > So what's wrong with pw = w?

    >
    > It should be &w.


    No.
    w is implicitly converted to a pointer to
    its first element, in this expression: (pw = w)
    It's first element, is an array of 3 char.

    Please try new.c with your compiler on strictest warning level.

    /* BEGIN new.c */

    int main(void)
    {
    int w[2][3], (*pw)[3];

    pw = w;
    return pw != w;
    }

    /* END new.c */

    --
    pete
     
    pete, Aug 20, 2007
    #6
  7. drazet

    drazet Guest

    Army1987 写é“:
    > On Mon, 20 Aug 2007 14:55:40 -0400, CBFalconer wrote:
    >
    >> drazet wrote:
    >>> i have a question about multidimensional array.
    >>>
    >>> int w[2][3],(*pw)[3];
    >>> pw=w;
    >>>
    >>> is *(pw+1)[2] wrong?why?
    >>> and *(w[0]+2),pw[0][0] and *(pw[1]+2) mean?

    >> Consider the following display:
    >>
    >> [1] c:\c\dispbase>explain int w[2][3]
    >> declare w as array 2 of array 3 of int
    >>
    >> [1] c:\c\dispbase>explain int (*pw)[3]
    >> declare pw as pointer to array 3 of int
    >>
    >> [1] c:\c\dispbase>alias explain
    >> cdecl explain %1&
    >>
    >> a pw probably can't hold any w. Use legitimate code first.

    > w evaluates to &w[0], which is a pointer to array 3 of int. So
    > what's wrong with pw = w?

    pw = w is right,my question is that why the use of "*(w[0]+2),pw[0][0]
    and *(pw[1]+2) "can get a right value,but "*(pw+1)[2]"gets a wrong?
     
    drazet, Aug 21, 2007
    #7
  8. drazet

    pete Guest

    drazet wrote:
    >
    > Army1987 写é“:
    > > On Mon, 20 Aug 2007 14:55:40 -0400, CBFalconer wrote:
    > >
    > >> drazet wrote:
    > >>> i have a question about multidimensional array.
    > >>>
    > >>> int w[2][3],(*pw)[3];
    > >>> pw=w;
    > >>>
    > >>> is *(pw+1)[2] wrong?why?
    > >>> and *(w[0]+2),pw[0][0] and *(pw[1]+2) mean?
    > >> Consider the following display:
    > >>
    > >> [1] c:\c\dispbase>explain int w[2][3]
    > >> declare w as array 2 of array 3 of int
    > >>
    > >> [1] c:\c\dispbase>explain int (*pw)[3]
    > >> declare pw as pointer to array 3 of int
    > >>
    > >> [1] c:\c\dispbase>alias explain
    > >> cdecl explain %1&
    > >>
    > >> a pw probably can't hold any w. Use legitimate code first.

    > > w evaluates to &w[0], which is a pointer to array 3 of int. So
    > > what's wrong with pw = w?

    > pw = w is right,my question is that why the use of "*(w[0]+2),pw[0][0]
    > and *(pw[1]+2) "can get a right value,but "*(pw+1)[2]"gets a wrong?


    It's supposed to be:

    (*(pw+1))[2]


    /* BEGIN new.c */

    #include <stdio.h>

    int main(void)
    {
    int w[2][3] = {1,2,3,4,5,6};
    int (*pw)[3];

    pw = w;
    printf("%d\n", (*(pw+1))[2]);
    return pw != w;
    }

    /* END new.c */

    --
    pete
     
    pete, Aug 21, 2007
    #8
  9. drazet

    Chris Torek Guest

    In article <fabnkp$goe$> drazet <> wrote:
    [given]
    >int w[2][3],(*pw)[3];
    >pw=w;
    >
    >is *(pw+1)[2] wrong? why?


    Yes. As for why, well, one moment:

    >and *(w[0]+2),pw[0][0] and *(pw[1]+2) mean?


    I think you are making an elementary mistake in parsing these
    expressions.

    Whenever you go to figure out an expression, you have to know
    (or look up) the way the various operators involve "bind". Most
    people do this with an "operator precedence table", which is
    convenient, but somewhat misleading.

    A precedence table tells you things like "multiply before add",
    for instance, so that in an expression like:

    3 + 4 * 5

    you know to multiply 4 by 5 first, then add 3 (result = 23), rather
    than add 3 and 4 first, then multiply by 5 (result = 35).

    Precedence is misleading in two ways. First -- and most important
    -- it tends to make people do *everything* in "precedence order":

    int f(void), g(void), h(void);
    int answer;

    answer = f() + g() * h();

    If you, as a human, go to "do the multiply first", you will probably
    also call g() first, then h(), then f(), in that order. A C compiler
    does not have to do this: it can call f() first, if it "wants to",
    and then call h(), and then g(), if it "feels like it", as long as
    it then uses the results of g() and h() to multiply, and the result
    of that and f() to add, to compute the final value for "answer". If
    you make f(), g(), and h() print their names:

    #include <stdio.h>
    int f(void) { printf("f called\n"); return 3; }
    int g(void) { printf("g called\n"); return 4; }
    int h(void) { printf("h called\n"); return 5; }

    and use this with the "answer" code fragment, the "f called", "g
    called", and "h called" lines can come out in any of the six possible
    orders (fgh, fhg, gfh, ghf, hfg, hgf).

    The second, more obvious problem is that "precedence" fails to tell
    you what to do if multiple operators have the "same precedence":

    answer = f2 / g2 / h2;

    Does this mean (f2/g2) / h2, or f2 / (g2/h2)? So people who use
    "precedence" add "associativity" to break ties.

    (The C Standards -- C89 and C99 both -- do not use precedence and
    associativity. Instead, they use a "fully factored grammar". From
    this grammar, one can derive precedence-and-associativity tables.
    Several different tables are possible, so if you find two that
    differ, they may both be correct. None of this is important as long
    as you, and the compilers, get the correct final binding.)

    In any case, let us now go back to the expressions:

    >*(pw+1)[2]


    The subscript operator binds more tightly than the unary "*" operator
    -- that is, *a "means" *(a) and not (*a) -- so this binds
    the same as:

    *((pw + 1)[2])

    Then, given the definition that a "means" (*(a) + (b)), this
    means the same as:

    *( *((pw + 1) + 2))

    which "means":

    *(*(pw + 3))

    which in turn "means":

    pw[3][0]

    But pw points to &w[0], and w has only two valid subscript values
    for "i", namely 0 and 1.

    Had you written:

    (*(pw + 1))[2]

    we could translate this to:

    pw[1][2]

    which *is* valid.

    >*(w[0]+2)


    This binds as:

    *((w[0]) + 2)

    Again, *(a + b) can be translated back to simply a, so:

    *(w[0] + 2)

    is just:

    w[0][2]

    >pw[0][0]


    This one should be obvious.

    >*(pw[1]+2)


    Again, we just use the equivalency and get:

    pw[1][2]

    Note that *p, for any pointer p, can be rewritten as p[0] (and
    vice versa) -- but because the operators have different binding
    strengths, you may have to add parentheses when doing this. In
    particular, since [] "binds tighter than" unary * -- or as many
    people prefer to think of it, [] is "higher precedence" than unary
    "*" -- rewriting p[0] as (*p) can require adding these parentheses,
    so that the unary "*" still binds to "p" before some other operator
    can bind to it.

    If you want to know more about arrays, pointers, and arrays of
    arrays in general, see <http://web.torek.net/torek/c/pa.html>.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Aug 21, 2007
    #9
  10. drazet

    drazet Guest

    pete 写é“:
    > drazet wrote:
    >> Army1987 写é“:
    >>> On Mon, 20 Aug 2007 14:55:40 -0400, CBFalconer wrote:
    >>>
    >>>> drazet wrote:
    >>>>> i have a question about multidimensional array.
    >>>>>
    >>>>> int w[2][3],(*pw)[3];
    >>>>> pw=w;
    >>>>>
    >>>>> is *(pw+1)[2] wrong?why?
    >>>>> and *(w[0]+2),pw[0][0] and *(pw[1]+2) mean?
    >>>> Consider the following display:
    >>>>
    >>>> [1] c:\c\dispbase>explain int w[2][3]
    >>>> declare w as array 2 of array 3 of int
    >>>>
    >>>> [1] c:\c\dispbase>explain int (*pw)[3]
    >>>> declare pw as pointer to array 3 of int
    >>>>
    >>>> [1] c:\c\dispbase>alias explain
    >>>> cdecl explain %1&
    >>>>
    >>>> a pw probably can't hold any w. Use legitimate code first.
    >>> w evaluates to &w[0], which is a pointer to array 3 of int. So
    >>> what's wrong with pw = w?

    >> pw = w is right,my question is that why the use of "*(w[0]+2),pw[0][0]
    >> and *(pw[1]+2) "can get a right value,but "*(pw+1)[2]"gets a wrong?

    >
    > It's supposed to be:
    >
    > (*(pw+1))[2]
    >
    >
    > /* BEGIN new.c */
    >
    > #include <stdio.h>
    >
    > int main(void)
    > {
    > int w[2][3] = {1,2,3,4,5,6};
    > int (*pw)[3];
    >
    > pw = w;
    > printf("%d\n", (*(pw+1))[2]);
    > return pw != w;
    > }
    >
    > /* END new.c */
    >

    thanks a lot, i understand it,the (pw+1)[2] is the address of
    w[3][0],but (*(pw+1))[2] is w[1][2].
     
    drazet, Aug 21, 2007
    #10
  11. drazet

    drazet Guest

    Chris Torek дµÀ:
    > In article <fabnkp$goe$> drazet <> wrote:
    > [given]
    >> int w[2][3],(*pw)[3];
    >> pw=w;
    >>
    >> is *(pw+1)[2] wrong? why?

    >
    > Yes. As for why, well, one moment:
    >
    >> and *(w[0]+2),pw[0][0] and *(pw[1]+2) mean?

    >
    > I think you are making an elementary mistake in parsing these
    > expressions.
    >
    > Whenever you go to figure out an expression, you have to know
    > (or look up) the way the various operators involve "bind". Most
    > people do this with an "operator precedence table", which is
    > convenient, but somewhat misleading.
    >
    > A precedence table tells you things like "multiply before add",
    > for instance, so that in an expression like:
    >
    > 3 + 4 * 5
    >
    > you know to multiply 4 by 5 first, then add 3 (result = 23), rather
    > than add 3 and 4 first, then multiply by 5 (result = 35).
    >
    > Precedence is misleading in two ways. First -- and most important
    > -- it tends to make people do *everything* in "precedence order":
    >
    > int f(void), g(void), h(void);
    > int answer;
    >
    > answer = f() + g() * h();
    >
    > If you, as a human, go to "do the multiply first", you will probably
    > also call g() first, then h(), then f(), in that order. A C compiler
    > does not have to do this: it can call f() first, if it "wants to",
    > and then call h(), and then g(), if it "feels like it", as long as
    > it then uses the results of g() and h() to multiply, and the result
    > of that and f() to add, to compute the final value for "answer". If
    > you make f(), g(), and h() print their names:
    >
    > #include <stdio.h>
    > int f(void) { printf("f called\n"); return 3; }
    > int g(void) { printf("g called\n"); return 4; }
    > int h(void) { printf("h called\n"); return 5; }
    >
    > and use this with the "answer" code fragment, the "f called", "g
    > called", and "h called" lines can come out in any of the six possible
    > orders (fgh, fhg, gfh, ghf, hfg, hgf).
    >
    > The second, more obvious problem is that "precedence" fails to tell
    > you what to do if multiple operators have the "same precedence":
    >
    > answer = f2 / g2 / h2;
    >
    > Does this mean (f2/g2) / h2, or f2 / (g2/h2)? So people who use
    > "precedence" add "associativity" to break ties.
    >
    > (The C Standards -- C89 and C99 both -- do not use precedence and
    > associativity. Instead, they use a "fully factored grammar". From
    > this grammar, one can derive precedence-and-associativity tables.
    > Several different tables are possible, so if you find two that
    > differ, they may both be correct. None of this is important as long
    > as you, and the compilers, get the correct final binding.)
    >
    > In any case, let us now go back to the expressions:
    >
    >> *(pw+1)[2]

    >
    > The subscript operator binds more tightly than the unary "*" operator
    > -- that is, *a "means" *(a) and not (*a) -- so this binds
    > the same as:
    >
    > *((pw + 1)[2])
    >
    > Then, given the definition that a "means" (*(a) + (b)), this
    > means the same as:
    >
    > *( *((pw + 1) + 2))
    >
    > which "means":
    >
    > *(*(pw + 3))
    >
    > which in turn "means":
    >
    > pw[3][0]
    >
    > But pw points to &w[0], and w has only two valid subscript values
    > for "i", namely 0 and 1.
    >
    > Had you written:
    >
    > (*(pw + 1))[2]
    >
    > we could translate this to:
    >
    > pw[1][2]
    >
    > which *is* valid.
    >
    >> *(w[0]+2)

    >
    > This binds as:
    >
    > *((w[0]) + 2)
    >
    > Again, *(a + b) can be translated back to simply a, so:
    >
    > *(w[0] + 2)
    >
    > is just:
    >
    > w[0][2]
    >
    >> pw[0][0]

    >
    > This one should be obvious.
    >
    >> *(pw[1]+2)

    >
    > Again, we just use the equivalency and get:
    >
    > pw[1][2]
    >
    > Note that *p, for any pointer p, can be rewritten as p[0] (and
    > vice versa) -- but because the operators have different binding
    > strengths, you may have to add parentheses when doing this. In
    > particular, since [] "binds tighter than" unary * -- or as many
    > people prefer to think of it, [] is "higher precedence" than unary
    > "*" -- rewriting p[0] as (*p) can require adding these parentheses,
    > so that the unary "*" still binds to "p" before some other operator
    > can bind to it.
    >
    > If you want to know more about arrays, pointers, and arrays of
    > arrays in general, see <http://web.torek.net/torek/c/pa.html>.

    thanks a lot ~!~
     
    drazet, Aug 21, 2007
    #11
  12. drazet

    Alan Curry Guest

    In article <fabnkp$goe$>, drazet <> wrote:
    >hi,all
    >
    >i have a question about multidimensional array.
    >
    >int w[2][3],(*pw)[3];
    >pw=w;
    >
    >is *(pw+1)[2] wrong?why?


    The [] has higher precedence than the * so this part:

    (pw+1)[2]

    is evaluated first. It's equivalent to these:

    *((pw+1)+2)
    *(pw+3)
    pw[3]
    w[3]

    which is out of bounds.

    (*(pw+1))[2] would be something different. Maybe it's what you meant.

    --
    Alan Curry
     
    Alan Curry, Aug 21, 2007
    #12
  13. drazet

    CBFalconer Guest

    drazet wrote:
    >

    .... snip about 140 lines ...

    > thanks a lot ~!~


    Again, this answer, which was exactly as quoted, no less, obviously
    required quoting all those 140 lines. Why can't people learn to
    snip - its really quite easy.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Aug 21, 2007
    #13
  14. drazet

    somenath Guest


    >
    > Then, given the definition that a "means" (*(a) + (b)), this


    Will it not be *((a) + (b)) ?
     
    somenath, Aug 21, 2007
    #14
  15. drazet

    pete Guest

    CBFalconer wrote:
    >
    > drazet wrote:
    > >

    > ... snip about 140 lines ...
    >
    > > thanks a lot ~!~

    >
    > Again, this answer, which was exactly as quoted, no less, obviously
    > required quoting all those 140 lines. Why can't people learn to
    > snip - its really quite easy.



    "Sometimes I do that as a cheap and easy way of saving
    the explanation in my email "Sent box"."
    --
    pete

    "Hey, I have a patent on that. Cease and desist immediately, or you
    will hear from my lawyers."
    --
    Chuck F (cbfalconer at maineline dot net)

    http://groups.google.com/group/comp.lang.c/msg/0a9c5003e8145cb4?dmode=source

    --
    pete
     
    pete, Aug 21, 2007
    #15
  16. drazet

    pete Guest

    somenath wrote:
    >
    > >
    > > Then, given the definition that a "means" (*(a) + (b)), this

    >
    > Will it not be *((a) + (b)) ?


    It is *((a) + (b)).

    (a) does not imply which of a or b is the pointer.

    --
    pete
     
    pete, Aug 21, 2007
    #16
  17. somenath said:

    >
    >>
    >> Then, given the definition that a "means" (*(a) + (b)), this

    >
    > Will it not be *((a) + (b)) ?


    Yes.

    Congratulations! You caught out Chris Torek in a mistake. That is such a
    rare achievement as to deserve a modding up.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Aug 21, 2007
    #17
  18. pete said:

    > somenath wrote:
    >>
    >> >
    >> > Then, given the definition that a "means" (*(a) + (b)), this

    >>
    >> Will it not be *((a) + (b)) ?

    >
    > It is *((a) + (b)).
    >
    > (a) does not imply which of a or b is the pointer.


    He didn't say it did. Read CT's upthread article again - it is indeed
    incorrect, and that was a very good spot indeed from somenath.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Aug 21, 2007
    #18
  19. drazet

    Richard Guest

    pete <> writes:

    > CBFalconer wrote:
    >>
    >> drazet wrote:
    >> >

    >> ... snip about 140 lines ...
    >>
    >> > thanks a lot ~!~

    >>
    >> Again, this answer, which was exactly as quoted, no less, obviously
    >> required quoting all those 140 lines. Why can't people learn to
    >> snip - its really quite easy.

    >
    >
    > "Sometimes I do that as a cheap and easy way of saving
    > the explanation in my email "Sent box"."
    > --
    > pete
    >
    > "Hey, I have a patent on that. Cease and desist immediately, or you
    > will hear from my lawyers."
    > --
    > Chuck F (cbfalconer at maineline dot net)
    >
    > http://groups.google.com/group/comp.lang.c/msg/0a9c5003e8145cb4?dmode=source


    So, the only contribution from Falconer is a wrong answer and a net
    nanny. Good to see things don't change.
     
    Richard, Aug 21, 2007
    #19
  20. drazet

    Chris Torek Guest

    [I wrote]
    >> Then, given the definition that a "means" (*(a) + (b)), this


    In article <>,
    somenath <> wrote:
    >Will it not be *((a) + (b)) ?


    Oops, yes! Sorry, I managed to typo the placement of the "*" (or
    miss out on a set of parentheses, although in this case I just
    meant to put the "*" first).
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Aug 21, 2007
    #20
    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. Dave Bazell

    slice of multidimensional array

    Dave Bazell, Jul 23, 2003, in forum: Perl
    Replies:
    2
    Views:
    4,083
  2. epigram
    Replies:
    1
    Views:
    10,820
    =?Utf-8?B?c29jaWV0b3BpYS5uZXQ=?=
    Jul 16, 2005
  3. Ben
    Replies:
    8
    Views:
    12,649
    Eki Y. Baskoro
    Dec 18, 2003
  4. Huub
    Replies:
    6
    Views:
    611
  5. geletine
    Replies:
    12
    Views:
    21,671
    Fred Kleinschmidt
    May 5, 2006
Loading...

Share This Page