[net.lang.c] Casting for a fish that never arrived

ded@aplvax.UUCP (Don E. Davis) (05/13/85)

Here is a problem which cropped up recently.  I had two two dimensional
arrays of pointers to character strings (as represented by Cwords and Pwords
below).  I wanted to point to either Cwords or Pwords
and be able to flip back and forth between two lists of strings
by indexing.  For example, if Words pointed to Cwords, then Words[0][0] would
point to "hello" and Words[1][0] would point to "goodbye".  If Words pointed
to Pwords the two choices would be "foo" and "foobar".  The only problem is,
I had a hard time getting this to work.  What I needed was something to put in
the place of CASTING EXPRESSION below.  Apparently there is no way to
perform this kind of cast (the array's second dimension is the problem). 

Of course, I could have used pointer arithmetic 
(e.g., printf("%s\n",*(Words+i*4+j)), but wound up using a typedef instead
since the WORD[][] format made my code a lot cleaner.

What do you say, gang, is there some CASTING EXPRESSION I could have used?

/*-----------------------------------------------------------------------*/

char *Cwords[2][4] = {
	{"hello","go","here","see"},
	{"goodbye","come","there","hear"} 
};
char *Pwords[2][4] = {
	{"foo","foo","foo","foo"},
	{"foobar","foobar","foobar","foobar"} 
};
char *Words;

main()
{
	int i,j;

	Words = (char *)Cwords;
	for (i=0; i<2; i++)
		for (j=0; j<2; j++)
			printf("%s\n",(CASTING EXPRESSION)Words[i][j]);
	Words = (char *)Pwords;
	for (i=0; i<2; i++)
		for (j=0; j<2; j++)
			printf("%s\n",(CASTING EXPRESSION)Words[i][j]);
}

/*-------------------------------------------------------------------------*/

Here is a solution which works.  I find it hard to believe this
can't be done without a typedef (or explicit pointer arithmetic), but
haven't been able to find a way yet.

typedef char *SYNTAX[4];
SYNTAX Cwords[2] = {
	{"hello","bye","go","come"},
	{"say","can","you","see"} 
};
SYNTAX Pwords[2] = {
	{"foo","foo","foo","foo"},
	{"foo","foo","foo","foo"} 
};
SYNTAX *Words;

main()
{
	int i,j;

	Words = (SYNTAX *)Cwords;
	for (i=0; i<2; i++)
		for (j=0; j<2; j++)
			printf("%s\n",Words[i][j]);
	Words = (SYNTAX *)Pwords;
	for (i=0; i<2; i++)
		for (j=0; j<2; j++)
			printf("%s\n",Words[i][j]);
}
-- 

					Don Davis
					JHU/APL
				...decvax!harpo!seismo!umcp-cs!aplvax!ded
				...rlgvax!cvl!umcp-cs!aplvax!ded

chris@umcp-cs.UUCP (Chris Torek) (05/14/85)

Your second example works because Words is (correctly) a pointer to
an array 4 of pointer to char (in cdecl syntax).  You don't even need
the casts in the assignment statements.

If you want to do it without typedefs, try

char *Cwords[2][4] = {{"1", "2", "3", "4"}, {"a", "b", "c", "d"}};
char *Pwords[2][4] = {{"w", "x", "y", "z"}, {"9", "8", "7", "6"}};
char *(*Words)[4];

main()
{
	register int i, j;

	Words = Cwords;
	for (i = 0; i < 2; i++)
		for (j = 0; j < 4; j++)
			printf("%s\n", Words[i][j]);
	Words = Pwords;
	for (i = 0; i < 2; i++)
		for (j = 0; j < 4; j++)
			printf("%s\n", Words[i][j]);
}
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (05/14/85)

> char *Cwords[2][4] = {
> 	{"hello","go","here","see"},
> 	{"goodbye","come","there","hear"} 
> };
> char *Pwords[2][4] = {
> 	{"foo","foo","foo","foo"},
> 	{"foobar","foobar","foobar","foobar"} 
> };
> char *Words;
char *(*Words)[4];	/* after all, you want Words[i][j] to be a (char *) */
> 
> main()
> {
> 	int i,j;
> 
> 	Words = (char *)Cwords;
	Words = Cwords;
> 	for (i=0; i<2; i++)
> 		for (j=0; j<2; j++)
> 			printf("%s\n",(CASTING EXPRESSION)Words[i][j]);
			printf("%s\n",Words[i][j]);
> 	Words = (char *)Pwords;
	Words = Pwords;
> 	for (i=0; i<2; i++)
> 		for (j=0; j<2; j++)
> 			printf("%s\n",(CASTING EXPRESSION)Words[i][j]);
			printf("%s\n",Words[i][j]);
> }

g-frank@gumby.UUCP (05/14/85)

> Here is a solution which works.  I find it hard to believe this
> can't be done without a typedef (or explicit pointer arithmetic), but
> haven't been able to find a way yet.
> 

See, Don?  C is so powerful, you can do anything in it!  You can't read it
or understand it, but who cares?


-- 
      Dan Frank

	  Q: What's the difference between an Apple MacIntosh
	     and an Etch-A-Sketch?

	  A: You don't have to shake the Mac to clear the screen.

john@x.UUCP (John Woods) (05/15/85)

> /*-----------------------------------------------------------------------*/
> 
> char *Cwords[2][4] = {
> 	{"hello","go","here","see"},
> 	{"goodbye","come","there","hear"} 
> };
> char *Pwords[2][4] = {
> 	{"foo","foo","foo","foo"},
> 	{"foobar","foobar","foobar","foobar"} 
> };
> char *Words;
> 
	Words = Cwords;
	dot dot dot
> 			printf("%s\n",(CASTING EXPRESSION)Words[i][j]);
> 
> Here is a solution which works.  I find it hard to believe this
> can't be done without a typedef (or explicit pointer arithmetic), but
> haven't been able to find a way yet.
> 
> typedef char *SYNTAX[4];
> SYNTAX Cwords[2] = {
> SYNTAX Pwords[2] = {
> SYNTAX *Words;

Well, I personally prefer the typedef style, but you didn't have to use
it.  The basic problem in the first example is that Words should not be
of type char *;  if Words were declared as a pointer to an array of four
char pointers, e.g.

char *(*Words)[4];

then you could use Words[i][k] without any casting required.
I *THINK* I have the parentheses in the right place, and some quick cc -S
experiments seem to make me believe I am right.  However, that is the very
reason that I prefer the typedef:  with typedef, you can express these
things quickly and easily.

Reminds me of the old puzzle about casting the number 7 into a pointer to
a function returning a pointer to a pointer to a function returning......

The answer took up about 70 characters on a single line, and looked like
the output from crypt(1).  The puzzle, of course, forbade the use of typedef,
which made it much too easy!-)
-- 
John Woods, Charles River Data Systems, Framingham MA, (617) 626-1101
...!decvax!frog!john, ...!mit-eddie!jfw, jfw%mit-ccc@MIT-XX.ARPA

"MU" said the Sacred Chao...