[comp.lang.c] Teaching const

davidsen@steinmetz.steinmetz.ge.com (William E. Davidsen Jr) (04/02/88)

Could someone give me a good method to use when teaching students C,
such that they will be able to remember the syntax of
	pointer to {type} const
	- vs -
	const pointer to {type}

I have been getting a few questions every course, so far from people who
could live with "look at the standard there."
-- 
	bill davidsen		(wedu@ge-crd.arpa)
  {uunet | philabs | seismo}!steinmetz!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me

karl@haddock.ISC.COM (Karl Heuer) (04/02/88)

In article <10203@steinmetz.steinmetz.ge.com> davidsen@kbsvax.steinmetz.UUCP (William E. Davidsen Jr) writes:
>Could someone give me a good method to use when teaching students C,
>such that they will be able to remember the syntax of
>	pointer to {type} const
>	- vs -
>	const pointer to {type}

If you write "{type} const" rather than "const {type}", then "const" follows
pretty much the same rules as "*".  You can use whatever method you use to
distinguish "pointer to function" from "function returning pointer".

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

bs@alice.UUCP (04/03/88)

In article <3300@haddock.ISC.COM>, karl@haddock.UUCP writes:
> In article <10203@steinmetz.steinmetz.ge.com> davidsen@kbsvax.steinmetz.UUCP (William E. Davidsen Jr) writes:
> >Could someone give me a good method to use when teaching students C,
> >such that they will be able to remember the syntax of
> >	pointer to {type} const
> >	- vs -
> >	const pointer to {type}
> 
> If you write "{type} const" rather than "const {type}", then "const" follows
> pretty much the same rules as "*".  You can use whatever method you use to
> distinguish "pointer to function" from "function returning pointer".
> 
> Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

Try reading C declarations backwards (from right to left) they often
make sense that way. The ones that don't you might consider simplifying
using typedef.

s
i
l
l
y
f
o
o
d
f
o
r
m
a
i
l
e
r

daniels@teklds.TEK.COM (Scott Daniels) (04/06/88)

In article <10203@steinmetz.steinmetz.ge.com> davidsen@kbsvax.steinmetz.UUCP (William E. Davidsen Jr) writes:
>Could someone give me a good method to use when teaching students C,
>such that they will be able to remember the syntax of
>	pointer to {type} const
>	- vs -
>	const pointer to {type}

How about:

const int *****p;
Had better be a pointer to a constant thing (there is no way to identify the
pointer that you are talking about):	pointer to ... pointer to {type} const

"const int i;"  and  "int const j;" both MUST be talking about constant ints.
We can therefore infer that "const int *p;"  and  "int const *j;" both are also 
talking about constant ints (since placing "*ptr" where a variable occurs in a
declaration is how you build declarations of pointers).  Any other meaning 
assigned to "int const *p;" either violates the "throw in a *ptr" rule, or 
yields to the "reductio ad absurdum" above.

Finally, it seems there is only one place left to put the const when talking
about a constant pointer (except following the variable name, but that is 
really non-C-like), so all we have left is "int * const ptr;".

Hope this helps,
-Scott Daniels	daniels@teklds.UUCP

nw@amdahl.uts.amdahl.com (Neal Weidenhofer) (04/08/88)

In article <7788@alice.UUCP>, bs@alice.UUCP writes:
> Try reading C declarations backwards (from right to left) they often
> make sense that way.

The way to read them is from the "inside out".  Start with the identifier
being declared.  The closest type/"*"/"[...]"/"(...)" describes it.
The next closest describes that and so on.  Just remember that, in the
absence of parentheses, things on the right ("[...]" and "(...)") are "closer"
than things on the left ("*", etc.).  The only exception is storage class
which ALWAYS applies directly to the identifier being declared.

For example:
	int * const a;
decodes as:
	a is a constant,
	a is a constant pointer,
	a is a constant pointer to an int.
		(i.e., a cannot be modified but *a can.)
while:
	const int * a;
means:
	a is a pointer,
	a is a pointer to an int,
	a is a pointer to a constant int (or int constant.)
		(i.e., *a cannot be modified but a can.)
and a toughie:
	int (*a[])();
means:
	a is an array (remember right is "closer" than left)
	a is an array of pointers,
	a is an array of pointers to functions,
	a is an array of pointers to functions that return int.

Please, please, please, if you're teaching C, teach them to decode 
declarations this way.  They'll bless you for it.

>		       The ones that don't you might consider simplifying
> using typedef.

This is ALWAYS a good idea if declarations become unmanageable.

