Re: Two dimensional array Question



mdh said:

<snip>

Although once admonished for writing code to figure things out, a weak
attempt follows.

Writing code "to figure things out" is a two-edged sword. It can certainly
be helpful for discovering how things *appear* to work, but it is a poor
guide for discovering how things *must* work. For example, the way a
for-loop works is well-defined, so if we've forgotten whether the
increment step (it isn't necessarily an increment, but let's keep things
simple) of a for-loop is always executed at least once, we can write a
quick program to find out:

#include <stdio.h>

int main(void)
{
int i;
int j = 0;
for(i = 0; i < j; i++)
{
printf("i is now %d\n");
}
printf("Outside the loop, i is now %d\n");
return 0;
}

and this is perfectly okay. What we /can't/ do is take a program like this:

#include <stdio.h>

int main(void)
{
printf("%d\n", 'A');
return 0;
}

and deduce from its output that the value of 'A' is *required* to be 193.
After all, you might not be running this program on an EBCDIC system.

So we have to be careful, that's all. Now, to your question:


#include <stdio.h>

int main (int argc, const char * argv[])
{
int i, j, k, l;
char arr [3][3] = {"One", "Two", "Lst"};

Legal, but dangerous. Don't treat these arrays of char as if they were
strings. They aren't.

char *p;
char **q;

for ( i = 0; i < 3; i ++)
for ( j= 0; j < 3; j++)
{
p=&arr[i][j];
printf( "%p\n", p);

Although the representations of char * and void * are required to be the
same, it is generally wiser to insist on void * for %p:

printf("%p\n", (void *)p);

}

putchar('\n');

for ( k = 0; k < 3; k ++)
for ( l= 0; l < 3; l++)
{
p=arr[k];
q=&arr[k][l];
printf( "%s %s\n", p, q);

You fell into the trap. Neither p nor q points at a string.

}
}
output:

....is irrelevant, since the program invokes undefined behaviour by treating
non-strings as if they were strings.

<snip>

Which I think says, as mentioned above, that the addresses are
contiguous. So at least that is an easy visual and conceptual concept
to comprehend.

The easiest way to comprehend multidimensional arrays is to think of them
as arrays of arrays. If you never try to breach the bounds of an object,
all will be well. By treating arrays-of-arrays as if they were a single
contiguous object (EVEN IF THAT IS TRUE), you're violating that principle.
Now, there are times when it can be necessary to do that (for example,
inspecting object representations), but one should tread very carefully
when so doing.

And to repeat what you put far more elegantly, more to see if I am
understanding it,
char *p in the context of the declaration arr[m][n], is a "row"
and char **q, is a character?

Not quite. In your first loop you point p to an individual character, so
that's what it points at. In your second loop, you point p to the first
element in an array, so it's reasonable to think of p as pointing at a
row.

q is only used in the second loop, where it most certainly is not a
character but yes, it does point at one.

--
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
.



Relevant Pages

  • Re: Problems with CLAPACK SVD routines on OS X
    ... but for delete arrays you must use: ... int main{ ... char JOBVT; ... integer INFO; ...
    (sci.math.num-analysis)
  • Re: Doubt
    ... int mainis better. ... void change (char *b) ... This is automatically done in the case of arrays, ...
    (comp.lang.c)
  • Re: C Strings
    ... I thought string literals were arrays until you operated on them, ... int main ... char *p1; ...
    (comp.lang.c)
  • Re: Variable length arrays proposal
    ... int length; char data;} String; ... It wouldn't be logical to restrict it to arrays of char, so you could apply the same logic to arrays of String, and arrays of those. ...
    (comp.std.c)
  • SSPI Kerberos for delegation
    ... const char *tokenSource, const char *name = NULL, ... DWORD bufsiz = sizeof buf; ... int n = ib.cbBuffer; ... // wserr() displays winsock errors and aborts. ...
    (microsoft.public.dotnet.framework.remoting)