Presentation is loading. Please wait.

Presentation is loading. Please wait.

Numeric Arrays Numeric Arrays Chapter 4.

Similar presentations


Presentation on theme: "Numeric Arrays Numeric Arrays Chapter 4."— Presentation transcript:

1 Numeric Arrays Numeric Arrays Chapter 4

2 What you MUST know before we start:
Numeric Arrays What you MUST know before we start: (Remember: The topics in this course build on each other) What integers and real numbers are How integers and real numbers are stored in RAM The basic concept of what an address is and how it is used The use of C/C++ to manipulate integers and real numbers

3 Numeric Arrays Array: (def) A Regular Order or Arrangement
For our Purposes, we can define an array as a data structure containing a fixed number of contiguous storage elements all of the same type Assume we wished to store the squares of the numbers: Number: 1 2 3 4 5 6 7 8 9 Square: 1 4 9 16 25 36 49 64 81 We could store the numbers as scalar variables: int d0 = 0, d1 = 1, d2 = 4, d3 = 9, d4 = 16, d5 = 25, d6 = 36, d7 = 49, d8 = 64, d9 = 81;

4 The problem with this approach is:
Numeric Arrays The problem with this approach is: Remembering the variables names can become complex Manipulating each of the variables is tedious For Example, suppose we were trying to find the value 64 in our list, but didn’t know where it was stored: if (d0 == 64) printf(“at d0’’); else if (d1 == 64) printf(“at d1’’); else if (d2 == 64) printf(“at d2’’); else if (d3 == 64) printf(“at d3’’); else if (d4 == 64) printf(“at d4’’); else if (d5 == 64) printf(“at d5’’); else if (d6 == 64) printf(“at d6’’); else if (d7 == 64) printf(“at d7’’); else if (d8 == 64) printf(“at d8’’); else if (d9 == 64) printf(“at d9’’); else printf(“Not found”);

5 What does this declaration do ???
Numeric Arrays A preferred alternative would be to store the squares of the numbers as an integer array: int numvector[10]; What does this declaration do ??? Using the datatype int implies that we will require 2-bytes per element the variable name numvector will be associated with the base address of the array [10] indicates how many elements will be in our array since we are creating an array of type int, we are requesting 2 * 10 = 20 CONTINGUOUS bytes of RAM

6 (We are just asking the compiler to determine the number)
Numeric Arrays We could also initialize our array when we declare it: int numvector[10] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}; OR int numvector[] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}; Even though we do not explicitly indicate how many elements are in the array, we are still requesting 20 bytes of CONTIGUOUS storage (We are just asking the compiler to determine the number) Because we are specifying only one subscript or offset, we are declaring a vector (a one-dimensional array)

7 How are arrays stored in RAM ???
Numeric Arrays How are arrays stored in RAM ??? That depends of the type of data we wish to store In our case, we are storing an integer array containing 10 elements, so we are requesting 2 * 10 = 20 bytes of CONTIGUOUS storage If (at run-time) we find there are 20 contiguous bytes of storage available starting at location 9050: 9050 ([0]) 9051 ([0]) 9052 ([1]) 9053 ([1]) 9054 ([2]) 9055 ([2]) 9056 ([3]) 9057 ([3]) 9058 ([4]) 9059 ([4]) 9060 ([5]) 9061 ([5]) 9062 ([6]) 9063 ([6]) 9064 ([7]) 9065 ([7]) 9066 ([8]) 9067 ([8]) 9068 ([9]) 9069 ([9]) 9070 9071 9072 9073

8 Numeric Arrays At a more abstract, and understandable, level, this might appear as: 9050 & 9051 numvector[0] 1 9052 & 9053 numvector[1] 4 9054 & 9055 numvector[2] Notice: The first element on the list (element number 1) has the subscript (offset) 0 (zero) The last element on the list (element number 10) has the subscript (offset) 9 (nine).

9 Numeric Arrays Why is the first element subscripted as [0] AND why is it also referred to as the offset ??? In fact, the subscript (at least in C) IS the offset from the base address of the array REMEMBER: When we first initialized our array, we stated: The variable name numvector will be associated with the base address of the array Given a base address, we can use the offset (or subscript) to determine the addresses of any individual element in the array How does this work ???

10 (Since 2-bytes are needed for an integer)
Numeric Arrays Remember: Our basic directive: “Give me an address and tell me what type of data is stored there, and I will tell you the value of that data type” Arrays allow a convenient way of determining an address Given an integer array of 10 elements, we can calculate individual array addresses using the formula: Element address = base address of the array + (offset number * 2) (Since 2-bytes are needed for an integer)