The opinions expressed above are mine (but I'm willing to share.)

			Regards,
				Neal Weidenhofer
And each one there              ...{hplabs|ihnp4|ames|decwrl}!amdahl!nw
     Had one thing shared...    Amdahl Corporation
And wept when it was all done   1250 E. Arques Ave. (M/S 316)
     For being done too soon.   P. O. Box 3470
				Sunnyvale, CA 94088-3470
				(408)737-5007

news@ism780c.UUCP (News system) (04/09/88)

In article <27071@amdahl.uts.amdahl.com> nw@amdahl.uts.amdahl.com (Neal Weidenhofer) writes:
>	int * const a;
>decodes as:
>	a is a constant,
>	a is a constant pointer,
>	a is a constant pointer to an int.
>		(i.e., a cannot be modified but *a can.)

Note that:
	 int a[1];
decodes as:
       a is a constant,
       a is a constant pointer,
       a is a constant pointer to an int.
	       (i.e., a cannot be modified but *a can.)

But there must (?) be some difference between the two.  How do you teach
this?

     Marv Rubinstein.

craig@srs.UUCP (Craig Schmackpfeffer) (04/11/88)

In article <9683@ism780c.UUCP> marv@ism780.UUCP (Marvin Rubenstein) writes:
>In article <27071@amdahl.uts.amdahl.com> nw@amdahl.uts.amdahl.com (Neal Weidenhofer) writes:
>>	int * const a;
>>decodes as:
>>	a is a constant,
>>	a is a constant pointer,
>>	a is a constant pointer to an int.
>>		(i.e., a cannot be modified but *a can.)
>
>Note that:
>	 int a[1];
>decodes as:
>       a is a constant,
>       a is a constant pointer,
>       a is a constant pointer to an int.
>	       (i.e., a cannot be modified but *a can.)
>
>But there must (?) be some difference between the two.  How do you teach
>this?
>

Of course there is a difference!  The "int * const a" declaration declares 
a pointer to an int.  The "int a[1]" declaration ALLOCATES space for an 
int and "a" itself is not a pointer, but actually the location of the array.

This confusion of pointers and arrays also occurs many times when people
declare an array in one file and then use an extern declaration which says
the variable is a pointer.

To teach this, it is probably easiest to draw the old memory 'boxes' and
show what is held where.  For instance, (sizeof(int)==2, sizeof(int*)==4):

int * const a;    ("a" is located @ 100 and contains address 200)
int b[1];         ("b" is located @ 104, "b"'s value is 104)

*a = *b;  (value taken from 104, put in address @100)

100                         200
+-+-+-+-+                   +-+-+
| 200   |                   |*a |
+-+-+-+-+                   +-+-+
104
+-+-+
| 0 |
+-+-+

Craig
-- 
Craig Schmackpfeffer  @ S.R. Systems
{allegra,rutgers,ames}!rochester!srs!craig

news@ism780c.UUCP (News system) (04/15/88)

In article <786@srs.UUCP> srs!craig@cs.rochester.edu (Craig Schmackpfeffer) writes:
>In article <9683@ism780c.UUCP> marv@ism780.UUCP (Marvin Rubenstein) writes:
>>In article <27071@amdahl.uts.amdahl.com> nw@amdahl.uts.amdahl.com (Neal Weidenhofer) writes:
>>>	int * const a;
>>>decodes as:
>>>	a is a constant,
>>>	a is a constant pointer,
>>>	a is a constant pointer to an int.
>>>		(i.e., a cannot be modified but *a can.)
>>
>>Note that:
>>	 int a[1];
>>decodes as:
>>       a is a constant,
>>       a is a constant pointer,
>>       a is a constant pointer to an int.
>>	       (i.e., a cannot be modified but *a can.)
>>
>>But there must (?) be some difference between the two.  How do you teach
>>this?
>>
>
>Of course there is a difference!  The "int * const a" declaration declares 
>a pointer to an int.  The "int a[1]" declaration ALLOCATES space for an 
>int and "a" itself is not a pointer, but actually the location of the array.
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
But "a" itself a pointer or else *a would not be allowed.  Nor would:

     char p = a;

I wrote the >> article.  I should have used a smiley.  I was discussing the
*teaching* problem.  Have you ever tried to explain to a novice why:

  char *p; and char p[1];

mean the same when p is a parameter, but do mean the same when p is not
a parameter.  Or why:

    extern  char p[];

makes sense, but

      char p[];

is an error.  If your students don't have any problems with this then they
are much smarter than mine (smiley used this time :-).

       Marv Rubinstein -- Interactive Systems

edk@gryphon.CTS.COM (Ed Kaulakis) (04/17/88)

> To teach this, it is probably easiest to draw the old memory 'boxes' and
> show what is held where.  For instance, (sizeof(int)==2, sizeof(int*)==4):
> 
> int * const a;    ("a" is located @ 100 and contains address 200)
> int b[1];         ("b" is located @ 104, "b"'s value is 104)
> 
> *a = *b;  (value taken from 104, put in address @100)
> 
> 100                         200
> +-+-+-+-+                   +-+-+
> | 200   |                   |*a |
> +-+-+-+-+                   +-+-+
> 104
> +-+-+
> | 0 |
> +-+-+
> 
> Craig
> -- 
> Craig Schmackpfeffer  @ S.R. Systems
> {allegra,rutgers,ames}!rochester!srs!craig

Uuuh... How did a get that 200 value? A const pointer declaration without
an initializer seems somehow odd to me...

franka@mmintl.UUCP (Frank Adams) (04/19/88)

In article <9719@ism780c.UUCP> marv@ism780.UUCP (Marvin Rubenstein) writes:
>In article <786@srs.UUCP> srs!craig@cs.rochester.edu (Craig Schmackpfeffer) writes:
>>The "int a[1]" declaration ALLOCATES space for an 
>>int and "a" itself is not a pointer.
>But "a" itself a pointer or else *a would not be allowed.

No, "a" itself is an array.  In the context of the "*" operator (and *most*
other contexts) it is *implicitly* converted to a pointer.  The same way in:

int x; long y;
return x+y;

x is implicitly converted to a long.
-- 

Frank Adams                           ihnp4!philabs!pwa-b!mmintl!franka
Ashton-Tate          52 Oakland Ave North         E. Hartford, CT 06108