rogers@iris.ucdavis.edu (Brewski Rogers) (11/03/90)
given the array: float spam[4][4]; How do I declare a pointer to it? Is this possible? -bruce
poser@csli.Stanford.EDU (Bill Poser) (11/03/90)
In article <9197@aggie.ucdavis.edu> rogers@iris.ucdavis.edu (Brewski Rogers) writes: >given the array: > > float spam[4][4]; > >How do I declare a pointer to it? Is this possible? float (*spamp) [4][4]; declares spamp to be a pointer to a 4x4 array of floats.
chris@mimsy.umd.edu (Chris Torek) (11/04/90)
>In article <9197@aggie.ucdavis.edu> rogers@iris.ucdavis.edu >(Brewski Rogers) asks: >> float spam[4][4]; >>How do I declare a pointer to it? Is this possible? In article <16189@csli.Stanford.EDU> poser@csli.Stanford.EDU (Bill Poser) answers: > float (*spamp) [4][4]; >declares spamp to be a pointer to a 4x4 array of floats. Correct, but chances are that this is not what is desired anyway. Most likely Mr. Rogers (sorry, I just *had* to write it that way :-) ) wants either `float (*p)[4];' or `float *p;'. Consider, e.g., the array int x[10]; This declares `x' as an object of type `array 10 of int'. Objects of type `array N of T', when placed in value contexts (most C contexts are value contexts), `decay' into values of type `pointer to T' which point to the first element of that array, i.e., the element whose index is 0. So to make use of `x' one would not write int (*ap)[10] = &x; /* NB: legal only in ANSI C, not K&R-1 */ but rather int *ip = x; /* or `= &x[0]' */ After all, the only thing you can do with `ap' that you cannot do with `ip' is index (or point) off into the n'th array-10-of-int objects, and there is no other such object. There is only `ap[0]'. The same holds for a `float spam[4][4];': this is an object of type array N=4 of T=(array 4 of float), so you want a pointer to T, or a pointer to `array 4 of float': float (*p)[4] = spam; /* or `= &spam[0]' */ and now you can index p to get objects 0, 1, 2, and 3: float *f = p[1]; /* or &p[1][0] */ p[3][2] += 3.0; /* bump element 2 of array number 3 */ -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris
gwyn@smoke.brl.mil (Doug Gwyn) (11/07/90)
In article <9197@aggie.ucdavis.edu> rogers@iris.ucdavis.edu (Brewski Rogers) writes: >given the array: > float spam[4][4]; >How do I declare a pointer to it? Is this possible? You don't declare a pointer to spam; however, you might declare a pointer to an array having the same type as spam and initialize it to point to spam. This may not work in pre-ANSI C compilers that don't allow you to take the address of an array, in which case you can use just spam or spam[0] and cast it to the desired type. float (*spamp)[4][4] = &spam; /* ANSI */ float (*spamq)[4][4] = ((*)[4][4])spam; /* others */
avery@netcom.UUCP (Avery Colter) (11/11/90)
Well, any array, when referred to by name only without subscripts, translates into a pointer to the lowest element of the array, i.e. the location of spam[0][0]. However, at least on my machine, pointers don't take kindly to more than one dimension of indexing. So I resorted to making a separate array of pointers, and setting each of the elements of this array of pointers to match the addresses of each of the subarrays of the original. Kinda like: int spam [10][10]; int *pointer[10]; int index; for (index=0;index<10;++index) pointer[index]=spam[index]; -- Avery Ray Colter {apple|claris}!netcom!avery {decwrl|mips|sgi}!btr!elfcat (415) 839-4567 "Fat and steel: two mortal enemies locked in deadly combat." - "The Bending of the Bars", A. R. Colter
gwyn@smoke.brl.mil (Doug Gwyn) (11/11/90)
In article <16580@netcom.UUCP> avery@netcom.UUCP (Avery Colter) writes: >However, at least on my machine, pointers don't take kindly to more >than one dimension of indexing. But pointers to pointers do, e.g. int **spampp;
chris@mimsy.umd.edu (Chris Torek) (11/12/90)
In article <16580@netcom.UUCP> avery@netcom.UUCP (Avery Colter) writes: >Well, any array, when referred to by name only without subscripts, >translates into a pointer to the lowest element of the array, In value contexts, yes; >i.e. the location of spam[0][0]. no. The declaration was `float spam[M][N];' for some constants M and N. The type of the object `spam' is thus `array M of array N of float'. In a value context, this becomes a pointer to the first element of `the' array. Which array?---we have two `array of's above. The answer is that it becomes a `pointer to array N of float'. This value is not an <object, array N of T> and therefore does NOT undergo a second conversion. The result is a pointer to first of the sub-arrays that make up the array `spam'. As I wrote before, this is float (*p)[N] = spam; >However, at least on my machine, pointers don't take kindly to more >than one dimension of indexing. The result of `indexing' (which is in C a sham: e1[e2] does not really `index' e1 `by' e2; instead, it adds e1 and e2 and indirects through the result) a `pointer to T' is, if not an error, an object (lvalue) of type T. If each pointer points to one or more `int's, then ptr[value] is a single int (or an error). In this case, p points to one or more---in fact, it points to exactly M ---`array N of float's, so p[value] is an object of type `array N of float'. Since this *is* an array object, it goes through another of those `array to pointer' conversions whenever it appears in a value context, so p[v1][v2] is entirely legal and means to take the v1'th `array N of float' at which p currently points, turn that object into the address of the first of the N floats in that array, then take the v2'th float at which the resulting pointer points: 0 1 2 ... N-1 +---+ +------------------+ | p |---------->| array N of float | p[0] +---+ +------------------+ | array N of float | p[1] +------------------+ | . | | . | ... | . | +------------------+ | array N of float | p[M-1] +------------------+ `p' points directly *to* one `array N of float' (p[0]), but p points *at* a whole passel of `array N of float's (p[0] through p[M-1]). An `array N of float' is slippery, though, and when you try to grab the whole thing with p[0]: +---+ +------------------+ | p |---------->| array N of float | p[0] +---+ +------------------+ you have to loosen your hold and you end up with a pointer to the first one: $ p[0] in value context | v +---+ +---+---+...+---+--+ | p |---------->| array N of float | p[0] +---+ +------------------+ `$' is an intermediate value and is not (necessarily) actually stored in memory anywhere in the computer (hence no box). It points to a single float (here p[0][0]) but it points `at' N floats (p[0][0] through p[0][N-1]). This means you can fetch `$[0]' (so to speak) to get p[0][0], or `$[4]' to get p[0][4], and so on. Of course `$' is not a legal character in C, except inside string and character constants and comments. (In the picture above, p points *to* the entire `array N of float', but `$'---p[0] taken as a value---points *to* only one float, hence the extra `+' marks along the top.) >So I resorted to making a separate array of pointers, and setting >each of the elements of this array of pointers to match the addresses >of each of the subarrays of the original. [edited to be `array M of array N of float', etc] >float spam[M][N]; >float *pointer[M]; >int index; >for (index = 0 ;index < M; ++index) > pointer[index] = spam[index]; This is entirely legal, and amounts to copying each `$' into an actual variable (pointer[index]) by placing each spam[index] computation in a value context (the right hand side of the last `='). Each spam[index] is an `object, array N of float' and therefore is transformed into a `value, pointer to float', which is proper to store in pointer[index]. The result is an array M of pointers, each pointing *to* one float but `at' N floats: 0 ... N-1 +--------------+ +---+---+---+ | pointer[0] |------->| |...| | spam[0] +--------------+ +---+---+---+ | pointer[1] |------->| |...| | spam[1] +--------------+ +---+---+---+ | . | | . | | . | | . | | . |...| . | ... | . | | . | | . | +--------------+ +---+---+---+ | pointer[M-1] |------->| |...| | spam[M-1] +--------------+ +---+---+---+ Each pointer[i] points *to* the 0'th spam[i] (hence the extra `|'s making each spam[x][y] a separate box, vs the diagram for `p' in which each spam[x] was a single continuous box) but `at' the entire `spam[i][0] through spam[i][N-1]'. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris