Arrays 1 A
Arrays 1 A
G S Lehal
1
2
Data Structure
A data structure is a scheme for efficiently organizing data in the
memory of a computer.
array
Linked list
queue
tree stack
2
Data Structures
◼ The way in which the data is organized
affects the performance of a program for
different tasks. The choice of data structure
and algorithm can make the difference
between a program running in a few seconds
or many days.
4
Some Questions to Ask
◼ Are all data inserted into the data structure at the
beginning, or are insertions interspersed with other
operations?
◼ Can data be deleted?
◼ Are all data processed in some well-defined order, or is
random access allowed?
5
Data Structure Philosophy
Each data structure has costs and benefits.
Rarely is one data structure better than another in all
situations.
A data structure requires:
◼ space for each data item it stores,
◼ time to perform each basic operation,
◼ programming effort.
6
Data Structure Philosophy (cont)
Each problem has constraints on available space and time.
Only after a careful analysis of problem characteristics can
we know the best data structure for the task.
Bank example:
◼ Start account: a few minutes
◼ Transactions: a few seconds
◼ Close account: overnight
7
Common operations Data Structures
◼ Add
◼ Change
◼ Delete
◼ Traverse
◼ Search
8
Data Structures
◼ Example:library
◼ is composed of elements
(books)
◼ Accessing a particular book
requires knowledge of the
arrangement of the books
◼ Users access books only
through the librarian
The logical arrangement of data
elements, combined with the set of
operations we need to access the
elements. 9
Common Data Structures
◼ Array
◼ Stack
◼ Queue
◼ Linked List
◼ Tree
◼ Heap
◼ Hash Table
◼ Priority Queue
10
Arrays
◼ Groups of nearly identical variables are very common
and very tedious to program.
◼ Example: make one variable to hold the total marks of each
student in the class. We would have to declare 22 integer
variables that all represent something similar (total marks) and
all have similar names (e.g. marks1, marks2, ..., marks22):
12
Arrays
◼ Each box holds one value
◼ All boxes hold values of the same type
◼ The entire set of boxes is given one name
◼ We can select any box by using the common name and
the index of the box
◼ The indices start at zero.
marks
223 256 312 299 329 ...
0 1 2 3 4 13
The Array data structure
◼ An array is an indexed sequence of
components stored in contiguous memory
locations.
◼ The length of the array is determined when the array is created,
and cannot be changed
◼ Each component of the array has a fixed, unique index
◼ Indices range from a lower bound to an upper
bound
◼ Any component of the array can be
inspected or updated by using its index
◼ This is an efficient operation: O(1) = constant time
14
Array variations
◼ The array indices may be integers (C, Java) or other
discrete data types (Pascal, Ada)
15
15
Arrays in C/C++
◼ Array indices are integers
◼ An array of length n has bounds 0 and n-1
◼ Arrays are homogeneous
16
16
Arrays
◼ To create an array, we must first declare it (just as we
need to declare variables).
◼ In the declaration we need to specify the name of the
array, the type of the elements and the number of
elements:
int marks[5];
◼ After the declaration:
marks (All box
contents are
initially
undefined)
17
Arrays
◼ Array declaration syntax:
element_type array_name[size];
18
Arrays
◼ Array indexing:
◼ Each element of the array is like an ordinary variable.
◼ In order to access that element, you must specify the name
of the array and the index of the element:
array_name[index]
◼ Example:
20
Arrays
◼ After you declare an array, you must assign values
(initialize it) before you can use it in any other way.
There are several ways to do this.
1. Initialize the array during declaration:
21
Array initialization
◼ You can initialize some of the elements with non zero values,
while the rest will automatically be initialized to zero.
int marks[5] = {219, 320};
Equivalent to:
marks[0] = 219; marks[1]=320;
marks[2] = marks[3] = marks[4] = 0;
• You can let the compiler figure the size for you:
int marks[] = {219, 320, 199, 256, 311};
This will set the size of array marks equal to the number of entries
in the RHS bracket
22
Array initialization
2. Use assignment statements to initialize each element
separately:
23
Array initialization
3. Use a for-loop to read the values from the user (or
assign some default value).
int marks[5];
for (i=0; i<5; i++) {
printf("Type total marks : ");
scanf("%d", &marks[i]);
}
24
Array initialization
4. For arrays of integers only:
You can initialize all elements to zero using the
following syntax:
25
Array pitfalls
◼ You CANNOT assign a value to the entire array as if it
were one big variable:
int scores[5];
int size;
int scores[size]; ERROR!
printf("Type array size: ");
scanf("%d", &size); 26
Array pitfalls
◼ You CANNOT rely on C to enforce valid index values
int scores[5];
▪ Example:
If Loc(X[0]) = 1200, and w = 4, find Loc(X[8]) ?
Loc(X[8])= Loc(X[0]) + 4*(8 )
= 1232
29
Insertion into Array
What happens if you want to insert an item at a
specified position in an existing array?
◼ Write over the current contents at the given index (which
might not be appropriate), or
◼ The item originally at the given index must be moved up one
position, and all the items after that index must shuffled up
30
Inserting an element into an array
◼ Suppose we want to insert the value 8 into this sorted
array (while keeping the array sorted)
1 3 3 7 12 14 17 19 22 30
◼ We can do this by shifting all the elements after the mark
right by one location
◼ Of course, we have to discard the 30 when we do this
1 3 3 7 8 12 14 17 19 22
• Moving all those elements makes this a slow
operation (linear in the size of the array)
31
Inserting an element into an array
◼ Suppose we want to insert the value 8 into this sorted
array (while keeping the array sorted)
1 3 3 7 12 14 17 19 22 30
◼ We can do this by shifting all the elements after the mark
right by one location
◼ Of course, we have to discard the 30 when we do this
1 3 3 7 8 12 14 17 19 22
• Moving all those elements makes this a slow
operation (linear in the size of the array)
32
Removal from Arrays
What happens if you want to remove an item from a
specified position in an existing array?
◼ Leave gaps in the array, i.e. indices that contain no
elements, which in practice, means that the array element
has to be given a special value to indicate that it is “empty”,
or
◼ All the items after the (removed item’s) index must be
shuffled down
33
Deleting an element from an array
◼ Deleting an element is similar--again, we have to
move all the elements after it
1 3 3 7 8 12 14 17 19 22
1 3 3 7 12 14 17 19 22 ?
35
Smallest Value
◼ Problem
◼ Find the smallest value in an array of integers
◼ Input
◼ An array of integers and a value indicating the
number of integers
◼ Output
◼ Smallest value in the array
◼ Note
◼ Array remains unchanged after finding the
smallest value!
36
Passing An Array
Notice empty brackets
37
Reverse function
void reverse(int list[], int newList[], int size)
{
for (int i = 0, j = size - 1; i < size; i++, j--)
{
newList[j] = list[i];
}
}
int main(){
int list1[5] = {1, 2 , 4, 5, 6};
int list2[5];
reverse(list1, list2 ,5);
return 0;
}
list 1 2 3 4 5 6
newList 6 5 4 3 2 1
38
A few exercises on arrays
◼ Write down the function
◼ int del_array(int a[], int size, int pos) to delete the value
stored at position pos in the array a.
◼ Write down the function
◼ void insert(int a[], int size, int pos, int val) to insert val at
position pos in the array a.
◼ Write down the function
◼ void reverse(int a[], int size) to reverse the contents of array
a.
39
2D Arrays
◼ Arrays are not limited to type int; we can have arrays
of... any other type including float, char , double and
even arrays !!!
◼ An array of arrays is called a two-dimensional array
and can be regarded as a table with a number of
rows and columns:
40
2D Arrays
◼ Each row corresponds to marks of a student. Each
column corresponds to marks in a subject.
50 50 50 60
is a 5 4 array: 80 80 88 72
5 rows, 4 columns 49 50 40 60
60 60 60 76
75 80 75 81
41
Declaring 2D Arrays
50 50 50 60
80 80 88 72
49 50 40 60
60 60 60 76
75 80 75 81
◼ This is
an array of size 5 marks[5]
whose elements are arrays of size 4 [4]
whose elements are integer int
◼ Declare it like this: int marks[5][4];
int marks[5][4] = {
{ 50, 50, 50, 60} ,
{ 80, 80, 88, 72} ,
{ 49, 50, 40, 60} ,
{ 60, 60, 60, 76} ,
{ 75, 80, 75, 81}
};
43
Initializing 2D arrays
◼ An array may be initialized by using a loop
#define ROWS 5
#define COLS 4
int main () {
int i, j;
int marks[5][4];
#define ROWS 5
#define COLS 4
int main () {
int i, j;
int marks[5][4];
for (i=0; i<ROWS; i++)
for (j=0; j<COLS; j++)
scanf("%d", &marks[i][j]);
}
45
Initializing 2D arrays
◼ An integer array may be initialized to all zeros as
follows:
int nums[5][4] = {0};
46
Using 2D arrays
◼ To access an element of a 2D array, you need to
specify both the row and the column:
nums[0][0] = 16;
printf("%d", nums[1][2]);
47
Storing Two-Dimensional Array in
memory
◼ A two-dimensional array can be stored in the
memory in two ways:
◼ Row-major implementation
◼ Column-major implementation
48
Row-major Implementation
◼ Row-major implementation is a linearization
technique in which elements of array are stored
row-wise that means the complete first row is
stored then the complete second row is stored and
so on.
◼ For example an array [3][3] is stored in the
memory as show bellow:
1 2 3
Row-major Implementation
50
Row-major Implementation
51
Row-major Implementation
1 2 3
Column-major Implementation
54
Column-major Implementation
56
Arrays and Pointers
57
Arrays and Pointers
◼ If a is the name of an array, the expression
a is equivalent to &a[0].
a[ 0 ] is equivalent to *a.
a[ i ] is equivalent to *(a + i).
◼ It follows then that &a[ i ] and (a + i) are also equivalent.
Both represent the address of the ith element beyond a.
◼ On the other hand, if p is a pointer, then it may be used with
a subscript as if it were the name of an array. p[ i ] is
identical to *(p + i)
58
Arrays and Pointers
59
Array Example Using a Pointer
int x[4] = {12, 20, 39, 43}, *y;
y = &x[0]; // y points to the beginning of the array
printf("%d\n", x[0]); // outputs 12
printf("%d\n", *y); // also outputs 12
printf("%d\n", *y+1); // outputs 13 (12 + 1)
printf("%d\n", (*y)+1); // also outputs 13
printf("%d\n", *(y+1)); // outputs x[1] or 20
y+=2; // y now points to x[2]
printf("%d\n", *y); // prints out 39
*y = 38; // changes x[2] to 38
printf("%d\n", *y-1); // prints out x[2] - 1 or 37
*y++; // sets y to point at the next array element
printf("%d\n", *y); // outputs x[3] (43)
(*y)++; // sets what y points to to be 1 greater
printf("%d\n", *y); // outputs the new value of x[3] (44)
60
Arrays and Pointers
62
Arrays and Pointers
63
Arrays and Pointers
What will be the output?
void main()
{
int b[10], *bPtr = b, i;
for(i=0; i<10; i++)b[i]=i;
printf("%d\n", *(bPtr+5)); 5
printf("%d\n", bPtr[5]); 5
printf("%d\n", 5[bPtr]); 5
printf("%d\n", 5[b]); 5
}
64
Arrays and Pointers
What will be the value of elements of array a ?
main()
{
int *p, *p2, x=50, i=2;
int a[5]={1,2,3,4,5};
p=&x;
p2=a;
*(p2+1)=*p;
*p= *p2 + *(p2+2);
*p2 = 10;
p=p2+4;
p[-2] = 60;
p2[3] = *p2*i;
p2[4] = p[-1] + *(p-1);
} 65
Arrays and Pointers
What will be the value of elements of array a ?
main()
{
int *p, *p2, x=50, i=2;
int a[5]={1,2,3,4,5};
p=&x;
p2=a;
*(p2+1)=*p;
*p= *p2 + *(p2+2);
*p2 = 10;
p=p2+4;
p[-2] = 60;
p2[3] = *p2*i;
p2[4] = p[-1] + *(p-1);
} 10, 50, 60, 20, 40 66
Arrays and Pointers
What will be the value of elements of array x ?
main()
{
int i, x[10], *p, *q;
for(i=0; i<10; i++)
x[i]=i+1;
p = x+9;
q = p-8;
for(i=3; i>0; i--, p--)
*p += 10;
for(i=1; i<5; i++, q++)
*q += i;
}
67
Arrays and Pointers
What will be the value of elements of array x ?
main()
{
int i, n=8, x[10], *p, *q, j=10;
for(i=0; i<10; i++)
x[i]=i+1;
p = x+9;
q = p-8;
for(i=3; i>0; i--, p--)
*p += 10;
for(i=1; i<5; i++, q++)
*q += i;
} 1, 3, 5, 7, 9, 6, 7, 18, 19, 20
68
Passing Arrays
◼ When an array is passed to a function, the address of the array
is copied onto the function parameter. Since an array address
is a pointer, the function parameter may be declared in either
fashion. E. g.
int sumArray( int a[ ], int size)
is equivalent to
int sumArray( int *a, int size)
◼ The code in the function is free to use “a” as an array name or
as a pointer as it sees fit.
◼ The compiler always sees “a” as a pointer. In fact, any error
messages produced will refer to “a” as an int *
69
sumArray
• int sumArray( int a[ ], int size)
• {
• int k, sum = 0;
• for (k = 0; k < size; k++)
• sum += a[ k ];
• return sum;
• }
70
sumArray (2)
• int sumArray( int a[ ], int size)
• {
• int k, sum = 0;
• for (k = 0; k < size; k++)
• sum += *(a + k);
• return sum;
• }
71
sumArray (3)
72
Arrays and Pointers
int
foo(int array[],
unsigned int size)
{
… What does this print? 4
printf(“%d\n”, sizeof(array));
}
... because array is really
a pointer
int
main(void)
{
int a[10], b[5];
… foo(a, 10)… foo(b, 5) … What does this print? 40
printf(“%d\n”, sizeof(a));
}
73
Arrays and Pointers
◼ Consider the following code. Which of the statements are
legal?
◼ void test(int x[10], int* p)
{
int y[10];
x += 1;
*x = 42;
p[2] = x[-1];
y = x;
x = y;
*y = 5;
}
74
Arrays and Pointers
◼ Consider the following code. Which of the statements are
legal?
◼ void test(int x[10], int* p)
{
int y[10];
x += 1; legal, x is really a pointer variable
*x = 42;
p[2] = x[-1];
y = x;
x = y;
*y = 5;
}
75
Arrays and Pointers
◼ Consider the following code. Which of the statements are
legal?
◼ void test(int x[10], int* p)
{
int y[10];
x += 1; legal, x is really a pointer variable
*x = 42; legal
p[2] = x[-1];
y = x;
x = y;
*y = 5;
}
76
Arrays and Pointers
◼ Consider the following code. Which of the statements are
legal?
◼ void test(int x[10], int* p)
{
int y[10];
x += 2; legal, x is really a pointer variable
*x = 42; legal
p[2] = x[-1]; legal
y = x;
x = y;
*y = 5;
}
77
Arrays and Pointers
◼ Consider the following code. Which of the statements are
legal?
◼ void test(int x[10], int* p)
{
int y[10];
x += 1; legal, x is really a pointer variable
*x = 42; legal
p[2] = x[-1]; legal
y = x; illegal y is an array
x = y;
*y = 5;
}
78
Arrays and Pointers
◼ Consider the following code. Which of the statements are
legal?
◼ void test(int x[10], int* p)
{
int y[10];
x += 1; legal, x is really a pointer variable
*x = 42; legal
p[2] = x[-1]; legal
y = x; illegal y is an array
x = y; legal, x is really a pointer variable
*y = 5;
}
79
Arrays and Pointers
◼ Consider the following code. Which of the statements are
legal?
◼ void test(int x[10], int* p)
{
int y[10];
x += 1; legal, x is really a pointer variable
*x = 42; legal
p[2] = x[-1]; legal
y = x; illegal y is an array
x = y; legal, x is really a pointer variable
*y = 5; legal, ‘cause *y is same as y[0]
}
80
81
◼ Memory allocation in C:
◼ calloc()
◼ malloc()
◼ realloc()
◼ Deallocated using the free() function.
◼ Memory allocation in C++
◼ using the new operator.
◼ Deallocated using the delete operator.
82
malloc()
To allocate memory use
void *malloc(unsigned int nBytes);
83
malloc() example
To create a dynamic array of 100 integers:
int *p;
if ((p = (int*)malloc(100 * sizeof(int))) ==
NULL){
printf("out of memory\n");
exit();
}
◼ Note we cast the return value to int*.
◼ Note we also check if the function returns NULL.
84
malloc() example
◼ Note Once the memory has allocated like this, we can
treat the memory block as an array. Thus :
p[40] = 50;
Is valid statement for previous example.
85
free()
To release allocated memory use
free()
Deallocates memory allocated by malloc().
◼ Takes a pointer as an argument.
e.g. free(p);
◼ NOTE:When we free()some memory, the memory is
not erased or destroyed Instead, the operating
system is informed that we don't need the memory
any more, so it may use it for e.g. another program
◼ Trying to use memory after freeing it can cause a
segmentation violation (program crash)
86
Allocation Examples
p1 = malloc(4)
p2 = malloc(5)
p3 = malloc(6)
free(p2)
p4 = malloc(2)
87
The new operator
◼ If memory is available, the new operator allocates memory
space for the requested object/array, and returns a pointer to
(address of) the memory allocated.
◼ If sufficient memory is not available, the new operator returns
NULL.
◼ The dynamically allocated object/array exists until the delete
operator destroys it.
88
The delete operator
◼ The delete operator deallocates the object or array currently
pointed to by the pointer which was previously allocated at
run-time by the new operator.
◼ the freed memory space is returned to Heap
◼ the pointer is then considered unassigned
◼ If the value of the pointer is NULL there is no effect.
89
Example
int *ptr; ptr FDE0
ptr = new int; FDE1
*ptr = 22; FDE2
cout << *ptr << endl;
FDE3
delete ptr;
ptr = NULL;
0EC4
0EC5
0EC6
0EC7
90
Example (Cont ..)
0EC4
0EC5
0EC6
0EC7
91
Example (Cont ..)
0EC4 22
0EC5
0EC6
0EC7
92
Example (Cont ..)
0EC4 22
Output:
0EC5
22 0EC6
0EC7
93
Example (Cont ..)
0EC4 22
0EC5
0EC6
0EC7
94
Example (Cont ..)
0EC4 22
0EC5
0EC6
0EC7
95
Dynamic allocation and deallocation of arrays
◼ Use the [IntExp] on the new statement to create an array of
objects instead of a single instance.
◼ On the delete statement use [] to indicate that an array of
objects is to be deallocated.
96
Example of dynamic array allocation
int* grades = NULL;
int numberOfGrades;
delete [] grades;
grades = NULL;
97
Programming Assignment - 1
98
Summary of Arrays
◼ Good things:
◼ Fast, random access of elements
◼ Very memory efficient, very little memory is required other
than that needed to store the contents (but see bellow)
◼ Bad things:
◼ Slow deletion and insertion of elements
◼ Size must be known when the array is created and is fixed
(static)
99