Sunteți pe pagina 1din 9

TWO-DIMENSIONAL ARRAYS

Two-dimensional arrays are a little more complicated to use than one-dimensional ones. This page presents two methods of passing a pointer to a two-dimensional array to a function for processing.

The first method uses subscript notation inside the function. This method has the same disadvantage as in Pascal -- the function is essentially array specific in that the data types need to match. However, while in Pascal you need to have a programmer-defined double-subscripted type which is used for both the array and the parameter in the called function, in C only the second subscript in each needs to match. A completesample program is provided below. The second method uses typecasting in the function call and a pointer with offsets inside the function. This method permits the programmer to use the same function to process information in arrays with different dimensions. A complete sample program is provided below.

Subscript Notation
Consider an int array as declared below.
#define NUM_STUDENTS 5 #define NUM_TESTS 4 int grades[NUM_STUDENTS][NUM_TESTS];

By convention, the first subscript is understood to be for rows and the second for columns. This array can hold up to 20 integer values, the product of the values used to declare the array. As is usual in C, subscripts start with zero, so the subscripts range from 0 to 4 for the rows and 0 to 3 for the columns. If the system uses four bytes for an int, this array would use 80 bytes of RAM. All of the bytes are in consecutive memory locations, the first row occupying the first 20 bytes, the second the next 20, and so on.

The following table illustrates how the subscripts are specified for this array, which has five (5) rows and four (4) columns.
0 1 2 3

0 [0][0] [0][1] [0][2] [0][3]

1 [1][0] [1][1] [1][2] [1][3] 2 [2][0] [2][1] [2][2] [2][3] 3 [3][0] [3][1] [3][2] [3][3] 4 [4][0] [4][1] [4][2] [4][3]

Array Initialization: Inline To initialize all elements of the grades array to -1 (a number that is highly improbable for a grade), you could use a nested loop structure such as the following.
for( i = 0; i < NUM_STUDENTS; i++) for( j = 0; j < NUM_TESTS; j++) grades[i][j] = -1;

Array Initialization: At Declaration It is also possible to initialize elements of an array at the time of its declaration. The following declaration assigns values for three grades for each of the first two students in the array. Note that the values for a specific row are enclosed within their own pair of curly brackets.
int grades[NUM_STUDENTS][NUM_TESTS] = { {55, 60, 65}, {95, 90, 85} };

It may facilitate your programming, if you keep track of how many elements in the array hold usable values. For this simple example, we can initialize two variables.
int num_students = 2; int num_tests = 3;

Array Processing: Using Subscripts in a Function Since, by definition, the name of any array is a pointer, we can call a function which returns the highest grade in the array as follows.
high_test = get_highest( grades, num_students, num_tests);

The second and third arguments allow the function to search only the elements which have been initialized. One of the ways of writing get_highest() uses subscript notation:
int get_highest(int a[][NUM_TESTS], int row, int col) /* Assumes that there is at least one element */

{ int i, j; int highest = a[0][0]; for( i = 0; i < row; i++) for( j = 0; j < col; j++) if ( a[i][j] > highest) highest = a[i][j]; return highest; }

It is necessary in this instance to specify the number of columns in the array (the number of items in a row) so that the compiler can determine the offsets from the beginning of the array. Unlike with the one-dimensional array algorithm, where we avoided comparing the first element with itself, here the extra code required does not outweigh the simplicity of the above algorithm.

Sample Program 1
This is a complete program which initializes part of an array of integer grades at the time of its declaration with 6 values and then calls a function to find, return, and print the highest grade. Note that the dimensions of the array have been changed from those used in the discussion above by altering the compiler directives.
#include <stdio.h> #define NUM_STUDENTS 25 #define NUM_TESTS 10 int get_highest(int a[][NUM_TESTS], int row, int col); int main() { int grades[NUM_STUDENTS][NUM_TESTS] = { {55, 60, 65}, {85, 90, 95} }; int num_students = 2; int num_tests = 3; int high_test; high_test = get_highest( grades, num_students, num_tests); printf("The highest score is %d.\n", high_test); return 0; } int get_highest(int a[][NUM_TESTS], int row, int col) /* Assumes that there is at least one element */ { int i, j; int highest = a[0][0]; for( i = 0; i < row; i++)

