|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
I am still having a problem understanding K&RII on p 112. I have
looked at the FAQs --which I am sure answer it in a way that I have missed, so here goes. A 2-dim array, (per K&R) is really a 1-dim array, each of whose elements is an array. Looking at the debugger I use, arr[2][13] is shown as an initial value of "2", but when expanded, there are 2 consecutive arrays of 13 elements. So, may I ask this? Is there anything special that marks the end of the first 13 elements from the beginning of the 2nd 13 elements? In other words, it seems to me that this is nothing more than a 1-dim array, with the information about the structure of the array provided by the declaration? Hopefully this makes sense. The exercise associated with this, used the construct *p = arr[1 or 0 ] to point to either the "first" or "second" row of the array. Does the compiler "know" where to point to because it has been given this information by the declaration of "13" in arr[2][13]. Hopefully this makes sense too! And lastly, K&R's description of "each of whose elements is an array" has never made sense to me. It may be that the answer to the above may clarify it. Thanks in advance. |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
mdh wrote:
> I am still having a problem understanding K&RII on p 112. I have > looked at the FAQs --which I am sure answer it in a way that I have > missed, so here goes. > A 2-dim array, (per K&R) is really a 1-dim array, each of whose > elements is an array. > Looking at the debugger I use, arr[2][13] is shown as an initial value > of "2", but when expanded, there are 2 consecutive arrays of 13 > elements. > So, may I ask this? > Is there anything special that marks the end of the first 13 elements > from the beginning of the 2nd 13 elements? In other words, it seems to > me that this is nothing more than a 1-dim array, with the information > about the structure of the array provided by the declaration? > Hopefully this makes sense. > Perfect sense. All above is correct. Given 'int arr[2][13];', arr is an array 2 of array 13 of int. 26 consecutive ints. > The exercise associated with this, used the construct > > *p = arr[1 or 0 ] to point to either the "first" or "second" row of > the array. Does the compiler "know" where to point to because it has > been given this information by the declaration of "13" in arr[2][13]. > Hopefully this makes sense too! > No. arr[0] is (the address of) an array 13 of int. The pointer 'p' must be declared to reflect this. int (*p)[13]; Now p is a pointer to array 13 of int and.. p = arr[0]; ...makes sense. > > And lastly, K&R's description of "each of whose elements is an array" > has never made sense to me. It may be that the answer to the above may > clarify it. > I hope so. You're really not too far off. Hang in there. > Thanks in advance. -- Joe Wright "Everything should be made as simple as possible, but not simpler." --- Albert Einstein --- |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Joe Wright wrote:
> mdh wrote: > Perfect sense. All above is correct. Given 'int arr[2][13];', arr is > an array 2 of array 13 of int. 26 consecutive ints. > > > The exercise associated with this, used the construct > > > > *p = arr[1 or 0 ] to point to either the "first" or "second" row of > > the array. Does the compiler "know" where to point to because it has > > been given this information by the declaration of "13" in > > arr[2][13]. Hopefully this makes sense too! > > > No. arr[0] is (the address of) an array 13 of int. No, it's not. It is an array 13 of int, not a pointer to one. arr is a pointer to array 13 of int. > The pointer 'p' > must be declared to reflect this. > > int (*p)[13]; > > Now p is a pointer to array 13 of int and.. > > p = arr[0]; > > ..makes sense. Not to me. p = &arr[0]; Would. Or what the OP had: int *p; p = arr[0]; Brian |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
mdh <mdeh@comcast.net> writes:
<When discussing int a[2][13];> > And lastly, K&R's description of "each of whose elements is an array" > has never made sense to me. It may be that the answer to the above may > clarify it. Another thought... Do you have a problem with: struct ints { int a,b,c,d,e,f,g,h,i,j,k,l,m; }; struct ints a[2]; being an array, each of whose elements is a structure of 13 ints? What if we say: struct ints { int e[13]; }; struct ints a[2]; For many people the trouble is the way it is written. If it were something like: 'int[13] a[2];' they might find it easier to swallow but the array declarators group like this: int (a[2]) [13] ; (you can write that if you want!) so a is "an array of 2... arrays of 13... ints. I think you are very close to "getting it". -- Ben. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Default User wrote:
> Joe Wright wrote: > >> mdh wrote: > >> Perfect sense. All above is correct. Given 'int arr[2][13];', arr is >> an array 2 of array 13 of int. 26 consecutive ints. >> >>> The exercise associated with this, used the construct >>> >>> *p = arr[1 or 0 ] to point to either the "first" or "second" row of >>> the array. Does the compiler "know" where to point to because it has >>> been given this information by the declaration of "13" in >>> arr[2][13]. Hopefully this makes sense too! >>> >> No. arr[0] is (the address of) an array 13 of int. > > No, it's not. It is an array 13 of int, not a pointer to one. arr is a > pointer to array 13 of int. You just made the same mistake that you just corrected. arr isn't any more of a pointer than arr[0] is. arr isn't any less of an array than arr[0] is. (sizeof arr) equals (2 * 13 * sizeof(int)). -- pete |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Thanks to all who responded. It makes a *little* more sense now, but I
think it will hopefully clear up with time and practice. |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On Thu, 8 May 2008 08:16:13 -0700 (PDT), mdh <mdeh@comcast.net> wrote:
>I am still having a problem understanding K&RII on p 112. I have >looked at the FAQs --which I am sure answer it in a way that I have >missed, so here goes. >A 2-dim array, (per K&R) is really a 1-dim array, each of whose >elements is an array. The C99 standard uses the term "multidinensional array" so K&R is slightly out of date in this regard. >Looking at the debugger I use, arr[2][13] is shown as an initial value >of "2", but when expanded, there are 2 consecutive arrays of 13 >elements. What do you mean by "2". Is it an array of char arrays and the first of such holds the string '2' '\0'? >So, may I ask this? >Is there anything special that marks the end of the first 13 elements >from the beginning of the 2nd 13 elements? In other words, it seems to No. It is prohibited. arr[1] must immediately follow arr[0] in memory. >me that this is nothing more than a 1-dim array, with the information >about the structure of the array provided by the declaration? >Hopefully this makes sense. It is true that the 26 "basic elements" of arr will appear in memory "linearly". This has prompted many debates about whether a pointer to arr[0][0] can be used with subscripts ranging from 0 to 25 to access all 26. What is not in dispute is that in a 1d array T x[N], x[0] evaluates to an element of type T. In your case, arr[0] evaluates to an array of T. To my mind, this is sufficient to say arr cannot be considered a 1d array. > >The exercise associated with this, used the construct > > *p = arr[1 or 0 ] to point to either the "first" or "second" row of >the array. Does the compiler "know" where to point to because it has >been given this information by the declaration of "13" in arr[2][13]. >Hopefully this makes sense too! Yes and yes. > > >And lastly, K&R's description of "each of whose elements is an array" >has never made sense to me. It may be that the answer to the above may >clarify it. arr[0] is an array 13 T. arr[1] is an array of 13 T. arr[2] does not exist. arr[i][j] is an object of type T as long as 0<=i<=1 and 0<=j<=12. arr[i][j] is an element of arr[i] but not element of arr. arr[i] is an element of arr and it is an array. Remove del for email |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
On May 8, 8:54pm, Barry Schwarz <schwa...@dqel.com> wrote:
> > > The C99 standard uses the term "multidinensional array" so K&R is > slightly out of date in this regard. > > >Looking at the debugger I use, arr[2][13] is shown as an initial value > >of "2", but when expanded, there are 2 consecutive arrays of 13 > >elements. > > What do you mean by "2". Is it an array of char arrays and the first > of such holds the string '2' '\0'? I am using Xcode...not that that probably makes any difference. Initially arr[2][13] is declared as a char array. In the debugger window, there is a column for value and the "initial" value of arr is "2". If one expands this, then one sees 2 arrays of 13 elements, and as you say below, these seem to be contiguous. I was trying to find a way of seeing what the address of each element is, but have been unable to do so.... > > It is true that the 26 "basic elements" of arr will appear in memory > "linearly". This has prompted many debates about whether a pointer to > arr[0][0] can be used with subscripts ranging from 0 to 25 to access > all 26. What is not in dispute is that in a 1d array T x[N], x[0] > evaluates to an element of type T. In your case, arr[0] evaluates to > an array of T. To my mind, this is sufficient to say arr cannot be > considered a 1d array. > thank you Barry. |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
pete wrote:
> Default User wrote: > > Joe Wright wrote: > > > > > mdh wrote: > > > > > Perfect sense. All above is correct. Given 'int arr[2][13];', arr > > > is an array 2 of array 13 of int. 26 consecutive ints. > > > > > > > The exercise associated with this, used the construct > > > > > > > > *p = arr[1 or 0 ] to point to either the "first" or "second" > > > > row of the array. Does the compiler "know" where to point to > > > > because it has been given this information by the declaration > > > > of "13" in arr[2][13]. Hopefully this makes sense too! > > > > > > > No. arr[0] is (the address of) an array 13 of int. > > > > No, it's not. It is an array 13 of int, not a pointer to one. arr > > is a pointer to array 13 of int. > > You just made the same mistake that you just corrected. Yes, I did in a way. I was sloppy about context. It is correct that arr is not a pointer, although it's converted to one in most contexts. The code was correct, which it wasn't originally. Thanks for clarifying my stab at i. Brian |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
> > > >The exercise associated with this, used the construct > > > *p = arr[1 or 0 ] to point to either the "first" or "second" row of > >the array. Does the compiler "know" where to point to because it has > >been given this information by the declaration of "13" in arr[2][13]. > >Hopefully this makes sense too! > > Yes and yes. > I was in a hurry to get to work this am...so forgot to ask this. In a multidimensional array, one can simply drop the second []? as in *p=arr[i] and this is legal? Thanks. |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
mdh wrote:
>> >>> The exercise associated with this, used the construct >>> *p = arr[1 or 0 ] to point to either the "first" or "second" row of >>> the array. Does the compiler "know" where to point to because it has >>> been given this information by the declaration of "13" in arr[2][13]. >>> Hopefully this makes sense too! >> Yes and yes. >> > I was in a hurry to get to work this am...so forgot to ask this. > In a multidimensional array, one can simply drop the second []? as in > *p=arr[i] and this is legal? > Thanks. It's legal regardless of whether or not you understand what you're writing. But it's better if you realize that *p = arr[i]; means the same thing as *p = &arr[i][0]; because &arr[i][0] means &*(*(arr + i) + 0) which can be simplified to (*(arr + i) + 0) *(arr + i) arr[i] -- pete |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
pete <pfiland@mindspring.com> writes:
> mdh wrote: >>> >>>> The exercise associated with this, used the construct >>>> *p = arr[1 or 0 ] to point to either the "first" or "second" row of >>>> the array. Does the compiler "know" where to point to because it has >>>> been given this information by the declaration of "13" in arr[2][13]. >>>> Hopefully this makes sense too! >>> Yes and yes. >>> >> I was in a hurry to get to work this am...so forgot to ask this. >> In a multidimensional array, one can simply drop the second []? as in >> *p=arr[i] and this is legal? >> Thanks. > > It's legal regardless of whether or not > you understand what you're writing. > But it's better if you realize that > > *p = arr[i]; > > means the same thing as > > *p = &arr[i][0]; The trouble is this phrase "means the same as". Both right hand sides are certainly closely related expressions, but they have different types, different sizes (sizeof arr[i] != sizeof &arr[i][0]) and they can't be used in the same places (you can, for example take the address of one but not of the other). Sometimes it s to gloss over these differences and sometimes it does not. I am not sure which is the case here. > because > > &arr[i][0] means &*(*(arr + i) + 0) > > which can be simplified to > > (*(arr + i) + 0) > *(arr + i) > arr[i] C is not good for equational reasoning. The OP might find this ful: #include <stdio.h> #define PSZ(exp) printf("sizeof " #exp " = %d\n", (int)sizeof exp) int main(void) { int i = 0; int arr[2][13] = {0}; PSZ(&arr[i][0]); PSZ(&*(*(arr + i) + 0)); PSZ((*(arr + i) + 0)); PSZ(*(arr + i)); PSZ(arr[i]); return 0; } -- Ben. |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
Ben Bacarisse wrote:
> pete <pfiland@mindspring.com> writes: > >> mdh wrote: >>>>> The exercise associated with this, used the construct >>>>> *p = arr[1 or 0 ] to point to either the "first" or "second" row of >>>>> the array. Does the compiler "know" where to point to because it has >>>>> been given this information by the declaration of "13" in arr[2][13]. >>>>> Hopefully this makes sense too! >>>> Yes and yes. >>>> >>> I was in a hurry to get to work this am...so forgot to ask this. >>> In a multidimensional array, one can simply drop the second []? as in >>> *p=arr[i] and this is legal? >>> Thanks. >> It's legal regardless of whether or not >> you understand what you're writing. >> But it's better if you realize that >> >> *p = arr[i]; >> >> means the same thing as >> >> *p = &arr[i][0]; > > The trouble is this phrase "means the same as". Both right hand sides > are certainly closely related expressions, but they have different > types, different sizes (sizeof arr[i] != sizeof &arr[i][0]) and they > can't be used in the same places (you can, for example take the > address of one but not of the other). Think harder. *p = arr[i]; means the same thing as *p = (arr[i] + 0); sizeof arr[i] does not mean the same thing as sizeof (arr[i] + 0) My claim was about two expression statements. You're talking about array type expressions in a context which is irrelevant to this. Consider new.c: Do you think new.c is missing a cast somewhere? Do you have a compiler that thinks that new.c is missing a cast somewhere? Do you know under what circumstances cast operators are required in C? /* BEGIN new.c */ int main(void) { int arr[2][13] = {0}; int **p1; int **p2; *p1 = arr[1]; *p2 = &arr[1][0]; return *p1 != *p2; } /* END new.c */ -- pete |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
Ben Bacarisse wrote:
> pete <pfiland@mindspring.com> writes: > >> mdh wrote: >>>>> The exercise associated with this, used the construct >>>>> *p = arr[1 or 0 ] to point to either the "first" or "second" row of >>>>> the array. Does the compiler "know" where to point to because it has >>>>> been given this information by the declaration of "13" in arr[2][13]. >>>>> Hopefully this makes sense too! >>>> Yes and yes. >>>> >>> I was in a hurry to get to work this am...so forgot to ask this. >>> In a multidimensional array, one can simply drop the second []? as in >>> *p=arr[i] and this is legal? >>> Thanks. >> It's legal regardless of whether or not >> you understand what you're writing. >> But it's better if you realize that >> >> *p = arr[i]; >> >> means the same thing as >> >> *p = &arr[i][0]; > > The trouble is this phrase "means the same as". Both right hand sides > are certainly closely related expressions, but they have different > types, different sizes (sizeof arr[i] != sizeof &arr[i][0]) and they > can't be used in the same places (you can, for example take the > address of one but not of the other). > > Sometimes it s to gloss over these differences and sometimes it > does not. I am not sure which is the case here. > >> because >> >> &arr[i][0] means &*(*(arr + i) + 0) >> >> which can be simplified to >> >> (*(arr + i) + 0) >> *(arr + i) >> arr[i] > > C is not good for equational reasoning. The OP might find this > ful: > > #include <stdio.h> > > #define PSZ(exp) printf("sizeof " #exp " = %d\n", (int)sizeof exp) > > int main(void) > { > int i = 0; > int arr[2][13] = {0}; > > PSZ(&arr[i][0]); > PSZ(&*(*(arr + i) + 0)); > PSZ((*(arr + i) + 0)); > PSZ(*(arr + i)); > PSZ(arr[i]); > > return 0; > } > All true on the face of it but sizeof was not what was asked, it was assignment. Given.. int *p; p = arr[i]; Yes, arr[i] is an array 13 of int but expressing an array as above yields the address of its first element, in this case int*. p = &arr[i][0]; The address of the int yields the same int*. -- Joe Wright "Everything should be made as simple as possible, but not simpler." --- Albert Einstein --- |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
pete <pfiland@mindspring.com> writes:
> Ben Bacarisse wrote: >> pete <pfiland@mindspring.com> writes: <snip> >>> But it's better if you realize that >>> >>> *p = arr[i]; >>> >>> means the same thing as >>> >>> *p = &arr[i][0]; >> >> The trouble is this phrase "means the same as". Both right hand sides >> are certainly closely related expressions, but they have different >> types, different sizes (sizeof arr[i] != sizeof &arr[i][0]) and they >> can't be used in the same places (you can, for example take the >> address of one but not of the other). > > Think harder. OK, but you'll have to me if you think I've missed something. I really do think I get it. I know you meant "in most expression contexts" and I did not say you said anything wrong. All I was saying is that it sometimes s to know the ways in which they *don't* mean the same thing. Obviously you disagree, and that is fine. Only the OP can say which is more ful in "getting it". > *p = arr[i]; > means the same thing as > *p = (arr[i] + 0); > > sizeof arr[i] > does not mean the same thing as > sizeof (arr[i] + 0) Of course not, and that is one reason why I'd be loath to say that arr[i] and &arr[i][0] mean the same thing. sizeof &arr[i][0] *does* mean the same thing as sizeof (&arr[i][0] + 0) (as do '*p = &arr[i][0];' and '*p = &arr[i][0] + 0;'). All this does is to highlight that we expect different things from two expressions that "mean the same". -- Ben. |
|
|
|
#16 |
|
Messages: n/a
Hébergeur: |
Joe Wright <joewwright@comcast.net> writes:
<snip> > All true on the face of it but sizeof was not what was asked, it was > assignment. Yes, I know I took it out of context. It was deliberate because I wanted to point out that context was critical. Maybe I complicated matters and, if so, I am sorry. -- Ben. |
|
|
|
#17 |
|
Messages: n/a
Hébergeur: |
Ben Bacarisse wrote:
> pete <pfiland@mindspring.com> writes: > >> Ben Bacarisse wrote: >>> pete <pfiland@mindspring.com> writes: > <snip> >>>> But it's better if you realize that >>>> >>>> *p = arr[i]; >>>> >>>> means the same thing as >>>> >>>> *p = &arr[i][0]; >>> The trouble is this phrase "means the same as". Both right hand sides >>> are certainly closely related expressions, but they have different >>> types, different sizes (sizeof arr[i] != sizeof &arr[i][0]) and they >>> can't be used in the same places (you can, for example take the >>> address of one but not of the other). >> Think harder. > > OK, but you'll have to me if you think I've missed something. I > really do think I get it. > > I know you meant "in most expression contexts" I didn't mean that. I meant that given int arr[2][13], **p, i; then *p = arr[i]; means exactly the same thing as *p = &arr[i][0]; -- pete |
|
|
|
#18 |
|
Messages: n/a
Hébergeur: |
pete <pfiland@mindspring.com> writes:
> Ben Bacarisse wrote: <snip> >> OK, but you'll have to me if you think I've missed something. I >> really do think I get it. >> >> I know you meant "in most expression contexts" > > I didn't mean that. > I meant that given > > int arr[2][13], **p, i; > > then > > *p = arr[i]; > > means exactly the same thing as > > *p = &arr[i][0]; Gotcha. You were making a very narrow point. Sadly, you led me a little up the path I ended up running down. Rather than stopping there, you went on to expand &arr[i][0] in stages (without the *p = context) which I jumped on as implying a more general equivalence. If you'd kept the context and written: "*p = &arr[i][0] means *p = &*(*(arr + i) + 0) which can be simplified to *p = (*(arr + i) + 0) *p = *(arr + i) *p = arr[i] I hope I'd have kept out of it. -- Ben. |
|
|
|
#19 |
|
Messages: n/a
Hébergeur: |
On May 9, 8:35pm, mdh <m...@comcast.net> wrote:
> I was in a hurry to get to work this am...so forgot to ask this. > In a multidimensional array, one can simply drop the second []? as in > *p=arr[i] and this is legal? Depending on the type of p. If arr is defined as T arr[N][M], then for your code to be legal, p must be a T**. *p will then have type T* and arr[i] will be converted to &arr[i][0] which is also of type T*. Far more common is for p to be a T* and the assignment to read p = arr[i]. |
|
|
|
#20 |
|
Messages: n/a
Hébergeur: |
On May 11, 4:17am, Barry Schwarz <schwar...@yahoo.com> wrote:
> On May 9, 8:35pm, mdh <m...@comcast.net> wrote: > > > Depending on the type of p. If arr is defined as T arr[N][M], then > for your code to be legal, p must be a T**. *p will then have type T* > and arr[i] will be converted to &arr[i][0] which is also of type T*. > > Far more common is for p to be a T* and the assignment to read > p = arr[i]. Well...I **think** I see it a little more clearly. Although once admonished for writing code to figure things out, a weak attempt follows. #include <stdio.h> int main (int argc, const char * argv[]) { int i, j, k, l; char arr [3][3] = {"One", "Two", "Lst"}; char *p; char **q; for ( i = 0; i < 3; i ++) for ( j= 0; j < 3; j++) { p=&arr[i][j]; printf( "%p\n", 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); } } output: 0xbffff7cf 0xbffff7d0 0xbffff7d1 0xbffff7d2 0xbffff7d3 0xbffff7d4 0xbffff7d5 0xbffff7d6 0xbffff7d7 OneTwoLst OneTwoLst OneTwoLst neTwoLst OneTwoLst eTwoLst TwoLst TwoLst TwoLst woLst TwoLst oLst Lst Lst Lst st Lst t 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. 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? |
|
|
|
#21 |
|
Messages: n/a
Hébergeur: |
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 ful 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 |
|
|
|
#22 |
|
Messages: n/a
Hébergeur: |
[sigh]
Richard Heathfield said: > 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 ful 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"); Spot both... > } > printf("Outside the loop, i is now %d\n"); ....mistakes. :-( > return 0; > } > > and this is perfectly okay ....after fixing! -- 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 |
|
|
|
#23 |
|
Messages: n/a
Hébergeur: |
mdh wrote:
> int main (int argc, const char * argv[]) > { > int i, j, k, l; > char arr [3][3] = {"One", "Two", "Lst"}; You do not reserve enough space for a null terminator. You will have arrays of char but not strings in your array. > char *p; > char **q; > > for ( i = 0; i < 3; i ++) > for ( j= 0; j < 3; j++) > { > p=&arr[i][j]; > printf( "%p\n", p); You should cast p to void*. > } > > 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 attempt to pass the non-strings when printf() is expecting strings. Your program now exhibits undefined behavior. Nothing else about it will tell you very much. Brian |
|
|
|
#24 |
|
Messages: n/a
Hébergeur: |
Richard Heathfield wrote:
> [sigh] > > Richard Heathfield said: > >> 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 ful 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"); > > Spot both... printf("i is now 0\n"); > >> } >> printf("Outside the loop, i is now %d\n"); > > ...mistakes. :-( printf("Outside the loop, i is now 0\n"); >> return 0; >> } >> >> and this is perfectly okay > > ...after fixing! > -- pete |
|
|
|
#25 |