Lecture #24: Arrays 2
December
1, 1999
Bob
Pitha
our story so far…
• On
Monday we began talking about arrays
• An
array is a group of one or more adjacent things in memory
– they are all
the same type
• any of the 7
basic data types
• pointers
• arrays (we
won’t tackle this yet)
• other things
we haven’t learned about
array recap: array declarations
• We
have to declare an array variable just like any other variable
type
name[size];
type
name[size] = { initializer
list
};
type
name[] = { initializer list };
– common
elements:
• type: the
data type of each element of the array
• name: the
name of the variable we are declaring
• size: either
explicit or implicit, it’s the number of elements
array recap: array definitions
• As
with other declarations, a defining declaration will reserve storage
– this will
allocate an adjacent block of memory large enough to store all elements of the
array
– all of the
declarations we’ve seen (and probably will see) have been definitions
array declaration examples
• Some
examples of array declarations
double coordinate[3];
• this defines
an array named coordinate
– each element
is a double
– it reserves
space for 3 elements
int frequency
[26];
• this defines
an array named frequency
– each element
is an int
– it reserves
space for 26 elements
int *pointer
[6];
• this defines
an array named pointer
– each element
is a pointer to an int
– it reserves
space for 6 elements
array recap: using arrays
• We
can only do two things with arrays:
– refer to an
element of the array
• we can then
do lots of different things with that element
– get a
pointer to the first element of the array
array recap: subscript expression
• We
refer to an array element using a subscript expression
– array_name[index]
– details
• the index is
any expression with integral value
• the index
value selects a specific element of the array
– the first
element is index 0
• a subscript
expression is usually an lvalue
– which means
we can assign a value to an array element
array recap: subscript expression
• Given
the following declaration:
int a[8];

– it’s not
illegal to use an index off the end of the array
• but it may
have undefined results, since it will mean you’re referring to memory that
isn’t part of the array
• we’ll see
why this is legal a little later…
subscript expression examples
• So
remember our example declarations:
double coor[3];
int frequency
[26];
int *pointer
[6];
– the
following code is legal:
printf (“(%f,
%f, %f)\n”, coor[0], coor[1], coor[2]);
for (i=0;
i<26; ++i)
frequency[i] = 0;
pointer[3] =
&frequency[12];
array recap: array name as pointer
• In
many contexts, using the array name by itself gets you a pointer to the first
element
int frequency
[26];
int *pointer
[6];
pointer[3] =
&frequency[12];
pointer[2] =
frequency;
so now back to our example
![Text Box: #include <stdio.h>
int InputScores (double *);
void PrintStats (double *, int);
int main (void)
{
double scores[250];
int numScores;
printf (“Scores: a program to compute grade statistics.\n”);
printf (“Enter all scores, finish with –1:\n\n”);
numScores = InputScores (scores);
PrintStats (scores, numScores);
}](./Lecture24_files/image003.gif)
•
Note that we call the two functions with the argument scores
passing arrays
• It
is perfectly legal to put an array name into a list of arguments to a function
– this is a
value context
– therefore,
the array name expression becomes a pointer to the first element of the array
– note that
the prototype for InputScores looks like this:

• So
when we pass an array into a function, we’re really just passing a pointer to
the beginning of the array
passing arrays
• Note
the “difference” between passing a scalar variable and an array
– up to now,
when we put a variable name in an argument list, its value was passed to the
function
– with an
array, what gets passed is a pointer
• There’s
no discrepancy here, really…
– remember The
Array Rule:
•
In a value context, the name of an array of
type “array N of T” becomes a “pointer to T”
– so in a
manner of speaking, the “value” of the variable is the pointer to the first
array element.
functions with array arguments
• We’ve
talked about passing arrays into functions, but what does it look like from the
function side?
– The function
gets a pointer as an argument.
• but we only
know how to dereference a pointer to a single value
• how does the
function access the whole array?
arrays and pointers
• Here’s
where we start getting into the real overlap between arrays and pointers
– remember I
told you The Rule:
•
In a value context, the name of an array of
type “array N of T” becomes a “pointer to T”
– and remember
the syntax of the subscript expression
array_name [index]
– in fact,
there’s nothing special about this use of the array name – it’s simply a value
context too
say what?
• A
subscript expression is really a pointer expression, not an array expression
– and to
understand this, we have to delve into pointer arithmetic
pointers again
• So
far, we have discussed three operators that deal with pointers:
– the
“address-of” operator: &
– the
dereference operator: *
– the
assignment operator
• There
are other pointer operators you can use, including:
– addition: +
– subtraction:
-
pointer arithmetic
• The
familiar arithmetic operators + and – can also be used with pointers
– but there
are rules…
– I said that
computer addresses are just numbers, but pointer arithmetic isn’t quite as
simple as that…
pointer addition
• One
of the operands of + can be a pointer
– but then the
other operand must be an integer
– and it
doesn’t just add the integer to the address
• instead, it
adds the integer times the size of the thing the pointer points to
– so given the
declarations:
int i;
int *p =
&i;

the logic of pointer addition
• Why
do things work this way?
– remember,
things are different sizes on different computers
• so we can’t
build into our programs an assumption that, say, ints are always 4 bytes long
– plus,
there’s array indexing…
• you can step
through an array by simply incrementing a pointer
• adding 1 to
a pointer gets you to the next “thing” in the array
– whether it’s
actually pointing to an array or not
pointer addition and array indexing
• So
given an array declared like this:
– int a[8];
– remember
that using the array name by itself just gets a pointer to the first element
– that means:
• a is equivalent
to &a[0]
• *a is equivalent
to a[0]
– now if we
mix in pointer addition:
• a+1 is equivalent
to &a[1]
• *(a+1) is
equivalent to a[1]
pointer addition and array indexing
• In
fact, the C language defines the subscript expression in terms of pointer
addition
– that is, the
expression a[b] is identical to *(a+b)
• So
back to the original reason we brought up pointer addition:
– you can use
an array name or a pointer in a subscript expression, because to C it’s the
same thing
• it all
becomes pointer arithmetic
some more details of pointer addition
• If
one operand of + is a pointer, the other operand must be an integer type
– you cannot
add two pointers
– the data
type of the expression is the same type as the pointer
• It
doesn’t matter what order you add the operands
– p+i is the same
as i+p
back to that locker analogy
• Remember
I’ve said that pointers are like locker numbers
– pointer
addition, then, is like finding a locker relative to another one
• “5 lockers
to the right of #371”
– and as with
pointer addition, it doesn’t make sense to add two locker numbers together