for( j = 0; j < col; j++) if ( a[i][j] > highest) highest = a[i][j]; return highest; }

Back to Top

Pointer Notation with Offset


Consider the int array as declared below. It is the same as the one discussed above except for the slight modification of the identifiers. This change was made so that we can have a second array which will be declared with different dimensions.
#define NUM_STUDENTS1 5 #define NUM_TESTS1 4 int grades1[NUM_STUDENTS1][NUM_TESTS1];

The following table illustrates the offsets of the elements from the start of this array, which has five (5) rows and four (4) columns. The italicized numbers are the subscripts for the rows and columns.
0 0 1 2 0 4 8 1 1 5 2 2 6 3 3 7

9 10 11

3 12 13 14 15 4 16 17 18 19

Array Initialization: Inline To initialize all elements of the grades1 array to -1 (a number that is highly improbable for a grade), you could use a nested loop structure as was done above or do a cheat such as the following.
for( i = 0; i < NUM_STUDENTS1 * NUM_TESTS1; i++) *((int *)grades1 + i) = -1;

This method takes advantage of the fact that grades1 is a pointer constant for a twodimensional array. It uses the loop control variable as the offset from the beginning of the array. The casting of the pointer constant fools the compiler into thinking that the array is one-dimensional. Since both our two-dimensional grade1 array and a one-

dimensional array capable of holding 20 ints would be stored using a total of 80 consecutive bytes of RAM, no harm is done by this trickery. Array Initialization: Generalized Using a Function However, since the code above is array specific, we may want to generalize by creating a function which will initialize any two-dimensional array of ints.
void init_int_array(int *a, int num_rows, int num_cols) { int i; for( i = 0; i < num_rows * num_cols; i++) *(a + i) = -1; }

Here we are using the generic variable name a which is a pointer to an int. The loop control variable i is the offset into the array. The call to this function for grades1 would be:
init_int_array( (int *)grades1, NUM_STUDENTS1, NUM_TESTS1);

Here we cast the pointer constant into a pointer to an integer, which matches the declaration in the function. The constants for the dimensions of the array are passed to init_int_array() to be used for the calculation of the total number of elements in the array. Array Processing: Generalized Using a Function If all of the usable data is stored in the upper left corner of the array, it is a relatively simple matter to access the appropriate elements. The following call to get_highest() sends a casted pointer to the array, the number of columns in the array, and the bounds of the upper left corner where the data is.
high_test1 = get_highest( (int *)grades1, NUM_TESTS1, num_students1, num_tests1);

The code for the function which follows illustrates the power of pointers and offsets in the C language. While we may wish to view a list of items as a number of sub-lists, the items are stored in the computer in consecutive memory locations. We can use pointer arithmetic to convert our two-dimensional perception of reality to the linear view dictated by how RAM is utilized. The four arguments passed by the function call above are sufficient for this purpose. 1. The pointer constant grades1 provides the array's starting point in RAM.

2. NUM_TESTS1 provides the maximum number of possible items in the sub-list. 3. num_students1 provides the number of rows to be checked. 4. num_tests1 provides the number of columns to be checked. The following expression can be used to access an element of the array.
*(a + i*cols + j)

1. 2. 3. 4.

a, which remains constant, points at the zeroth element of the list. cols, which remains constant, is the number of columns in a row. i ranges from 0 to one less than the number of rows to be searched. j ranges from 0 to one less than the number of columns to be searched.

