- A type qualifier is something like static or register
which goes before a variable declaration and modifies how the variable
can be used. const is another type qualifier and it declares
that the variable never changes:
const double pi = 3.14159;
const variables are superior to #define
constants in that they are type checked and can have their address taken
(&pi is valid but &M_PI is not), but inferior in that
they can not be used to specify the size of an array.
- One valuable place to put const's is in function argument
lists:
int lessThan(const double a, const double b)
{
return ( a < b );
}
- Using const's in function argument lists becomes even more
useful (but also slightly confusing) when coupled with pointers. Simply
put, const int *ip DOES NOT MEAN that ip is constant,
but rather that *ip or what ip points to is constant.
To say *ip is constant, use int * const ip. Here are
some examples:
int strcmp(const char *s1, const char *s2 );
/* strcmp doesn't change the strings, but
it might change s1 and s2 internally. */
int sprintf( char *s, const char *format, ... );
/* sprintf definitely changes s, but leaves
the format string alone. */
/* strlen should never change the string it is passed,
and this particular version never changes the pointer
s internally */
int strlen( const char * const s )
{
char *cp;
cp = s;
while ( *cp++ != '\0' );
return( s - cp );
}
/* *ip is changed, but ip isn't */
void addfive( int * const ip )
{
*ip = *ip + 5;
}
- The volatile type qualifier works in the same way as the
const type qualifier, but it tells the compiler that the variable
could change at any time for any reason. The most common use is to get
the compiler to turn off all optimizations related to that variable. For
example, if I am writing a program to read in data from an I/O port I might
write
volatile char *ioport1;
ioport1 = (char *) 0xFF3E; /* casting an integer to a char *
is machine specific, but so is
this io port address! */
while( *ioport == 0 ); /* wait for data. If I didn't declare
*ioport to be volatile, my compiler
might remove this statement! */