11 Given our the Array (as stored in RAM):
Numeric Arrays Given our the Array (as stored in RAM): 9 9056 & 9057 numvector[3] 16 9058 & 9059 numvector[4] 25 9060 & 9061 numvector[5] 9050 & 9051 numvector[0] 1 9052 & 9053 numvector[1] 4 9054 & 9055 numvector[2] 81 9068 & 9069 numvector[9] ---- 9070 & 9071 9072 & 9073 49 9064 & 9065 numvector[7] 64 9066 & 9067 numvector[8] 36 9062 & 9063 numvector[6] We can calculate element addresses as: Address: Offset Address: Offset (0 * 2) = 9050 5 (5 * 2) = 9060 1 (1 * 2) = 9052 6 (6 * 2) = 9062 2 (2 * 2) = 9054 7 (7 * 2) = 9064 3 (3 * 2) = 9056 8 (8 * 2) = 9066 4 (0 * 2) = 9058 9 (9 * 2) = 9068

12 Suppose we made the declaration: float fvector[10];
Numeric Arrays Suppose we made the declaration: float fvector[10]; And the base address of the array was 12348 In RAM this might appear as: ----- 12348 to fvector[0] 12352 to fvector[1] 12356 to fvector[2] 12360 to fvector[3] 12364 to fvector[4] 12368 to fvector[5] 12372 to fvector[6] 12376 to fvector[7] 12380 to fvector[8] We could calculate element addresses as: Offset Address: Offset Address: (0 * 4) = 12348 5 (5 * 4) = 12368 1 (1 * 4) = 12352 6 (6 * 4) = 12372 2 (2 * 4) = 12356 7 (7 * 4) = 12376 3 (3 * 4) = 12360 8 (8 * 4) = 12380 4 (4 * 4) = 12364 9 (9 * 4) = 12384

13 Consider the following C Code:
Numeric Arrays Consider the following C Code: #include <stdio.h> void main() { int vector[] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}; int index; printf("the base address of vector is %lu\n",&vector); for (index = 0; index < 10; index++) printf("vector[%d] = %d; stored at address %lu\n", index, vector[index], &vector[index]); } The (slightly modified) output would be: the base address of vector is vector[0] = 0; stored at address vector[1] = 1; stored at address vector[2] = 4; stored at address vector[3] = 9; stored at address vector[4] = 16; stored at address vector[5] = 25; stored at address vector[6] = 36; stored at address vector[7] = 49; stored at address vector[8] = 64; stored at address vector[9] = 81; stored at address

14 Numeric Arrays What if we entered illegal subscripts? For example, for the previous code, what if we entered the for loop parameters: for (index = 8; index < 12; index++) printf ("vector[%d] = %d; stored at address %lu\n", index, vector[index], &vector[index]); (This is illegal because index should not take on any values larger than 9) The (slightly modified) output might appear as: vector[8] = 64; stored at address vector[9] = 81; stored at address vector[10] = ; stored at address vector[11] = ; stored at address

15 But why is the value stored at, for example, vector[10], -13107 ???
Numeric Arrays How can there be a vector[10]? Or vector[11]?? vector[10] is nothing more than address 10 * 2 = 20 bytes offset from the base ( = ) vector[11] is nothing more than address 11 * 2 = 22 bytes offset from the base ( = ) The command we issued was: index++ Which increments the contents of index (at the time, 9) by 1 Therefore, the location: &vector[index] Would yield the addresses given above But why is the value stored at, for example, vector[10], ???

16 If we were to go to address: &vector[10]
Numeric Arrays If we were to go to address: &vector[10] We might find which equates to Neg. One’s Compliment Two’s Compliment = -( ) = -( ) = -13,107

17 Multi-dimensional Arrays
Numeric Arrays Multi-dimensional Arrays Suppose I wished to store the Squares AND the cubes of the digits from 0 through 9 We could store them as two vectors: int vect1[10] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}, vect2[10] = {0, 1, 8, 27, 64, 125, 216, 343, 512, 729}; Assuming that we did, AND we found that the base addresses of the two arrays were: vect1 = &vect1[0] = 12350 AND vect2 = &vect2[0] = 12424 the relevant section of RAM might appear as:

