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[b] "means" *(a[b]) and not (*a)[b] -- so this binds
the same as:
*((pw + 1)[2])
Then, given the definition that a[b] "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[i] 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[b], 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 (4039.22'N, 11150.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.