Transcript Document

Chapter 8
Arrays
Instructor:
Alkar & Demirer
What is an Array?
• Scalar data types use a single memory cell to store a single
value.
• For many problems you need to group data items together.
• A program that processes exam scores for a class, for example,
would be easier to write if all the scores were stored in one area
of memory and were able to be accessed as a group.
• C allows a programmer to group such related data items together
into a single composite data structure.
• In this lecture, we look at one such data structure: the Array.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-2
Array Terminology (1)
• An array is a collection of two or more adjacent memory cells
that are:
– The same type (i.e. int)
– Referenced by the same name
• These individual cells are called array elements
• To set up an array in memory, we must declare both the name
and type of the array and the number of cells associated with it
double x[8];
• This instructs C to associate eight memory cells with the name
x; these memory cells will be adjacent to each other in memory.
• You can declare arrays along with regular variables
double cactus[5], needle, pins[7];
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-3
Array Terminology (2)
• Each element of the array x may contain a single value of type
double, so a total of eight such numbers may be stored and
referenced using the array name x.
• To process the data stored in an array, we reference each
individual element by specifying the array name and identifying
the element desired.
• The elements are numbered starting with 0
– An array with 8 elements has elements at 0,1,2,3,4,5,6, and 7
• The subscripted variable x[0] (read as x sub zero) refers to the
initial or 0th element of the array x, x[1] is the next element in
the array, and so on.
• The integer enclosed in brackets is the array subscript or index
and its value must be in the range from zero to one less than the
array size.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-4
Array Declaration - Syntax
•
•
•
•
<element-type> <array-name> [<array-size>]
The number of elements, or array size must be
specified in the declaration.
Contiguous space in memory is allocated for the array.
Related data items of the same type (i.e. contiguous
memory cells are of the same size).
Remain same size once created (i.e. they are “Fixedlength entries” )
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-5
Arrays
• Simple data types use a single memory cell to
store variable.
• Array is a data structure which groups two or
more adjacent memory cells.
• Syntax:
element-type aname[size];
element-type aname[size]={initialization lsit};
• e.g., double x[8];
char name[4];
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-6
The Elements of Array
• We use the array subscript to specify the array
element being manipulated, which ranges from
zero to one less than the number of size.
Array size
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
Array subscript
8-7
Array Initialization
• We can initialize an array in its declaration.
• We can omit the size of an array that is being
fully initialized since the size can be deduced
from the initailization list.
• e.g.,
char vowels[] = {‘A’,
‘E’, ’I’, ’O’, ’U’};
int prime[]={2, 3, 5, 7, 11, 13,
17, 19, 23};
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-8
Visual representation of an Array
int x[8]; x[2] = 20;
Memory
Addresses
342901
?
0
342905
?
1
342909
20
2
342913
?
3
342917
?
4
342921
?
5
342925
?
6
342929
?
7
Array
Index/Subscript
Array Element
Note: Index starts with 0, not with 1
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-9
Array Initialization(1)
• When you declare a variable, its value isn’t initialized unless
you specify.
int sum;
int sum = 1;
// Does not initialize sum
// Initializes sum to 1
• Arrays, like variables, aren’t initialized by default
int X[10]; //creates the array, but doesn’t set any of its values.
• To initialize an array, list all of the initial values separated by
commas and surrounded by curly braces:
int X[10] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
• The array elements are initialized in the order listed
X[0] == 2
X[4] == 11
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-10
Array Initialization(2)
• If there are values in the initialization block, but not enough to
fill the array, all the elements in the array without values are
initialized to 0 in the case of double or int, and NULL in the
case of char.
int scores[20] = {0};
// all 20 elements are initialized to 0
int scores[20] = {1, 2, 3}; // First 3 elements are initialized to 1, 2,
// 3 and the rest are initialized to 0
• If there are values in the initialization block, an explicit size for
the array does not need to be specified. Only an empty array
element is sufficient, C will count the size of the array for you.
int scores[] = {20, 10, 25, 30, 40}; // size of the array score is
// automatically
calculated as 5
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-11
Good Practice
const int maxAarraySize = 12;
int myArray[maxArraySize];
OR
#define MAX_ARRAY_SIZE 12
int myArray[MAX_ARRAY_SIZE];
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-12
Array Subscripts
• We use subscripts/indices to differentiate between the
individual array elements
• We can use any expression of type int as an array subscript.
• However, to create a valid reference, the value of this subscript
must lie between 0 and one less than the array size.
• It is essential that we understand the distinction between an
array subscript value and an array element value.
int x[2]; int y = 1; x[y] = 5;
The subscript is y (which is 1 in this case), and the array
element value is 5
• C compiler does not provide any array bound checking. As a
programmer it is your job to make sure that every reference is
valid (falls within the boundary of the array).
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-13
Access (1)
1.
2.
point[1]
// the 2nd element of array point is accessed
point[9] = 20; // the 10th element of array point is assigned
// the value 20
3. Want to process all of the elements of an array?
Example: Adding the values of all array elements
Two alternative style for loops
for ( i = 0; i < arraySize; i++) sum += a[i];
for ( i = 0; i <= arraySize-1; i++) sum += a[i];
•
Note : The array element is a single valued variable of the
corresponding type and can be manipulated as a variable of
that type.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-14
Using for Loops for Sequential
Access
• The elements of an array are usually processed
by for loops, because
– the elements are sequentially stored in the memory,
and
– the for loop is suitable for sequential manipulation.
• e.g.,
int square[SIZE], i;
for(i=0; i<SIZE; i++)
square[i]=i*i;
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-15
Access (2)
int x[5];
int i = 2;
// declare an integer array of size 5
x[0] = 20; // valid
x[2.3] = 5; // Invalid, index is not int
x[6] = 10; // valid, but dangerous
x[2*i – 3] = 3; // valid, assign 3 to x[1]
x[i++];
// access x[2] and then assign 3 to i
x[(int) x[1]]; // access x[3]
• Referencing to an array element outside of the created bounds
is possible but rather not recommended.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-16
Algorithm for Searching an Array
1. Assume target has not been found
2. Start with the intial array element
3. Repeat while the target is not found and there are more
4. if the current element matches array
5. set flag true
6. remember array index
7. else
8. advance to next array element
9. If flag set true
10. return the array index
11. else
12. return -1 to indicate not found
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-17
int found = 0, i = 0;
int arr[10];
while ( !found && (i <10) ) {
if ( arr[i] == target ) {
found = 1;
index = i;
}
else
i++;
}
if ( found )
return index;
else
return -1;
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-18
Basics
int * ptr1, * ptr2;
int a[10];
ptr1 = &a[2];
ptr2 = a; // equivalent to ptr2 = &a[0];
• An array variable is actually a pointer to
the first element of the array.
• ptr2 points to the first element of the
array and get others by offset.
• Referring a[i] is same as referring *(a+i).
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
Memory
Addresses
a
?
0
a+1
?
1
a+2
?
2
.
?
3
.
?
4
?
5
?
6
?
7
8-19
Array Elements as Function
arguments
• If we want to print the ith element of the array x[i], then
we can do the following:
printf(”%d\n”, x[i]);
scanf(”%d”, &x[i]);
• We can also pass array elements as arguments to
functions that we write. For example:
swap1(x[i], x[i+1]);
swap2(&x[i], &x[i+1]);
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-20
Having arrays as function arguments
• Besides passing individual array elements to functions, we can
write functions that take entire arrays as arguments.
• There are several ways of passing arrays to functions but in
each case we only pass the address of the array.
• This is very similar to what we did during “passing variables
by reference…”
• As we are not passing a copy of the array – any changes to the
array made within the function will also effect the original
array.
• When an array name with no subscript appears in the argument
list of a function call, what is actually stored in the function’s
corresponding parameter is the address of the array. Example,
int a[10];
foo(a);
foo(&a[0]); // same as above
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-21
Array Arguments
• We can also pass an entire array as the input
argument for a function.
• However, the function does not copy the array
but just manipulates the original array.
– An assignment to one of the array elements by a
statement in the function changes the contents of the
original array.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-22
Passing array as function parameter
• Array names are pointers.
• The name of an array contain the address of its initial
element, a = &a[0];
• Passing an array as function argument copies the
value of the pointer to the formal array parameter and
points to the same location.
• Where is the array actually located?
– At the data area of the function that declared it.
– For an array declared as formal parameter, space is
allocated in the function data area only for the address of
the initial array element of the array passed as actual
argument.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-23
Using arrays in formal parameter list
void foo(int x[10]); // sized array
• Store the address of the corresponding array argument (a in
previous slide) to variable x and remember it as an array of 10
elements.
void foo(int x[]); // unsized array
• The length of the array is not specified. Since it is not a copy ,
the compiler does not need to allocate space for the array and
therefore does not need to know the size of the array.
• With this, we can pass an array of any size to function foo.
void foo(int *x); // array pointer
• Function foo can take any integer array as argument.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-24
Arrays as Input Arguments
• ANSI C provides a qualifier that we can include in the
declaration of the array formal parameter in order to
notify the C complier that the array is only an input to
the function and that the function does not intend to
modify the array.
• This qualifier allows the compiler to mark as an error
any attempt to change an array element within the
function.
void foo(const int x[], int size)
• The const tells C not to allow any element of the array x
to change in the function foo.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-25
C code Example
int main(void){
int a[5]={1,2,3,4,5};
int i;
clear1(a,5);
clear2(a,5);
for(i=0; i<5; i=i+1)
printf("%d ", a[i]);
return 0;
}
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
void clear1(int x[], int size){
int i;
for(i=0; i<size; i=i+1)
x[i] = 0;
}
void clear2(int *x, int size){
int *p;
for(p=x; p<(x+size); p=p+1)
// for(p=&x[0]; p<&x[size]; p=p+1)
*p = 0;
}
8-26
An Example of Array Arguments
• We have the flexibility to pass an array of any
size to the function.
– Because C does not allocate any memory space for
the array, and thus the compiler does not need to
know the size.
int list[] is
the declaration for
passing an int array
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-27
Data Areas After Calling
fill_array (x, 5, 1);
The value of each element in the
original array are changed to 1.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-28
Alternative Formats of Array
Arguments
• fill_array(x, 5, 1) is the same as
fill_array(&x[0], 5, 1).
– This call may lead to misunderstanding of the reader.
• In the declaration for function fill_array,
we can declare the array argument as either
– int list[] or int *list.
• If you wish to prevent the modification of the
array argument, you can write
– fill_array(const int list[], …)
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-29
Using Array Elements as Function
Arguments (1/2)
• Suppose that we have a function prototype as
shown below.
– void do_it(double arg_1, double
*arg2_p, double *arg3_p);
• Let x be an array of type double elements.
• We can call the function do_it as follows.
– do_it(x[0], &x[1], &x[2]);
• The modification on arg2_p and arg3_p will
change the values of x[1] and x[2].
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-30
Using Array Elements as Function
Arguments (2/2)
arg_1 has a
copy of the value
from x[0]
arg_3 is a pointer
pointed to the
Copyright ©2004 Pearson Addison-Wesley.memory
All rights reserved.of x[2].
8-31
Returning an Array from a
function(1)
• Returning arrays should work too - right?
int a[5];
a = foo();
…..
int* foo() {
int c[5] = {1,2,3,4,5};
return c;
}
• Wrong! In C, it is not legal for a function’s return
type to be an array.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-32
Returning an Array from a
function(2)
• Type problem between int[] and int*
– a is a constant pointer type, you can’t change it.
• Array c is stored in function foo’s stack frame.
– Return just copies the pointer, not the array.
– Memory where the array c resides may be overwritten once
function foo finishes its execution.
• To do it properly
– Pass an array as a function argument from your calling
function and modify it inside the called function.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-33
Returning an Array Result
• The add_arrays function computes the sum of
corresponding elements in arrays ar1 and ar2,
and then stores results into ar3.
Input array arguments
Output array arguments
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-34
Memory for calling add_arrays(x,
y, x_plus_y)
Indirectly read the values of array x
Indirectly read the values of array y
Indirectly write the values of x+y into
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
x_plus_y
8-35
Stacks
• The stack is a data structure in which only the
top element can be accessed.
• There are two operations which are associated
with the stack.
– Pop: remove the top element of a stack.
– Push: insert a new element at the top of the stack.
a
b
c
pop
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
push d
b
c
d
b
c
8-36
Stacks
• The usage of stack is commonly in daily life.
– e.g., Dishes used by guests in a buffet restaurant.
• Stacks are the frequently used data structure in
programming.
– e.g., Before jumping to a sub-function, the variables
in the current function are pushed into a stack.
• Array is one of the approaches to implement the
stack.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-37
The Implementation of a Stack by
an Array (push)
• Suppose we have the following global variables.
int size = 5;
char stack[size];
int count=0;
• The push function:
void push(char item){
if(count < size){
stack[count]=item;
count++;
}
}
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-38
The Implementation of a Stack by
an Array (pop)
char pop(void){
char temp;
if(count > 0){
temp=stack[count];
count--;
}else{
printf(“Stack empty!\n”);
return 0;
}
return temp;
}
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-39
Searching and Sorting an Array
• Sometimes we may need to
– search a particular value in an array, or
– sort an array to rearrange the array elements in
numerical order.
• Commonly used searching methods:
– Sequential search, binary search, etc.
• Commonly used sorting methods:
– Selection sort, bubble sort, quick sort, etc.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-40
Sequential Search in an Array
target is the value we want to
locate in the array
Traverse the array to look for the
value identical to target.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-41
Selection Sort in an Array
• Selection sort is an
intuitive sorting
algorithm.
– Find the index of the
smallest element in the
array.
– Swap the smallest
element with the first
element.
– Repeat the above steps
for the 2nd, 3rd, …,
smallest elements.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-42
An Function for Selection Sort
Suppose we have a function that can
find the minimal element.
Swap the minimal
element with the
previous larger element.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-43
Multidimensional Arrays
• A multidimensional array is an array with two or more
dimensions.
• We will use two-dimensional arrays to represent tables of data,
matrices, and other two-dimensional objects.
• Thus int x[3][3] would define a three by three matrix that holds
integers.
• Initialization is bit different
int x[3][3] = {{1,2,3}, {4,5,6}, {7,8,9}};
• Both indices starts at 0.
• Think of it as x[rows][cols].
x[0][0]=1
x[0][1]=2
x[0][2]=3
x[1][0]=4
x[1][1]=5
x[1][2]=6
x[2][0]=7
x[2][1]=8
x[2][2]=9
Row
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
Col inside a row
8-44
Multidimensional Arrays
• Multidimensional arrays stand for the arrays
with two or more dimensions.
• Syntax for normal usage:
element-type aname[size1][size2]…[sizen];
Syntax for parameter in function prototype:
element-type aname[][size2]…[sizen]
• e.g., char tictac[3][3];
– A 2-dimensional array with three rows and three
columns.
• e.g., tictac[][3];
– The declaration for the function prototype.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-45
The Memory Allocated for
tictac[3][3]
• The memory allocated for array
tictac[3][3]is shown below.
• The number of total allocated element is 3*3=9
elements.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-46
Initialization of Multidimensional
Arrays
• The multidimensional array can also be
initialized in declarations.
• The initialized values are grouped in rows.
– e.g., char
tictac[3][3]={{‘a’, ’b’, ’c’},
{‘d’, ’e’, ’f’}, {‘ ’,‘ ’,‘ ’}};
• We can also declare arrays with more
dimensions.
– e.g., declare a 3-dimensional array.
int
enroll[course][campus][cls_rank];
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-47
2D array in address space(1)
• How to store a multidimensional array into a onedimensional memory space.
• Row major ordering assigns
successive elements, moving
across the rows and then down
the columns, to successive
memory locations.
Address of a[row][col] = Base_Address + (row * row_size + col)
Base_Address is the address of the first element of the array (A[0][0] in
this case).
char *base = &A[0][0];
Referring A[i][j] is same as referring *(base+4*i+j);
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-48
2D array in address space(2)
int a[2][3]; // 2 rows and 3 cols
• Alternative interpretation: Three 1D array of 4 integers.
• The base address of the array is &a[0][0].
• The array name a by itself is equivalent to &a[0]. This time it is
a pointer to an array of 3 elements.
• Different ways to access (i,j) th element:
a[1][2]
a[i][j]
a[1][1]
*(a[i] + j)
a[1][0] a+1
*((*(a+i)) + j)
a[0][2]
a[0][1]
*(&a[0][0] + 4*i + j)
a[0][0]
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
a
8-49
Multi-dimensional Arrays.
Declaration
int a[N]; int b[M][N]; int c[L][M][N];
Array element
a[i]
b[i][j]
c[i][j][k]
Pointer to element
a
b[i]
c[i][j]
b
c[i]
Pointer to 1D array
of N element
Pointer to 2D array
of M*N element
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
c
8-50
Passing Multidimensional array (1)
For a multidimensional array we
a[7][9][2] = {0};
must declare all but the first
…
dimension. Only 7 can be omitted.
sum(arr,7);
…
int sum(int a[][9][2], int asize){
int i, j, k, sum = 0
for( i = 0; i<asize; ++i) {
for( j = 0; j<9; ++j) {
for( k = 0; k<2; ++k) {
sum += a[i][j][k];
return sum;
}
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-51
Passing Multidimensional array (1)
Address of a[row][col] = b_add + (row * row_size + col)
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-52
The Memory Allocated for
enroll[100][5][4]
enroll[10
0][5][4]
consists of
100*5*4
=2000
elements.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-53
Having trouble linking math.h?
• Link with the following option
gcc –lm –o test test.o
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-54
Figure 8.9 Function to Add Two Arrays
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-55
Figure 8.10 Function Data Areas for
add_arrays(x, y, x_plus_y, 5);
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-56
Partially Filled Arrays
• Frequently, a program will need to process many lists of similar
data
• These list may not all be the same length
• In order to reuse an array for processing more than one data set,
the programmer often declares an array large enough to hold the
largest data set anticipated.
• This array can be used for processing shorter lists as well,
provided that the program keeps track of how many array
elements are actually in use.
• One way to do this is to have the original array size declared as
the highest needed, and then store a sentinel value after the last
value inputted.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-57
Sorting an Array – Selection Sort
• Similar to sorting cards.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-58
Figure 8.16 Trace of Selection Sort
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-59
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-60
Common Programming Errors
• The most common error in using arrays is a subscriptrange error.
• An out-of-range reference occurs when the subscript
value is outside the range specified by the array
declaration.
– In some situations, no run-time error message will be
produced – the program will simply produce incorrect
results.
– Other times, you may get a runtime error like “segmentation
fault” or “bus error”
• Remember how to pass arrays to functions.
• Remember that the first index of the array is 0
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-61
Study (1/2)
• Write a function that computes the average grades and
sorts the grades of two classes.
• Your program should input two lists of grades for each
class.
• Your program should output:
(1) average grades for each class;
(2) a list of sorted grades of two classes.
• You can use the sorting function in p.401 in the text
book.
• You can either assume the number of students in each
class is fixed or prompt the user to input the number.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-62
Study (2/2)
• e.g.,
Please input grades of 1st class:
55 45 65 85 75
Please input grades of 2nd class:
80 70 50 60 40
Output:
The average grades of 1st class is: 65
The average grades of 2nd class is: 60
The sorted grades of two classes are:
40 45 50 55 60 65 70 75 80 85
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8-63