in C is the address of something.
It is a rare case indeed when we care what
the specific address itself is,
but pointers are a quite common way to get at
the contents of something.
The unary operator `&' is used to produce the address of
an object, if it has one. Thus
We can't do much with it except print it or pass it
to some other routine, because we haven't given
the right kind of declaration.
to an integer, we're in good shape:
means to use the value in
as an address, i.e., as a pointer.
The effect is that we get back the contents of
albeit rather indirectly.
(It's always the case that
The most frequent use of pointers in C is for walking
efficiently along arrays.
in the implementation of an array,
represents the address of the zeroth element of the array,
so you can't use it on the left side of an expression.
(You can't change the address of something by assigning to it.)
is of type pointer to character
(although it doesn't yet point anywhere).
this is legal and consistent.
that computes how long a character array is.
Remember that by convention all character arrays are
(And if they aren't, this program will blow up inevitably.)
for( n=0; s[n] != '\\0'; )
Rewriting with pointers gives
for( n=0; \**s != '\\0'; s\*+ )
You can now see why we have to say what kind of thing
if we're to increment it with
we have to increment it by the right amount.
The pointer version is more efficient
(this is almost always true)
for( n=0; \**s\*+ != '\\0'; n\*+ );
increments the pointer so we'll get the next character
As you can see, as we make things more efficient,
we also make them less clear.
that you have to know it.
that copies a character array
while(\**t\*+ = \**s\*+);
We have omitted the test against `\\0',
because `\\0' is identically zero;
you will often see the code this way.
have a space after the `=':
to a function, and there only,
are equivalent _ a pointer to a type,
or an array of unspecified size of that type, are the same thing.
If this all seems mysterious, copy these forms until they become second nature.
You don't often need anything more complicated.
Look back at the function
We passed it two string names as arguments, then proceeded
to clobber both of them by incrementation.
So how come we don't lose the original strings
in the function that called
C is a ``call by value'' language:
when you make a function call like
this isn't a problem, because
and you're not trying to change it,
And it's convenient not to have to worry about
making temporary copies of the input arguments.
you do want to change it?
and then use it as a pointer.
Thus for example, to interchange two integers, we must write
we have to pass the addresses of the variables:
Multiple Levels of Pointers; Program Arguments
When a C program is called,
the arguments on the command line are made available
to the main program as an argument count
and an array of character strings
containing the arguments.
Manipulating these arguments is one of the most common uses of
multiple levels of pointers
(``pointer to pointer to ...'').
is the command name itself.
Here is a program that simply echoes its arguments.
for( i=1; i < argc; i\*+ )
is called with two arguments,
the argument count and the array of arguments.
is a pointer to an array,
whose individual elements are pointers to arrays of characters.
The zeroth argument is the name of the command itself,
with the first argument, until we've printed them all.
is a character array, so we use a
You will sometimes see the declaration of
because both dimensions are variable and
there would be no way to figure
out how big the array is.
Here's a bigger example using
A common convention in C programs is that
if the first argument is `\(mi',
it indicates a flag of some sort.
For example, suppose we want a program to be callable as
prog -abc arg1 arg2 \*.\*.\*.
where the `\(mi' argument is optional;
if it is present, it may be followed by any combination of
aflag = bflag = cflag = 0;
if( argc > 1 && argv[1][0] \*= '-' ) {
for( i=1; (c=argv[1][i]) != '\\0'; i\*+ )
There are several things worth noticing about this code.
First, there is a real need for the left-to-right evaluation
unless we know it's there.
let us march along the argument list by one position,
so we can skip over the flag argument as if it had never existed _
the rest of the program is independent of
whether or not there was a flag argument.
is a pointer which can be incremented.
The Switch Statement; Break; Continue
can be used to replace the multi-way test
we used in the last example.
When the tests are like this:
if( c \*= 'a' ) \*.\*.\*.
else if( c \*= 'b' ) \*.\*.\*.
else if( c \*= 'c' ) \*.\*.\*.
testing a value against a series of
statement is often clearer and usually gives better code.
statements label the various actions we want;
gets done if none of the other cases are satisfied.
and none of the cases match,
you just fall out the bottom.)
statement in this example is new.
the cases are just labels,
and after you do one of them,
to the next unless you take some explicit action to escape.
This is a mixed blessing.
you can have multiple cases on a single statement;
we might want to allow both upper and lower case letters in our flag field,
case 'a': case 'A': \*.\*.\*.
case 'b': case 'B': \*.\*.\*.
But what if we just want to get out
statement lets us exit without either
/\** the break statements get us here directly \**/
it causes an immediate exit from the loop.
it causes the next iteration of the loop to be started.
This means it goes to the increment part of the
in our example to get on with the next iteration
but it seems clearer to use