18 Numeric Arrays 12350 & 12351 12352 & 12353 1 12354 & 12355 4 12356 & 12357 9 12358 & 12359 16 12360 & 12361 25 12362 & 12363 36 12364 & 12365 49 12366 & 12367 64 12368 & 12369 81 12424 & 12425 12426 & 12427 1 12428 & 12429 8 12430 & 12431 27 12432 & 12433 64 12434 & 12435 125 12436 & 12437 216 12438 & 12439 343 12440 & 12441 512 12442 & 12443 729 vect1 = &vect1[0] = 12350 Where: AND vect2 = &vect2[0] = 12424

19 The Row and Column numbers are the table offsets
Numeric Arrays OR we could store the values as ONE table: Table sqrscubes Row\Col 1 1 1 Where: 2 4 8 The Row and Column numbers are the table offsets 3 9 27 4 16 64 5 25 125 6 36 217 7 49 343 8 64 512 9 81 729

20 How is RAM storage different ???
Numeric Arrays What difference does it make if we use one or two arrays ??? With two vectors we need 2 blocks of RAM each containing 20 contiguous bytes of RAM With one array (matrix) we need 1 block of RAM which contains 40 contiguous bytes With two vectors we need two variables (two base addresses) With one matrix we need one variable (one base address) The ORDER in which the data is stored in RAM differs How is RAM storage different ???

21 Consider the following C code:
Numeric Arrays Consider the following C code: void main() { int matrix[10][2], index; for (index = 0; index < 10; index++) { matrix[index][0] = index * index; matrix[index][1] = index * index * index; } } Using the datatype int implies that we will require 2-bytes per element since we are creating a 2-dimensional array of type int, we are requesting 2 * 2 * 10 = 40 CONTINGUOUS bytes of RAM the variable name matrix will be associated with the base address of the array

22 If the base address for the array matrix was: 63128
Numeric Arrays If the base address for the array matrix was: 63128 The relevant portion of RAM might appear as: 63128 & 63129 63130 & 63131 63132 & 63133 1 63134 & 63135 63136 & 63137 4 63138 & 63139 8 63140 & 63141 9 63142 & 63143 27 63144 & 63145 16 63146 & 63147 64 63148 & 63149 25 63150 & 63151 125 63152 & 63153 36 63154 & 63155 217 63156 & 63157 49 63158 & 53159 343 63160 & 63161 63162 & 63163 512 63164 & 63165 81 63166 & 63167 729 NOTICE that the data is stored BY ROWS or by row offset

23 How do we calculate these addresses ???
Numeric Arrays Looking at RAM in terms of offsets, we find: 63128 & 63129 matrix[0][0] 63130 & 63131 63132 & 63133 matrix[1][0] 63134 & 63135 matrix[1][1] 63136 & 63137 matrix[2][0] 63138 & 63139 matrix[2][1] 63140 & 63141 matrix[3][0] 63142 & 63143 matrix[3][1] 63144 & 63145 matrix[4][0] 63146 & 63147 matrix[4][1] 63148 & 63149 matrix[5][0] 63150 & 63151 matrix[5][1] 63152 & 63153 matrix[6][0] 63154 & 63155 matrix[6][1] 63156 & 63157 matrix[7][0] 63158 & 53159 matrix[7][1] 63160 & 63161 matrix[8][0] 63162 & 63163 matrix[8][1] 63164 & 63165 matrix[9][0] 63166 & 63167 matrix[9][1] Which corresponds to the manner in which we originally laid out our table. How do we calculate these addresses ???

24 Element address = base address of the array
Numeric Arrays Since we know that each row contains 2 elements (4-bytes), and each element requires 2-bytes of storage, we must (slightly) modify our previous formula: Element address = base address of the array + (row offset * bytes per row) + (column offset * bytes per element) Since we are dealing with an integer array which has the base address the formula is: Element address = + (row offset * 4) + (column offset * 2)

