Array
Arrays are a data structure that is used to store a group of objects of the same type sequentially in memory. All the elements of an array must be the same data type, for example float, char, int, pointer to float, pointer to int, a structure or function. Structures provide a way to organize related data and will be studied in a later lesson. Functions provide a way to define a new operation. They are used to calculate a result or update parameters. Functions will be covered in a later lesson. The elements of an array are stored sequentially in memory. This allows convenient and powerful manipulation of array elements using pointers.
Defining Arrays
An array is defined with this syntax.
An array is defined with this syntax.
| datatype arrayName[size]; |
Examples:
| int ID[30]; /* Could be used to store the ID numbers of students in a class */ float temperatures[31]; /* Could be used to store the daily temperatures in a month */ char name[20]; /* Could be used to store a character string. Character strings in C are terminated by the null character, '\0'. This will be discussed later in the this lesson. */ int *ptrs[10]; /* An array holding 10 pointers to integer data */ unsigned short int[52]; /* Holds 52 unsigned short integer values */ |
We will start with a simple program to get a few definitions out of the way. Consider the following code fragment;
int index;
double ar[4];
double *pt;
int main()
{ pt = ar + 2; /* Pointer arithmetic */ for (index = 0 ; index < 4 ; index++) { ar[index] = (double)(3 * index); }}
We define a simple integer variable named index that will be stored in global memory and because it is a global variable, it will be initialized to zero according to the definition of C. We also define an array of 4 double type variables. Each of these variables will also be automatically initialized to zero. Finally, we define a pointer named pt which will be initially set to a value of NULL because it is global.
When we complete execution of the for loop and are just ready to drop out of the bottom of the main() function, we have a memory map like that shown in figure 1. The pointer pt has been assigned the address of the third element of the array so it is effectively pointing to that element. The variable named index contains the value of 4 because it was used to iterate through the loop.
MULTI DIMENSIONED ARRAYS
If a singly dimensioned array is built with a pointer, you should also suspect that a multiply dimensioned array is generated with one or more pointers. This is true as we shall see. Consider the following array definition;
double ar2[3][4];
Our first problem is to define what this array would look like, but it is difficult to do with the logical layout. Figure 3 is the logical layout but it does not give us a good picture of what is happening under the hood. In fact, it does not give a good picture at all because I found it necessary to put the name of each box within the box, which does not leave room to write the value currently stored in each box, or that will be stored there when we actually store some data in the array.The "internal pseudo-memory map" (there's that big term I invented earlier) works just fine to display what the doubly-dimensioned array looks like within the system, and can be used to illustrate how it is actually implemented. Figure 4 is the graphical representation of the array. Keep in mind that this may not be an accurate picture of what is actually stored in memory, but it is accurate in terms of the concept of a doubly dimensioned array.
The first thing you will notice is that there is still a single pointer that is the name of the entire array, but in this case it is a constant pointer to a constant pointer. It points to an array of pointers, each of which points somewhere inside of the array. Finally, there is the actual storage for the elements of the array. According to the definition of C, all elements of the array must be contiguous, so we have chosen to draw the elements in the manner shown to emphasize this fact. You may guess, and properly so, that none of the pointers are necessarily real pointers, but are somehow bound up in the addressing logic of the code, or they may be stored in registers. On the other hand, they could actually all be pointers if the implementors decided to do so. We really cannot make any assumptions about the underlying implementation. We can still use address arithmetic for the ar2[n] array of pointers as we did earlier in this document, but we have a slightly different case this time since we only need to move the pointer by the number of bytes in a pointer, rather than by the number of bytes in one of the elements of the array. So the following formula is used with size being the number of bytes used to store a pointer;
byte_address = ar2 + index * size However, we must keep in mind that the compiler writer has the option to store these pointers anywhere, even in registers, so the address of these pointers may not be available for your use. It will be correct to think of these pointers existing somewhere in memory conceptually however in order to understand how a doubly dimensioned array is stored in the computer memory.
We can still do pointer arithmetic within each row as we did with the singly dimensioned array.
The constant pointer named ar2[0]can be considered to be a constant pointer to the first element in the first row and the formula given above can be used to do pointer arithmetic just like it is referring to a singly dimensioned array. Therefore, the following two lines of code,
*(ar2[0] + 3) = 17.1; ar2[0][3] = 17.1; are identical as far as the compiler is concerned. Either will assign the value of 17.1 to the last element of the first row.
Passing Arrays to Functions
When an array is passed into a function, the function receives not a copy the array, but instead the address of the first element of the array. The function receives a pointer to the start of the array. Any modifications made via this pointer will be seen in the calling program. Let's see how this works. Suppose the main program has an array of 10 integers and that a function has been written to double each of these.
When an array is passed into a function, the function receives not a copy the array, but instead the address of the first element of the array. The function receives a pointer to the start of the array. Any modifications made via this pointer will be seen in the calling program. Let's see how this works. Suppose the main program has an array of 10 integers and that a function has been written to double each of these.
| void doubleThem(int a[], int size); int main() { int myInts[10] = {1,2,3,4,5,6,7,8,9,10}; doubleThem(myInts, 10); return 0; } void doubleThem(int a[], int size) { int i; for (i = 0; i < size; i++) { a[i] = 2 * a[i]; } } |
No comments:
Post a Comment