Copyright 1998-2014 Curt Hill Arrays in C/C++ What? Why? How?
Jan 18, 2016
Copyright 1998-2014 Curt Hill
Arrays in C/C++
What? Why? How?
Copyright 1998-2014 Curt Hill
Motivating Example• Suppose we have an application
that collects votes• We have one office with four
candidates• We want to read in a number and
then increment the vote count for that candidate
Copyright 1998-2014 Curt Hill
Use the following first cut
• Set variables to zero• While input do
– Read in a variable– Test value– If in 0..3– Then increment appropriate vote
total– Else reject
• When done show results
Copyright 1998-2014 Curt Hill
Voting Machineint count,v0=0,v1=0,v2=0,v3=0, vote;while(cin>>vote) { switch (vote) {
case 0: v0++; break;
case 1: v1++; break;
case 2: v2++; break;
case 3: v3++; break;
default: cout << "Invalid vote\n";}}
cout << "Totals " << v0 << v1 << v2 << v3 << "\n";
Copyright 1998-2014 Curt Hill
Explanation
• cin >> vote also returns a value that can drive the if
• If the cin fails to find an int, because it:– hit end of file– hit something that did not conform
to the specifications of an integer
• Then the while ends– Classic C way of doing two things in
one construct
Copyright 1998-2014 Curt Hill
What is wrong with this?• This will work fine for 4 candidates• What about 20?• What is the significant difference
between v0 and v1?• The candidate to which the count
applied• They all have the same type and
the same meaning
Copyright 1998-2014 Curt Hill
Array Solution int v[4], vote; for (int i=0;i<4;i++)
v[i]=0; while(cin>>vote) {
if (vote<0 || vote > 3) cout << "Invalid vote\n";else v[vote]++;}
for (i=0;i<4;i++)cout << "Candidate " << i
<< " received "<< v[i] << " votes\n";
Copyright 1998-2014 Curt Hill
What is an array?• Multiple occurrences of values of
one type– One name many values
• Item is selected at run time by an integer index
• The mark of arrays is a pair of square brackets: [ ]
• Arrays are not a type in themselves– Rather an array name is a constant
pointer
Copyright 1998-2014 Curt Hill
Why do we need arrays?
• We often need to select a value by an index rather than just name
• Awkward to have 20 names to hold the vote totals of 20 candidates– More awkward to use
• Instead we find one name and use an integer subscript to choose which of the twenty we want
Copyright 1998-2014 Curt Hill
Arrays• One name, many values• Arrays elements demonstrate
identical form and function• The form is that each element has
exactly the same type– Polymorphism can come into play
here, but not considered until later
• The function is that they are there for the same purpose
Copyright 1998-2014 Curt Hill
Voting Machine Again• The form and function each v
variable was the same• Each was an integer (identical
form)• Each recorded votes cast for one
candidate (identical function or purpose)
• The only thing that distinguished the values is the numeric value of each candidate
Copyright 1998-2014 Curt Hill
Explanations still needed• Declaration
– Marked by the []
• Access and reference– Indexing or subscripting– In languages other than COBOL index
and subscript are synonyms
• Answers to these questions:– What can we do to an array element?– What can we do to the whole array?
Copyright 1998-2014 Curt Hill
Array declaration• General form:
type name [constant];• Example:
– int a[5], b, c[20];– float d[50];
• Size must be enclosed in brackets• Size must be a constant:
– Literal– Defined– constant integer
Copyright 1998-2014 Curt Hill
More on declaration• Brackets are attached to variable
name• Example:int a[5], b, c[4];
• The variables a and c are arrays, but b is a simple integer
• Bracketed expression does two things:– Declares this to be an array– Specifies the size of the array
Copyright 1998-2014 Curt Hill
Index Range• The index or subscript range is
always zero to one less than the declared size
• Example:– int a[4];
• There are four elements:• a[0], a[1], a[2], a[3]
Copyright 1998-2014 Curt Hill
Initialization• Generally done with a for loop:for(int i = 0;i<5;i++) a[i] = 0;
• The [i] chooses which integer to set to zero
• This is an example of a subscript or index
• Starts at zero
Copyright 1998-2014 Curt Hill
Alternate Initialization• Initialization may be done with a
brace list at declaration time– Several variations to this
• First example – int b[4] = {0,-1,-2,-3};– Only general form of whole array
assignment
• Leave out size:– int b[] = {0,-1,-2,-3};– Counts list for size– This is same as above
Copyright 1998-2014 Curt Hill
This allows problems• What if the size of the brace list does
not match the size of the array?• Two possibilities:• Too long:
– int a[3] = {0,1,2,3}– This is a syntax error - what to do with
3?• Too short:
– int a[10] = {0,1,2,3}– First four items are initialized and rest
are not– No syntax error, no warning
Copyright 1998-2014 Curt Hill
Initialization Again• What can be in the braces?• Most anything that may be on right
hand side of an assignment operator– Constants– Variables– Expressions– Function calls– Constructors for classes
Copyright 1998-2014 Curt Hill
Constant Array Bounds• We use defined constants to
parameterize arrays and the for loops that process them
• Thus:#define MAX 10const int SMax 50…int counts[MAX], states[SMax];…for(int i = 0;i<MAX;i++) {…}
• Easy to change the constant if we need a different size
Copyright 1998-2014 Curt Hill
Brackets [ ]• We can think of brackets as
an address modification operator in code and a length modification in declarations
• As such they have very high precedence
• They can only be applied to pointer like operands
• An array name is a constant pointer
Copyright 1998-2014 Curt Hill
Alternate Initialization Again• No parameterized way to initialize
with braces• FORTRAN allows an initializer:
10*0– which generates 10 zeros
• Nothing like that in C/C++• Thus arrays that have ranges that
may change are usually initialized with a for
Copyright 1998-2014 Curt Hill
Subscripting• Using an index obtains an element
– a[2] = 5;– a[k] = a[j+2]-2;
• Anywhere an int can be used a[k] can be used– Even nested
a[a[k+1]] = a[a[a[j]+2]]-2;
• First element has index zero• Last element has subscript array
size minus one
Copyright 1998-2014 Curt Hill
A Subscript• Chooses the element of the array• The item may be a
– integral constant– integral variable– integral expression
• No doubles or float subscripts– There is no element between [2] and [3]– They will be truncated to an integer
• Must be in the correct range– 0 to length of array-1
Copyright 1998-2014 Curt Hill
Errors• What if the value presented for a
subscript is not valid?– It is not in proper range
• Oops - by default there is no checking– In many cases checking is not possible
• Presumably if you go after the array element that is larger than the bounds then you damage nearby variables
• This is not necessarily caught at compile time or runtime
Copyright 1998-2014 Curt Hill
Subscript error example• Suppose:
int first, v[10], last;• Thus v[-1] or v[10] will not cause a
compile error• However first and last will be accessed
rather than v• The compiler is under no obligation to
lay out the variables in any way other than for its own convenience– Thus v[10] could be the same as first or last
– we cannot tell which
• At runtime the OS may intervene if the subscript is wildly out of bounds
Copyright 1998-2014 Curt Hill
Discussion• Since an array is one name with
many values, an array element has a two piece name– The array name and the subscript
• We may assign to this name or use in an expression
• Processing an array sequentially is almost always done with a for statement
Copyright 1998-2014 Curt Hill
Address Modification• The address calculation needs
some explanation• Consider the following
declarationItem var[MAX];
• Suppose the following expression:var[ndx]
• How does the compiler compute the needed address?
• address(var) + sizeof(Item) * ndx
Copyright 1998-2014 Curt Hill
What was that again?• address(var) + sizeof(Item) * ndx• The first thing it needs is the
base address of the array• This is actually the constant
pointer– The name of the variable
• To this it must add the product of– The length of one Item thing– The subscript
• In this case ndx
Copyright 1998-2014 Curt Hill
Examples• int x[4],y[4];x[i] = y[j];
• To find x[i]– Take the base address of x– Add the product of
• i• the length of an int (4)
• No assignments of the this form are allowed:
x = y;because x is a constant pointer
Using whole arrays• Suppose the following
declaration– int a[50], b[50];
• Without subscript an array name is just a constant pointer
• Thus– b = a;– Is not legal
• Only place to use an array name without an index is when passing as a parameter
Copyright 1998-2014 Curt Hill
Copyright 1998-2014 Curt Hill
Arrays as parameters• Array elements by value
– Nothing odd: cos(z[3])– An element of an array may be
used anywhere that type may be used
• Array elements by reference– Nothing odd: void doit(int & x);…doit(z[i]);
Copyright 1998-2014 Curt Hill
Whole array parameters• Two things that are different
– No size needed– Passed by reference only
Copyright 1998-2014 Curt Hill
No Size Needed• The formal parameter list does
not need the size:int sum(int ar[], int size);– The brackets mark it as an array– It is already allocated so no size
needed– Any array of right type may be
passed• There is no way for sum to
discover the size on its own• Thus most functions take the
array and a separate parameter to indicate size to use
Copyright 1998-2014 Curt Hill
Reference Only• Since an array name is a
constant pointer we do not need to use the & in the formal parameter list
• A value parameter makes a copy and passes it
• Since arrays could be large, making a copy could be expensive– Thus disallowed
Copyright 1998-2014 Curt Hill
Example formal parameters• Consider:
int average(int ar[], int size){…}…int large[1000], small[10];…x = average(large,1000);y = average(small,10);
• Creating generalized array processing libraries in C/C++ is easy
Copyright 1998-2014 Curt Hill
Arrays as input parameters• Since we only use call by
reference, how do we prevent a function from changing an array?
• Use const prefix:int cc(const int ar[], int size);
• If you attempt to assign to ar then errors occur– Unfortunately you can get around it
and change a constant array– But I am not going to say how
Copyright 1998-2014 Curt Hill
Specifying the size• You may specify a size in a
formal parameter list– But it is ignored
• Thus:int doit(int ar[], int size);int doit(int ar[9],int size);are exactly the same