﻿ One, Two-Dimensional (2D) Arrays and Pointers in C yale university faculty

## One, Two-Dimensional (2D) Arrays and Pointers in C yale university faculty

Array arr defined in above program contains 5 integer values stored at indices from 0 to 4. Array index starts from zero that’s why index of the last element will be size of array minus one, that is, arr in this case. Below is the pictorial representation of arr, where the array arr points to first element at location 0. This element has address 1024 that is the base address of the array and represented by the array name.

Elements stored in an array are accessed by following the syntax "arrayname[index]" e.G., arr yields 4 in above example. This strategy computes the base address of the desired element by combining the base address of the array with the index of desired element. How much is the tuition for yale university every array element takes a fixed number of bytes, which is known at compile time and this is decided by the type of array.

In above example array is of type integer thus consumes 4 bytes (size of integer) per element. So the address of any n th element in the array using 0 based indexing will be at an offset of (n * element_size) bytes from the base address of the array. You can devise the following formula to compute n th element address.

The square bracket ([]) syntax to access array elements deals with address computation at its own. It takes the index that you wish to access, multiplies it with the element size, adds this resulting offset to the base address of the array, and finally dereferences the resulting pointer to get the desired element.

Now that you understand the computation of offset and then address of the element you want to access. Any element in the valid range of array can also be accessed by adding the index of that element to the base address and it computes the same offset as it was computed by square bracket syntax. Yale university united states but it leaves the result as a pointer and you have to dereference it at your own.

It should be clear from above passage of text that (arr + 3) is a pointer to the integer arr, (arr + 3) is of type int* while arr is of type int. The two expressions only differ by whether the pointer is dereferenced or not. Thus the expression (arr + 3) is exactly equivalent to the expression &arr. In fact those two probably compile to exactly the same code. They both represent a pointer to the element at index 3. Any square bracket ([]) syntax expression can be written with the + syntax instead. We just need to add in the pointer dereference. Conclusively, arr is exactly equivalent to *(arr + 3).

You can also write *(arr + 3) to *(3 + arr), this is perfectly right and acceptable as addition is commutative. Where is yale university in usa likewise, can you write arr to 3[arr]? Yes, you can. But on the contrary [arr]3 or arr is not correct and will result into syntax error, as (arr + 3)* and (3 + arr)* are not valid expressions. The reason is dereference operator should be placed before the address yielded by the expression not after the address.

The short answer is, it depends on language design whether the start index should be zero or any other positive integer of your choice. In fortran, when an array is declared with integer a(10) (an array of 10 integer elements), the index starts from 1 and ends at 10. Yalle yalle however, this behavior can be overridden using a statement like, integer a(0:9), declaring an array with indices from 0 to 9.

But in C language we do not have the freedom to start the array index from any other number than zero, and language strictly sticks to zero as start index of array. It is because in C the name of an array is a pointer, which is a reference to a memory location. Therefore, an expression *(arr + n) or arr[n] locates an element n-locations away from the starting location because the index is used as an offset. Likewise, the first element of the array is exactly contained by the memory location that array refers (0 elements away), so it should be denoted as *(arr + 0) or *(arr) or arr.

A two dimensional array (will be written 2-D hereafter) can be imagined as a matrix or table of rows and columns or as an array of one dimensional arrays. Following is a small program twodimarraydemo.C that declares a 2-D array of 4×3 ( 4 rows and 3 columns) and prints its elements.

/* program: twodimarraydemo.C */ #include #define ROWS 4 #define COLS 3 int main ( ) { // declare 4×3 array int matrix [ROWS ] [COLS ] = { { 1 , 2 , 3 } , { 4 , 5 , 6 } , { 7 , 8 , 9 } , { 10 , 11 , 12 } } ; for ( int i = 0 ; i < ROWS ; i ++ ) { for ( int j = 0 ; j < COLS ; j ++ ) { printf ( "%d \t" , matrix [i ] [j ] ) ; } printf ( " \n" ) ; } return 0 ; }

The array elements in above program are stored in memory row after row sequentially; assuming array is stored in row major order. As you know array name behaves like a constant pointer and points to the very first element of the array. The same is true for 2-D arrays, array name matrix serves as a constant pointer, and points to the first element of the first row. Yale college seminars array elements within valid range of matrix can be accessed by following different syntaxes.

Passing 2-D array to a function seems tricky when you think it to pass as a pointer because a pointer to an array and pointer to a pointer (double pointer) are two different things. If you are passing a two dimensional array to a function, you should either use square bracket syntax or pointer to an array syntax but not double pointer. Why should not you use double pointer to access array elements will be described in next section. Let’s rewrite twodimarraydemo.C as twodimarraydemoptrver.C and demonstrate passing 2-D array to function for printing array.

/* program: twodimarraydemoptrver.C */ #include #define ROWS 4 #define COLS 3 void array_of_arrays_ver ( int arr [ ] [COLS ] ) ; /* prototype */ void ptr_to_array_ver ( int ( *arr ) [COLS ] ) ; /* prototype */ int main ( ) { // declare 4×3 array int matrix [ROWS ] [COLS ] = { { 1 , 2 , 3 } , { 4 , 5 , 6 } , { 7 , 8 , 9 } , { 10 , 11 , 12 } } ; printf ( "printing array elements by array of arrays version function: \n" ) ;

Ptr_to_array_ver (matrix ) ; return 0 ; } void array_of_arrays_ver ( int arr [ ] [COLS ] ) { int i , j ; for (i = 0 ; i < ROWS ; i ++ ) { for (j = 0 ; j < COLS ; j ++ ) { printf ( "%d \t" , arr [i ] [j ] ) ; } printf ( " \n" ) ; } } void ptr_to_array_ver ( int ( *arr ) [COLS ] ) { int i , j ; for (i = 0 ; i < ROWS ; i ++ ) { for (j = 0 ; j < COLS ; j ++ ) { printf ( "%d \t" , ( *arr ) [j ] ) ; }

Another very important point to note is the called function does not allocate space for the array and it does not need to know the overall size, so the number of rows can be omitted. Space is not allocated because called function does not create a local copy of the array rather it uses the original one that has been passed to it. The width of the array is still important because number of elements contained by one row has to be told to compiler in order to increment the pointer to point the next row. So the column dimension COLS must be specified.