With a remaining constant, it can be seen that i*cols + j provides the offset from the beginning of the list. Here is a complete function which can be used to return the largest int in a portion of a two-dimensional array of any size.
int get_highest(int *a, int cols, int row, int col) /* Assumes that the elements with usable values are in the upper left corner of the array as delimited by row and col; cols is the number of columns in the array passed */ { int i, j; int highest = *a; for( i = 0; i < row; i++) for( j = 0; j < col; j++) if ( *(a + i*cols + j) > highest) highest = *(a + i*cols + j); return highest; }

Sample Program 2
This is a program which initializes parts of two arrays of integer grades at the time of their declaration, each with 6 values. Then it calls a function to find, return, and print the highest grade in each of the two arrays.
#include <stdio.h> #define #define #define #define NUM_STUDENTS1 25 NUM_TESTS1 10 NUM_STUDENTS2 15 NUM_TESTS2 8

int get_highest(int *a, int cols, int row, int col); int main() { int grades1[NUM_STUDENTS1][NUM_TESTS1] = { {55, 60, 65}, {85, 90, 95} }; int num_students1 = 2; int num_tests1 = 3; int high_test1; int grades2[NUM_STUDENTS2][NUM_TESTS2] = { {55, 60}, {85, 90}, {75, 70} }; int num_students2 = 3; int num_tests2 = 2; int high_test2; high_test1 = get_highest( (int *)grades1, NUM_TESTS1, num_students1, num_tests1); printf("The highest score in the first class is %d.\n", high_test1); high_test2 = get_highest( (int *)grades2, NUM_TESTS2, num_students2, num_tests2); printf("The highest score in the second class is %d.\n", high_test2); return 0; } int get_highest(int *a, int cols, int row, int col) /* Assumes that the elements with usable values are in the upper left corner of the array as delimited by row and col; cols is the number of columns in the array passed */ { int i, j; int highest = *a; for( i = 0; i < row; i++) for( j = 0; j < col; j++) if ( *(a + i*cols + j) > highest) highest = *(a + i*cols + j); return highest; }

Back to

main() { int i, j, car; int frequency[5][5] = { {0},{0},{0},{0},{0} }; char city; printf("For each person, enter the city code \n"); printf("followed by the car code.\n"); printf("Enter the letter X to indicate end.\n"); /*. . . . . . TABULATION BEGINS . . . . . */ for( i = 1 ; i < 100 ; i++ ) { scanf("%c", &city ); if( city == 'X' ) break; scanf("%d", &car ); switch(city) { case'B' : frequency[1][car]++; break; case'C' : frequency[2][car]++; break; case'D' : frequency[3][car]++; break; case'M' : frequency[4][car]++; break;

} } /*. . . . .TABULATION COMPLETED AND PRINTING BEGINS. . . .*/ printf("\n\n"); printf(" POPULARITY TABLE\n\n"); printf("-------------------------------------------\n"); printf("City Ambassador Fiat Dolphin Maruti \n"); printf("-------------------------------------------\n"); for( i = 1 ; i <= 4 ; i++ ) { switch(i) { case 1 : case 2 : case 3 : case 4 : printf("Bombay break ; printf("Calcutta break ; printf("Delhi break ; printf("Madras break ; ") ; ") ; ") ; ") ;

} for( j = 1 ; j <= 4 ; j++ ) printf("%7d", frequency[i][j] ) ; printf("\n") ; } printf("-------------------------------------------\n"); /*. . . . . . . . . PRINTING ENDS. . . . . . . . . . .*/ } Output For each person, enter the city code

followed by the car code. Enter the letter X to indicate end. M C D C D D 1 1 4 1 1 3 C D D C C M 2 3 4 1 2 4 B M M C B C 1 4 1 2 3 1 D B M M M D 3 2 1 4 1 2 M D B M B M 2 1 3 4 1 3 B C B C C B 4 3 3 2 2 4

POPULARITY TABLE ------------------------------------------City Ambassador Fiat Dolphin Maruti ------------------------------------------Bombay 2 1 3 2 Calcutta 4 5 1 0 Delhi 2 1 3 2 Madras 4 1 1 4 -------------------------------------------

S-ar putea să vă placă și