Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!uunet!mfci!karzes From: karzes@mfci.UUCP (Tom Karzes) Newsgroups: comp.lang.c Subject: Re: arrays of pointers - NOVICE QUESTION!( Be forwarned ! ) Keywords: pointers, arrays Message-ID: <883@m3.mfci.UUCP> Date: 6 Jun 89 04:07:48 GMT References: <10971@orstcs.CS.ORST.EDU> <17882@mimsy.UUCP> Sender: karzes@mfci.UUCP Reply-To: karzes@mfci.UUCP (Tom Karzes) Organization: Multiflow Computer Inc., Branford Ct. 06405 Lines: 147 I once wrote a simple test to exercise our C compiler. Actually I wrote a program which will create a program that tests all forms of simple declarators that can be constructed from indirection "*", function calls "()", and arrays "[N]" (with grouping parentheses "(...)" thrown in as needed to obtain the desired precedence), up to a desired level of declarator composition. Of course, it weeded out the illegal combinations (e.g., f()(), g[10](), h()[12], etc.). The underlying type is int, and the program declares and statically initializes a variable or function (determined by the declarator) of each form, then dynamically loads and prints their values. Most forms require auxiliary variables and/or functions. By convention, these auxiliary objects were given names which are the name of the primary object followed by an underscore and a number (the larger the number, the "further away" from the primary object). I've included a tiny excerpt from the 7-ply portion of the test. This excerpt defines and initializes x361, x362, x363, x364, x365, and x366, each of which uses auxialiary variables and/or functions. Also shown is the section of code from the main program which fully dereferences and prints the values of these same objects. Here is what the types are. Notice that each pointer is treated as pointing to a single object of the given type, although of course any pointer that points to a non-function can really point into an array of those objects. E.g., int (*x)[7] is treated as a pointer to an array of 7 ints (which is really what it is), although it could also be treated as a pointer into an array of arrays of 7 ints (e.g., into int y[123][7]). Note that this latter style is more common in C, particularly in the single subscript case (e.g., int *x pointing into int y[123], rather than int (*x)[123] pointing at int y[123]). ... int *(**(*x361())[4])[3] A function which returns a pointer to an array of 4 pointers to pointers to arrays of 3 pointers to ints. int *(**(*x362)[3][4])[3] A pointer to an array of 3 arrays of 4 pointers to pointers to arrays of 3 pointers to ints. int *(**x363[2][3][4])[3] An array of 2 arrays of 3 arrays of 4 arrays of pointers to pointers to arrays of 3 pointers to ints. int *(**(**x364)())[3] A pointer to a pointer to a function which returns a pointer to a pointer to an array of 3 pointers to ints. int *(**(*x365[2])())[3] An array of 2 pointers to functions which return pointers to pointers to arrays of 3 pointers to ints. int *(**(*x366())())[3] A function which returns a pointer to a function which returns a pointer to a pointer to an array of 3 pointers to ints. ... Here are the actual excerpts from the program: ... int x361_4 = 361; int *x361_3[3] = {0, &x361_4}; int *(*x361_2)[3] = (int *(*)[3]) /* & */ x361_3; int *(**x361_1[4])[3] = {0, 0, &x361_2}; int *(**(*x361())[4])[3] { return (int *(**(*)[4])[3]) /* & */ x361_1; } int x362_4 = 362; int *x362_3[3] = {0, &x362_4}; int *(*x362_2)[3] = (int *(*)[3]) /* & */ x362_3; int *(**x362_1[3][4])[3] = {{0}, {0, 0, &x362_2}}; int *(**(*x362)[3][4])[3] = (int *(**(*)[3][4])[3]) /* & */ x362_1; int x363_3 = 363; int *x363_2[3] = {0, &x363_3}; int *(*x363_1)[3] = (int *(*)[3]) /* & */ x363_2; int *(**x363[2][3][4])[3] = {{{0}}, {{0}, {0, 0, &x363_1}}}; int x364_5 = 364; int *x364_4[3] = {0, &x364_5}; int *(*x364_3)[3] = (int *(*)[3]) /* & */ x364_4; int *(**x364_2())[3] { return &x364_3; } int *(**(*x364_1)())[3] = /* & */ x364_2; int *(**(**x364)())[3] = &x364_1; int x365_4 = 365; int *x365_3[3] = {0, &x365_4}; int *(*x365_2)[3] = (int *(*)[3]) /* & */ x365_3; int *(**x365_1())[3] { return &x365_2; } int *(**(*x365[2])())[3] = {0, /* & */ x365_1}; int x366_4 = 366; int *x366_3[3] = {0, &x366_4}; int *(*x366_2)[3] = (int *(*)[3]) /* & */ x366_3; int *(**x366_1())[3] { return &x366_2; } int *(**(*x366())())[3] { return /* & */ x366_1; } ... int c1 = 1; int c2 = 2; main() { ... printf(" %3d", *(**(*x361())[c2])[c1]); printf(" %3d", *(**(*x362)[c1][c2])[c1]); printf(" %3d", *(**x363[c1][c1][c2])[c1]); printf(" %3d", *(**(**x364)())[c1]); printf(" %3d", *(**(*x365[c1])())[c1]); printf(" %3d", *(**(*x366())())[c1]); ... }