There are 235 messages in this thread.
You are currently looking at messages 210 to 220.
j...@panix.com (John Francis) writes: > In article <2...@eircom.net>, > Ahem A Rivet's Shot <s...@eircom.net> wrote: >>On Sun, 07 Mar 2010 07:48:01 -0500 >>Greg Menke <g...@comcast.net> wrote: >> >>> >>> Ahem A Rivet's Shot <s...@eircom.net> writes: >>> > The C subscript operator does do nothing other than adding two >>> > numbers and dereferencing the result, that last action is rather >>> > important. The validity of constructs like 2[a] and *(2+a) make this >>> > clear - as does the equivalence of a and &(a[0]) or of *a and a[0] >>> > where a is a pointer. >>> >>> Yet when dereferencing arrays of rank >= 2, dimensions are automatically >>> incorporated into the effective address, so its not quite equivalent to >>> a simple addition of pointer and offset. >> >> There is a way to regard it as such - consider a[x][y] as being >>equivalent to *(a[x] + y) where we regard a[x] as devolving into a pointer >>to a row of the array. But yes multidimensional array support is a little >>more involved than single dimensional array support. It's still not a >>proper type though. > > That's all very well, but in fact no C implementation of which I am > aware uses dope vectors when allocating multidimensional arrays. (I > have come across the practice in other languages). In fact C has to > perform different calculations to evaluate the address of an element > a[i][j], depending on how a was defined (int a[4][5], or int** a). > The sizeof operator also knows something about array types. "Regard" is a key word there -- the syntax shown ought to work whether it's actually a dope vector (I assume you mean the same thing I learned about under the name "Iliffe vectors") or not. Haven't had a chance to try it.... -- As we enjoy great advantages from the inventions of others, we should be glad of an opportunity to serve others by any invention of ours; and this we should do freely and generously. (Benjamin Franklin)
Uwe Kloß wrote:
> Quadibloc schrieb:
>> On Mar 5, 12:44 pm, Joe Pfeiffer <pfeif...@cs.nmsu.edu> wrote:
>>> #include <stdio.h>
>>> int main()
>>> {
>>> int a[4];
>>>
>>> printf("a[2] at 0x%8x\n", &(a[2]));
>>> printf("2[a] at 0x%8x\n", &(2[a]));
>>> printf("(a+2) is 0x%8x\n", a+2);
>>> printf("(2+a) is 0x%8x\n", 2+a);
>>>
>>> }
>>>
>>> [pfeiffer@snowball ~/temp]# ./awry
>>> a[2] at 0xbfff97b8
>>> 2[a] at 0xbfff97b8
>>> (a+2) is 0xbfff97b8
>>> (2+a) is 0xbfff97b8
>> The 2[a] syntax actually *works* in C the way it was described? I am
>> astonished. I would expect it to yield the contents of the memory
>> location a+&2 assuming that &2 can be persuaded to yield up the
>> location where the value of the constant "2" is stored.
>
> You can think of the "a" in "a[4]" as a named numerical
(integer)
> constant (alias), giving the address of the memory block that was
> allocated by the definition.
>
> So there is no difference, between using that (named) constant or an
> explicit numerical constant.
>
> The only differences between:
> (1) int a[4];
> and:
> (2) int * a = malloc( 4 * sizeof(int));
> is the place where the memory is allocated and the value in (2) may be
> changed later. (And the amount of typing, ofcourse!)
>
> In both cases you can use "a[1]" or "*(a+1)" for access.
>
Yes, you *can* use "a[1]" or "*(a+1)" for access. And you can
think of "a" as a "named numerical (integer) constant", except
that array "a" also has an implied length that is used to scale
whatever integer is added to the address in "a".
--
+----------------------------------------+
| Charles and Francis Richmond |
| |
| plano dot net at aquaporin4 dot com |
+----------------------------------------+
______________________________Ahem A Rivet's Shot wrote: > On Sat, 6 Mar 2010 01:58:43 -0800 (PST) > Quadibloc <j...@ecn.ab.ca> wrote: > >> On Mar 5, 10:16 am, Ahem A Rivet's Shot <ste...@eircom.net> wrote: >> >>> No but x = *(y + 3) will store in x the contents of the memory >>> location at 3 + the value of y just as x = y[3] will and x = 3[y] will, >>> which is what I stated. You missed out the all important * and ()s. >> Intentionally. My point was that, while there is _some_ truth to the >> claim that C arrays tread rather lightly on the ground of hardware >> addressing, the claim that C doesn't have arrays at all, and the C >> array subscript operator does nothing at all but add two addresses >> together... is not *quite* true. > > The C subscript operator does do nothing other than adding two > numbers and dereferencing the result, that last action is rather important. > The validity of constructs like 2[a] and *(2+a) make this clear - as does > the equivalence of a and &(a[0]) or of *a and a[0] where a is a pointer. > > C does have good support for pointers and adding integers to > pointers and for declaring blocks of storage with an array like syntax. > ... but do *not* forget that when an integer is added to a pointer, that integer is "scaled" by the length associated with that pointer. So if "a" is a pointer to a four byte integer, then "a+1" actually adds *four* to the pointer. The integer "1" is scaled by the length of the object pointed to by "a". -- +----------------------------------------+ | Charles and Francis Richmond | | | | plano dot net at aquaporin4 dot com | +----------------------------------------+______________________________
Charles Richmond <f...@tx.rr.com> writes: > > ... but do *not* forget that when an integer is added to a pointer, > that integer is "scaled" by the length associated with that > pointer. So if "a" is a pointer to a four byte integer, then "a+1" > actually adds *four* to the pointer. The integer "1" is scaled by the > length of the object pointed to by "a". That fact took me several painful days to learn. I had (in a project I don't remember, for reasons I don't remember) used the + syntax dereferencing a buffer of integers, and had scaled it myself. Which meant, of course, that everything seemed fine for a ways into the buffer, then mysteriously segfaulted. Hmmm... I've got quite a few like that, with vividly remembered bugs in totally forgotten projects. -- As we enjoy great advantages from the inventions of others, we should be glad of an opportunity to serve others by any invention of ours; and this we should do freely and generously. (Benjamin Franklin)______________________________
On Sun, 07 Mar 2010 20:11:53 -0600 Charles Richmond <f...@tx.rr.com> wrote: > Ahem A Rivet's Shot wrote: > > On Sat, 6 Mar 2010 01:58:43 -0800 (PST) > > Quadibloc <j...@ecn.ab.ca> wrote: > > > >> On Mar 5, 10:16 am, Ahem A Rivet's Shot <ste...@eircom.net> wrote: > >> > >>> No but x = *(y + 3) will store in x the contents of the memory > >>> location at 3 + the value of y just as x = y[3] will and x = 3[y] > >>> will, which is what I stated. You missed out the all important * and > >>> ()s. > >> Intentionally. My point was that, while there is _some_ truth to the > >> claim that C arrays tread rather lightly on the ground of hardware > >> addressing, the claim that C doesn't have arrays at all, and the C > >> array subscript operator does nothing at all but add two addresses > >> together... is not *quite* true. > > > > The C subscript operator does do nothing other than adding two > > numbers and dereferencing the result, that last action is rather > > important. The validity of constructs like 2[a] and *(2+a) make this > > clear - as does the equivalence of a and &(a[0]) or of *a and a[0] > > where a is a pointer. > > > > C does have good support for pointers and adding integers to > > pointers and for declaring blocks of storage with an array like syntax. > > > > ... but do *not* forget that when an integer is added to a > pointer, that integer is "scaled" by the length associated with > that pointer. Yep *good* support for adding integers to pointers. -- Steve O'Hara-Smith | Directable Mirror Arrays C:>WIN | A better way to focus the sun The computer obeys and wins. | licences available see You lose and Bill collects. | http://www.sohara.org/
In article <2...@eircom.net>, Ahem A Rivet's Shot <s...@eircom.net> wrote: >On Sun, 7 Mar 2010 18:59:43 +0000 (UTC) >j...@panix.com (John Francis) wrote: > >> have come across the practice in other languages). In fact C has to >> perform different calculations to evaluate the address of an element >> a[i][j], depending on how a was defined (int a[4][5], or int** a). >> The sizeof operator also knows something about array types. > > If a is defined as int **a then a[i][j] is not valid at all. Rubbish. a[i][j] is a perfectly legal term in both cases I supplied, and has a well-defined way of calculating the address.
On Mon, 8 Mar 2010 07:45:53 +0000 (UTC) j...@panix.com (John Francis) wrote: > In article <2...@eircom.net>, > Ahem A Rivet's Shot <s...@eircom.net> wrote: > >On Sun, 7 Mar 2010 18:59:43 +0000 (UTC) > >j...@panix.com (John Francis) wrote: > > > >> have come across the practice in other languages). In fact C has to > >> perform different calculations to evaluate the address of an element > >> a[i][j], depending on how a was defined (int a[4][5], or int** a). > >> The sizeof operator also knows something about array types. > > > > If a is defined as int **a then a[i][j] is not valid at all. > > Rubbish. a[i][j] is a perfectly legal term in both cases I supplied, > and has a well-defined way of calculating the address. Er OK - you're right int **a is a pointer to a pointer to integers so the first offset works in terms of sizeof(int *) and the second in terms of sizeof(int). -- Steve O'Hara-Smith | Directable Mirror Arrays C:>WIN | A better way to focus the sun The computer obeys and wins. | licences available see You lose and Bill collects. | http://www.sohara.org/______________________________
In article <2...@eircom.net>, Ahem A Rivet's Shot <s...@eircom.net> wrote: >On Mon, 8 Mar 2010 07:45:53 +0000 (UTC) >j...@panix.com (John Francis) wrote: > >> In article <20100307214004.5b5fc8b4.s...@eircom.net>, >> Ahem A Rivet's Shot <s...@eircom.net> wrote: >> >On Sun, 7 Mar 2010 18:59:43 +0000 (UTC) >> >j...@panix.com (John Francis) wrote: >> > >> >> have come across the practice in other languages). In fact C has to >> >> perform different calculations to evaluate the address of an element >> >> a[i][j], depending on how a was defined (int a[4][5], or int** a). >> >> The sizeof operator also knows something about array types. >> > >> > If a is defined as int **a then a[i][j] is not valid at all. >> >> Rubbish. a[i][j] is a perfectly legal term in both cases I supplied, >> and has a well-defined way of calculating the address. > > Er OK - you're right int **a is a pointer to a pointer to integers >so the first offset works in terms of sizeof(int *) and the second in terms >of sizeof(int). True iff a is defined as int**. Note that sizeof(a[n]) returns different values for the two declarations; for the two-dimensional array the elements of a are not of type (int *); they are of an anonymous datatype (a vector of 5 ints).______________________________
Joe Pfeiffer wrote: > Charles Richmond <f...@tx.rr.com> writes: >> ... but do *not* forget that when an integer is added to a pointer, >> that integer is "scaled" by the length associated with that >> pointer. So if "a" is a pointer to a four byte integer, then "a+1" >> actually adds *four* to the pointer. The integer "1" is scaled by the >> length of the object pointed to by "a". > > That fact took me several painful days to learn. I had (in a project I > don't remember, for reasons I don't remember) used the + syntax > dereferencing a buffer of integers, and had scaled it myself. Which > meant, of course, that everything seemed fine for a ways into the > buffer, then mysteriously segfaulted. > > Hmmm... I've got quite a few like that, with vividly remembered bugs in > totally forgotten projects. This scaling of an integer when added to a pointer... is fundamental to the way C arrays and the array operator works. -- +----------------------------------------+ | Charles and Francis Richmond | | | | plano dot net at aquaporin4 dot com | +----------------------------------------+______________________________
Ahem A Rivet's Shot wrote: > On Sun, 7 Mar 2010 18:59:43 +0000 (UTC) > j...@panix.com (John Francis) wrote: > >> In article <2...@eircom.net>, >> Ahem A Rivet's Shot <s...@eircom.net> wrote: >>> On Sun, 07 Mar 2010 07:48:01 -0500 >>> Greg Menke <g...@comcast.net> wrote: >>> >>>> Ahem A Rivet's Shot <s...@eircom.net> writes: >>>>> The C subscript operator does do nothing other than adding >>>>> two numbers and dereferencing the result, that last action is rather >>>>> important. The validity of constructs like 2[a] and *(2+a) make this >>>>> clear - as does the equivalence of a and &(a[0]) or of *a and a[0] >>>>> where a is a pointer. >>>> Yet when dereferencing arrays of rank >= 2, dimensions are >>>> automatically incorporated into the effective address, so its not >>>> quite equivalent to a simple addition of pointer and offset. >>> There is a way to regard it as such - consider a[x][y] as being >>> equivalent to *(a[x] + y) where we regard a[x] as devolving into a >>> pointer to a row of the array. But yes multidimensional array support is >>> a little more involved than single dimensional array support. It's still >>> not a proper type though. >> That's all very well, but in fact no C implementation of which I am >> aware uses dope vectors when allocating multidimensional arrays. (I > > Indeed they don't - it is simply a matter of how you interpret the > partial construct a[x] when a is declared as a two dimensional array - one > way of interpreting it is as a pointer to an array row even though it is > not a valid construct on it's own. > > There is a clear extension of the one dimentsional case a declaration > int a[5] leaves future references to a as being equivalent to &(a[0]) so > it is reasonable to regard a declaration int a[4][5] as leaving future > references like a[i] as equivalent to &(a[i][0]). > One important point is: a two-dimensional array is a double indirection. The construct "x[5][8]" is equivalent to "*(*(x+5)+8)". Each of those two "*" does a dereference. >> have come across the practice in other languages). In fact C has to >> perform different calculations to evaluate the address of an element >> a[i][j], depending on how a was defined (int a[4][5], or int** a). >> The sizeof operator also knows something about array types. > > If a is defined as int **a then a[i][j] is not valid at all. > *Not* completely true. If a is a pointer to a pointer, it can be dereference with **a: x = **a; equivalently, this can be written: x = a[0][0]; since it is equivalent to: x = *(*(a+0)+0); -- +----------------------------------------+ | Charles and Francis Richmond | | | | plano dot net at aquaporin4 dot com | +----------------------------------------+______________________________