Arrays, Pointers, and sizeof(), oh my!

here's a little program (and it's output) that will hopefully make these topics make sense. :) The text and the output are given here, or you can download the source and run it yourself. :)

The OutPut

A table of comparisons - see source for explinations

		   hello	 hello[0]	charPointer	 someChar
		===========	===========	===========	===========
address of	-1073742596	-1073742596	-1073742600	-1073742605
contents of	-1073742596	   104		-1073742596	   113
pointing to	    104		 invalid	    104		 invalid
---------------------------------------------------------------------------
sizeof addresses    4		     4		     4		    4
sizeof contents	    12		     1		     4		    1
sizeof what's being pointed to
		    1		 invalid	     1		 invalid

The Source

/* pas.c 

   This file contains examples pertaining to pointers, arrays, and the
   sizeof operator in pure ansi c.  I may do it in c++ too, just to
   see if there is any difference (I'm pretty sure there's not, but
   you never know untill you try).  Also, I think it would be easier
   to read in c++.

   The file was written by the DreamingKat, and is licenced under the
   GNU Public Licence.  see http://www.gnu.org/ for details.

*/

#include 

int main()
{
  /* given these */
  char hello[] = "hello world";
  char *charPointer;
  char *pt2;
  char someChar = 'q';

  /* you can do these */
  pt2 = charPointer;
  charPointer = hello;

  /* but the following satements don't work. This is the first of
     three times when the name of an array does not behave like a
     pointer would.
  
     char hello2[] = hello; 
     char hello2[] = *charPointer;
     char hello2[] = 'a';

     so in summary you cannot assign:
     * an array to another array
     * a pointer to an array
     * a pointer to the type of thingie in the array

     Note: I do believe Julianna posted that you cannot assign
     _anything_ directly to the array name.   arrays and pointers 
     probably being the only thing anyone would ever _try_ to 
     assign to the array, wich we just demonstrated here.  */

  /* A note on strings: 

     The string 'contained in' or 'pointed to by' the charecter array
     we named 'hello' contains 11 characters ("hello world" and the
     NULL character).  

     In pure ansii C, putting the NULL character at the end of a
     character array makes it a string.  This is different in C++,
     where strings are their own type of object. 

  */

  printf( "A table of comparisons - see source for explinations\n\n");

  printf( "\t\t   hello\t hello[0]\tcharPointer\t someChar\n");
  printf( "\t\t===========\t===========\t===========\t===========\n");

  /* The address of a variable is the memory location at wich it's
     stored.  This is second of the 3 times when the name of an array
     doesn't act like a pointer.  Using the address of operator (&)
     tells us the address of the first element in the array.  This
     lets us think of the array as it's own data type.  I have
     absolutely no clue how or where the name of the array is stored
     in memory.  
*/
  printf( "address of\t%d\t%d\t%d\t%d\n", &hello, &hello[0], 
	  &charPointer, &someChar );

  /* this line tells us what value is actually stored in the
     variable. I have casted (forced) the value of the characters to
     be read as an integer to keep things uniform.  
  */
  printf( "contents of\t%d\t   %d\t\t%d\t   %d\n", 
	  hello, (int) hello[0], charPointer, (int) someChar );

  /* this line shows the value of the address being pointed at.
     Pointers are variables that store the address of another
     variable.  using the dereference operator (*) tells the compiler
     to look at the address stored in this variable.  Since hello[0]
     does not contain an address, the compiler gives us an error if we
     attempt to dereference it.  
  */
  printf( "pointing to\t    %d\t\t%s\t    %d\t\t%s\n", 
	  *hello, " invalid", *charPointer, " invalid" );

  printf( "------------------------------------------------------" );
  printf( "---------------------\n");

  /* the size of operator tells us how much memory is being used by
     the variable.  Can someone explain why all addresses are the same
     size on the same machine?
  */
  printf( "sizeof addresses    %d\t\t     %d\t\t     %d\t\t    %d\n", 
	  sizeof( &hello ), sizeof( &hello[0] ), 
	  sizeof( &charPointer), sizeof( &someChar ) );

  /* This is the third (and final) time that the name of an array does
     not behave exactly like a character pointer. the sizeof operator
     does exactly what it's supposed to do and tells us how much space
     is being reserved by the variable we give it. 
  */
  printf( "sizeof contents\t    %d\t\t     %d\t\t     %d\t\t    %d\n", 
	  sizeof( hello ), sizeof( hello[0] ), 
	  sizeof( charPointer ), sizeof( someChar ) );

  /* can't think of a comment for this one.  */
  printf( "sizeof what's being pointed to\n");
  printf( "\t\t    %d\t\t%s\t     %d\t\t%s\n", 
	  sizeof( *hello), " invalid", sizeof( *charPointer ), " invalid" );

  return 0;
}