[comp.lang.c] More Pointers ...

karln@uunet.uu.net (03/14/91)

  Something bothers me about this example program. I works, but
I did not think the array passing and pointers would come out looking
like this. I've tried other ways of doing this, but this seems to be
the only way I can get it to work. Is there another way ???

[---------------------------Cut Here--------------------------]
#include <stdio.h>
main()
{
	int Board[3][3];

	init_board( Board );
	
	show_board ( Board );
}
init_board ( Board )
int (*Board)[3][3];
{
	int i, j;
	for ( i=0; i < 3; ++i ) {
		for ( j=0; j<3; ++j ) {
			(*Board)[i][j] = 0;
		}
	}
}
show_board( Board )
int (*Board)[3][3];
{
	int i;
	for ( i=0; i < 3; ++i ) {
		printf("%d %d %d\n", 
			(*Board)[i][0], 
			(*Board)[i][1], 
			(*Board)[i][2] );
	}
}
[---------------------------Cut Here--------------------------]

   Specificly the use of Board seems strange. Should I be using
int **Board somewhere? I did try using them at first, but things
wouldn't work right. Anybody care to make ANY sort of comment here?

	Karl Nicholas
	karln!karln@uunet.uu.net
	

tlglenn@cs.arizona.edu (Ted L. Glenn) (03/14/91)

In article <1991Mar13.161322.8214@uunet.uu.net>, karln@uunet.uu.net writes:
> 
>   Something bothers me about this example program. I works, but
> I did not think the array passing and pointers would come out looking
> like this. I've tried other ways of doing this, but this seems to be
> the only way I can get it to work. Is there another way ???
> 
             [ Program deleted ]
> 
>    Specificly the use of Board seems strange. Should I be using
> int **Board somewhere? I did try using them at first, but things
> wouldn't work right. Anybody care to make ANY sort of comment here?
> 
> 	Karl Nicholas
> 	karln!karln@uunet.uu.net
> 	

     When you pass an array to a function, you're passing a pointer to
the "top" of the array. In the function, you can make the array declaration
without the *. So, you have (Board)[3][3] instead of (*Board)[3][3]. The
program worked as is because you were consistent with the *.
     I mentioned that you were passing a pointer. That usually means that
the function's declaration should have a *. Arrays, however, work a little
differently. C's handling of arrays do not require the * in the function's
declaration. I can't recall right now exactly how C implement's this.....
     Anyways, your program will be fine if you replace all the (*Board)'s
with (Board).


-- 
        -Ted L. Glenn             "Don't worry, be happy!" <--Ack! Pffffhhht!
         tlglenn@cs.arizona.edu
         G19382105@ccit.arizona.edu    G19382105@ARIZRVAX.BITNET

torek@elf.ee.lbl.gov (Chris Torek) (03/15/91)

In article <1991Mar13.161322.8214@uunet.uu.net> karln!karln@uunet.uu.net
(Karl Nicholas) writes:
>	int Board[3][3];
>	init_board( Board );

>init_board ( Board )
>int (*Board)[3][3];

Someone else posted an incomplete followup that is likely to provoke all
sorts of noise.  The declaration in init_board here is incorrect; it
must be one of:

	int (*Board)[3];	/* I recommend this over all others. */

or:

	int Board[][3];

or:

	int Board[3][3];

You may get away with

	int Board[99][3];

or other bogus values in the first dimension, but I would advise against
it even if ANSI X3.159-1989 permits it (I do not know whether it does).

I recommend the first format because it is the least misleading.

See the Frequently Asked Questions for discussion as to why the first
declaration is correct.
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab EE div (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov

throopw@sheol.UUCP (Wayne Throop) (03/18/91)

> karln@uunet.uu.net
> Something bothers me about this example program. [...]
> main() {
>     int Board[3][3];
>     init_board( Board );
>     show_board ( Board );
> }
> init_board ( Board )
>     int (*Board)[3][3];
> { [...] (*Board)[i][j] = 0; [...] }
> show_board( Board )
>     int (*Board)[3][3];
> { [...] (*Board)[i][0], (*Board)[i][1], [...] }

Well, I'd tend to predeclare init_board and show_board, or place
main after their definitions.  But that's a minor nit.  More of a
problem are the things lint finds wrong here:

    t.c
    ==============
    Warning: (9)  main() returns random value to invocation environment
    ==============
    function argument ( number ) used inconsistently
        init_board( arg 1 )         t.c(12) :: t.c(6)
        show_board( arg 1 )         t.c(22) :: t.c(8)
    function returns value which is always ignored
        printf

In particular, passing something of type (int [N][M]) to something
of type (int (*)[N][M]) is a no-no (as is falling off the end
of an int-returning function).    

Most disressing to me is that gcc -Wall -ansi -pedantic didn't
diagnose this problem.   "Bzzzzzt!!  Thanks for playing our game, gcc..."

As to the specific example, I'd do it so:

    init_board ( Board )
        int Board[3][3];
    { [...] Board[i][j] = 0; [...] }
    show_board( Board )
        int Board[3][3];
    { [...] Board[i][0], Board[i][1], [...] }
    main() {
        int Board[3][3];
        init_board( Board );
        show_board ( Board );
    }

Further ideas: typedef-ing the board type, or the use of (int [][N])
formal argument types (equivalent to (int (*)[N]) formal argument types,
but ONLY as a formal argument type, NOT anywhere else!!!). 
--
Wayne Throop  ...!mcnc!dg-rtp!sheol!throopw