25 Row/Col Address Row/Col Address matrix[0][0] matrix[0][1] matrix[1][0]
Numeric Arrays Row/Col Address Row/Col Address [0][0] *4 + 0*2 = 63128 [5][0] *4 + 0*2 = 63148 [0][1] *4 + 1*2 = 63130 [5][1] *4 + 1*2 = 63150 [1][0] *4 + 0*2 = 63132 [6][0] *4 + 0*2 = 63152 [1][1] *4 + 1*2 = 63134 [6][1] *4 + 1*2 = 63154 [2][0] *4 + 0*2 = 63136 [7][0] *4 + 0*2 = 63156 [2][1] *4 + 1*2 = 63138 [7][1] *4 + 1*2 = 63158 [3][0] *4 + 0*2 = 63140 [8][0] *4 + 0*2 = 63160 [3][1] *4 + 1*2 = 63142 [8][1] *4 + 1*2 = 63162 [4][0] *4 + 0*2 = 63144 [9][0] *4 + 0*2 = 63164 [4][1] *4 + 1*2 = 63146 [9][1] *4 + 1*2 = 63166 63128 & 63129 matrix[0][0] 63130 & 63131 matrix[0][1] 63132 & 63133 matrix[1][0] 63134 & 63135 matrix[1][1] 63136 & 63137 matrix[2][0] 63138 & 63139 matrix[2][1] 63140 & 63141 matrix[3][0] 63142 & 63143 matrix[3][1] 63144 & 63145 matrix[4][0] 63146 & 63147 matrix[4][1] 63148 & 63149 matrix[5][0] 63150 & 63151 matrix[5][1] 63152 & 63153 matrix[6][0] 63154 & 63155 matrix[6][1] 63156 & 63157 matrix[7][0] 63158 & 63159 matrix[7][1] 63160 & 63161 matrix[8][0] 63162 & 63163 matrix[8][1] 63164 & 63165 matrix[9][0] 63166 & 63167 matrix[9][1]

26 The formula works regardless of how many dimensions there are.
Numeric Arrays The formula works regardless of how many dimensions there are. Consider the C declaration: float multiarray[5][4][3][2]; We are requesting a total of: 4 * (5 * 4 * 3 * 2) = 4 * 120 = 480 Contiguous bytes of RAM Notice that: Each change in the last (4th) offset requires: 4-bytes Each change in the 3rd offset requires: 8-bytes Each change in the 2nd offset requires: 24-bytes Each change in the 1st offset requires: 96-bytes Which makes sense since the first offset can change 5 times and we know we require a total of 480 (= 5 * 96) bytes

27 The General formula, therefore, would be:
Numeric Arrays The General formula, therefore, would be: Element address = base address of the array + (first offset * 96) + (second offset * 24) + (third offset * 8) + (fourth offset * 4) If we found that the base address of our variable multiarray was: 21578 We could calculate the following (sample) addresses as: Array Element Address multiarray[0][0][2][1] *96 + 0*24 + 2*8 + 1*4 = multiarray[1][2][0][0] *96 + 2*24 + 0*8 + 0*4 = multiarray[1][3][2][1] *96 + 3*24 + 2*8 + 1*4 = multiarray[2][1][1][0] *96 + 1*24 + 1*8 + 0*4 = multiarray[4][3][2][1] *96 + 3*24 + 2*8 + 1*4 =

28 Let’s Consider this program line by line
Numeric Arrays Searching an Array Assume that we wished to determine if the number 25 was in our original list (of squared values): #include <stdio.h> void main() { int vector[10] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}; int index; for (index = 0; index < 10 && vector[index] != 25; index++); if (index > 9) printf(“The value was not found\n”); else printf(“The value %d was found at offset %d\n”, vector[index], index); } Let’s Consider this program line by line

29 int vector[10] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}; int index; 1 4
Numeric Arrays int vector[10] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}; Reserve (& initialize) 2 * 10 = 20 bytes at base address vector int index; Reserve 2 bytes at base address index for (index = 0; Set (once) the contents of location index to zero (0) 15234 & 15235 12350 & 12351 12352 & 12353 1 12354 & 12355 4 12356 & 12357 9 12358 & 12359 16 12360 & 12361 25 12362 & 12363 36 12364 & 12365 49 12366 & 12367 64 12368 & 12369 81

30 Therefore, execute the command
Numeric Arrays int vector[10] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}; Reserve (& initialize) 2 * 10 = 20 bytes at base address vector int index; Reserve 2 bytes at base address index for (index = 0; index < 10 && vector[index] != 25; True True 15234 & 15235 Therefore, execute the command 12350 & 12351 12352 & 12353 1 12354 & 12355 4 12356 & 12357 9 12358 & 12359 16 12360 & 12361 25 12362 & 12363 36 12364 & 12365 49 12366 & 12367 64 12368 & 12369 81

31 Numeric Arrays int vector[10] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}; Reserve (& initialize) 2 * 10 = 20 bytes at base address vector int index; Reserve 2 bytes at base address index for (index = 0; index < 10 && vector[index] != 25; index++); What Command ??? There is none needed in this case We know that the element we are looking for has not been found (vector[index] != 25) We also know that the list hasn’t been exhausted (index < 10) We need only move to the next element

32 Throughout the loop, the logic would be:
Numeric Arrays int vector[10] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}; Reserve (& initialize) 2 * 10 = 20 bytes at base address vector int index; Reserve 2 bytes at base address index for (index = 0; index < 10 && vector[index] != 25; index++); Throughout the loop, the logic would be: (contents of) index Vector[index] != 25 ? Pass No. index <= 10 ? Yes (= 0) Yes 1 1 Yes (= 1) Yes 2 2 Yes (= 4) Yes 3 (= 9) Yes 4 3 Yes 4 Yes (= 16) Yes 5 5 Yes (= 25) NO 6 We are out of the loop

33 The value 25 was found at offset 5
Numeric Arrays int vector[10] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}; Reserve (& initialize) 2 * 10 = 20 bytes at base address vector int index; Reserve 2 bytes at base address index for (index = 0; index < 10 && vector[index] != 25; index++); Once out of the loop we need to print our findings: False if (index > 9) º º º º º º º º º º else printf(“The value %d was found at offset %d\n”, vector[index], index); The value 25 was found at offset 5

34 Let’s Consider this program line by line
Numeric Arrays Pointers and Arrays: Assume that we wished to determine if the number 25 was in our original list (of squared values): #include <stdio.h> void main() { int vector[] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}; int * index; index = vector; while ((index <= &vector[9]) && (* index != 25)) index++; if (index > &vector[9]) printf(“The value was not found\n”); else printf(“The value %d was found at address %p\n”, *index, index); } Let’s Consider this program line by line

35 while ((index <= &vector[9]) && (*index != 25))
Numeric Arrays int vector[] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}; Reserve (& initialize) 2 * 10 = 20 bytes at base address vector (assume that vector has the base address 8900) int *index; Reserve 4-bytes of storage at location index If we go to location index, we would find a signed integer value (assume that index has the base address 8932) index = vector; Store the address of vector (i.e., 8900) at location index while ((index <= &vector[9]) && (*index != 25)) Continue processing as long as: The contents of index (presently 8900) is less than or equal to &vector (= *2 = 8918) AND The contents of the address stored at location index (at location 8900 we will presently find the integer 0) is not equal to the integer 25

36 index++; Inside the loop, there is only one statement:
Numeric Arrays Inside the loop, there is only one statement: index++; Increment the contents of location index since location index contains an address which points to an integer, incrementing means increasing the value by 2 Throughout the loop, the logic would be: = 8918 (contents of) index index <= &vector[9] ? *index *index != 25 ? Pass No. 8900 Yes Yes 1 8902 Yes 1 Yes 2 8904 Yes 4 Yes 3 8906 Yes 9 Yes 4 8908 Yes 16 Yes 5 8910 Yes 25 NO 6 We are out of the loop

37 (Assuming we were looking for the value 25)
Numeric Arrays When we come out of the loop, there are two possibilities: EITHER: index > &vector[9] Meaning that the contents of location index (which contains an an address) are greater than the address of the last legal array address (i.e., 8918) In which case we print out: The value was not found OR We print out the value: The value 25 was found at address 8910 (Assuming we were looking for the value 25) How could the contents of location index ever be greater than the array address 8918 ???

38 And we are out of the loop
Numeric Arrays If we were looking for the value 108 (not on the list): = 8918 (contents of) index index <= &vector[9] ? *index *index != 108 ? Pass No. 1 8900 Yes Yes 2 8902 Yes 1 Yes 8904 Yes 4 Yes 3 4 8906 Yes 9 Yes 8908 Yes 16 Yes 5 8910 Yes 25 Yes 6 Yes 36 Yes 7 8912 8914 Yes 49 Yes 8 8916 Yes 64 Yes 9 8918 Yes 81 Yes 10 8920 NO Unknown 11 Probably Not And we are out of the loop

39 Array Declarations Automatic Arrays External Arrays int main()
Numeric Arrays Array Declarations Automatic Arrays Defined INSIDE a function Exists ONLY for the duration of the function NOT initialized When done, memory allocation freed int main() { int intarray[100], index; External Arrays Known to ALL functions Do NOT Expire when a particular functions ends INITIALIZED when declared int intarray[100]; int main() { int index;

40 Static Arrays int main() { static int intarray[100]; int index;
Numeric Arrays Static Arrays Like Automatic Arrays, LOCAL to the function Like External arrays, RETAIN VALUES between calls INITIALIZED at declaration int main() { static int intarray[100]; int index;

41 Numeric Arrays


Download ppt "Numeric Arrays Numeric Arrays Chapter 4."

Similar presentations


Ads by Google