2-d Arrays
1
Two Dimensional Arrays
We have seen that an array variable can store
a list of values
Many applications require us to store a table
of values
Subject 1 Subject 2 Subject 3 Subject 4 Subject 5
Student 1 75 82 90 65 76
Student 2 68 75 80 70 72
Student 3
88 74 85 76 80
Student 4
50 65 68 40 70
2
Contd.
The table contains a total of 20 values, five
in each line
The table can be regarded as a matrix
consisting of four rows and five columns
C allows us to define such tables of items
by using two-dimensional arrays
3
Declaring 2-D Arrays
General form:
type array_name [row_size][column_size];
Examples:
int marks[4][5];
float sales[12][25];
double matrix[100][100];
4
Initializing 2-d arrays
int a[2][3] = {1,2,3,4,5,6};
int a[2][3] = {{1,2,3}, {4,5,6}};
int a[][3] = {{1,2,3}, {4,5,6}};
All of the above will give the 2x3 array
1 2 3
4 5 6
5
Accessing Elements of a 2-d
Array
Similar to that for 1-d array, but use two indices
First indicates row, second indicates column
Both the indices should be expressions which
evaluate to integer values (within range of the
sizes mentioned in the array declaration)
Examples:
x[m][n] = 0;
c[i][k] += a[i][j] * b[j][k];
a = sqrt (a[j*3][k]);
6
Example
int a[3][5];
A two-dimensional array of 15 elements
Can be looked upon as a table of 3 rows and 5 columns
col0 col1 col2 col3 col4
row0 a[0][0] a[0][1] a[0][2] a[0][3] a[0][4]
row1 a[1][0] a[1][1] a[1][2] a[1][3] a[1][4]
row2 a[2][0] a[2][1] a[2][2] a[2][3] a[2][4]
7
How is a 2-d array is stored in
memory?
Starting from a given memory location, the elements
are stored row-wise in consecutive memory locations
(row-major order)
x: starting address of the array in memory
c: number of columns
k: number of bytes allocated per array element
a[i][j] is allocated memory location at
address x + (i * c + j) * k
a[0]0] a[0][1] a[0]2] a[0][3] a[1][0] a[1][1] a[1][2] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3]
Row 0 Row 1 Row 2
8
Array Addresses Output
3221224480
int main() 3221224484
{ 3221224488
int a[3][5]; 3221224492
3221224496
int i,j;
3221224500
for (i=0; i<3;i++) 3221224504
3221224508
{ 3221224512
for (j=0; j<5; j++) printf("%u\n", &a[i][j]); 3221224516
printf("\n");
3221224520
} 3221224524
return 0; 3221224528
} 3221224532
3221224536
9
More on Array Addresses
int main()
{
int a[3][5];
printf("a = %u\n", a);
printf("&a[0][0] = %u\n", &a[0][0]); Output
printf("&a[2][3] = %u\n", &a[2][3]); a = 3221224480
printf("a[2]+3 = %u\n", a[2]+3); &a[0][0] = 3221224480
&a[2][3] = 3221224532
printf("*(a+2)+3 = %u\n", *(a+2)+3); a[2]+3 = 3221224532
printf("*(a+2) = %u\n", *(a+2)); *(a+2)+3 = 3221224532
printf("a[2] = %u\n", a[2]); *(a+2) = 3221224520
a[2] = 3221224520
printf("&a[2][0] = %u\n", &a[2][0]); &a[2][0] = 3221224520
printf("(a+2) = %u\n", (a+2)); (a+2) = 3221224520
printf("&a[2] = %u\n", &a[2]); &a[2] = 3221224520
return 0;
10
}
How to read the elements of a
2-d array?
By reading them one element at a time
for (i=0; i<nrow; i++)
for (j=0; j<ncol; j++)
scanf (“%f”, &a[i][j]);
The ampersand (&) is necessary
The elements can be entered all in one
line or in different lines
11
How to print the elements of a
2-d array?
By printing them one element at a time
for (i=0; i<nrow; i++)
for (j=0; j<ncol; j++)
printf (“\n %f”, a[i][j]);
The elements are printed one per line
for (i=0; i<nrow; i++)
for (j=0; j<ncol; j++)
printf (“%f”, a[i][j]);
The elements are all printed on the same line12
Contd.
for (i=0; i<nrow; i++)
{
printf (“\n”);
for (j=0; j<ncol; j++)
printf (“%f ”, a[i][j]);
}
The elements are printed nicely in matrix form
13
Example: Matrix Addition
int main()
{ for (p=0; p<m; p++)
int a[100][100], b[100][100], for (q=0; q<n; q++)
c[100][100], p, q, m, n; c[p][q] = a[p][q] + b[p][q];
scanf (“%d %d”, &m, &n); for (p=0; p<m; p++)
{
for (p=0; p<m; p++) printf (“\n”);
for (q=0; q<n; q++) for (q=0; q<n; q++)
scanf (“%d”, &a[p][q]);
printf (“%d ”, c[p][q]);
for (p=0; p<m; p++) }
for (q=0; q<n; q++) return 0;
scanf (“%d”, &b[p][q]); }
14
Passing 2-d Arrays as Parameters
Similar to that for 1-D arrays
The array contents are not copied into the function
Rather, the address of the first element is passed
For calculating the address of an element in a 2-d
array, we need:
The starting address of the array in memory
Number of bytes per element
Number of columns in the array
The above three pieces of information must be known
to the function
15
Example Usage
void add (int x[][25], int
y[][25], int rows, int cols)
int main() {
{ :
int a[15][25], b[15]25]; }
:
:
add (a, b, 15, 25);
:
} We can also write
int x[15][25], y[15][25];
But at least 2nd dimension
must be given
16
Dynamic Allocation of 2-d Arrays
Recall that address of [i][j]-th element is found
by first finding the address of first element of i-
th row, then adding j to it
Now think of a 2-d array of dimension [M][N]
as M 1-d arrays, each with N elements, such
that the starting address of the M arrays are
contiguous (so the starting address of k-th row
can be found by adding 1 to the starting
address of (k-1)-th row)
This is done by allocating an array p of M
pointers, the pointer p[k] to store the starting
address of the k-th row 17
Contd.
Now, allocate the M arrays, each of N
elements, with p[k] holding the pointer for
the k-th row array
Now p can be subscripted and used as a
2-d array
Address of p[i][j] = *(p+i) + j (note that
*(p+i) is a pointer itself, and p is a pointer
to a pointer)
18
Dynamic Allocation of 2-d Arrays
int **allocate (int h, int w)
{ void read_data (int **p, int h, int w)
int **p; Allocate array {
int i, j; of pointers int i, j;
for (i=0;i<h;i++)
p = (int **) malloc(h*sizeof (int *) ); for (j=0;j<w;j++)
for (i=0;i<h;i++) scanf ("%d", &p[i][j]);
p[i] = (int *) malloc(w * sizeof (int)); }
return(p);
} Allocate array of Elements accessed
integers for each like 2-D array elements.
row
19
Contd.
void print_data (int **p, int h, int w) int main()
{ {
int i, j; int **p;
for (i=0;i<h;i++) int M, N;
{ printf ("Give M and N \n");
for (j=0;j<w;j++) scanf ("%d%d", &M, &N);
printf ("%5d ", p[i][j]); p = allocate (M, N);
printf ("\n"); read_data (p, M, N);
} printf ("\nThe array read as \n");
} print_data (p, M, N);
return 0;
}
20
Contd.
void print_data (int **p, int h, int w) int main()
{ {
int i, j; int **p;
for (i=0;i<h;i++) int M, N;
{ printf ("Give M and N \n");
for (j=0;j<w;j++) scanf ("%d%d", &M, &N);
printf ("%5d ", p[i][j]); p = allocate (M, N);
printf ("\n"); read_data (p, M, N);
Give M and N
} 33 printf ("\nThe array read as \n");
} 123 print_data (p, M, N);
456 return 0;
789
}
The array read as
1 2 3
4 5 6
7 8 9
21
Memory Layout in Dynamic Allocation
int **allocate (int h, int w)
int main() {
{ int **p;
int **p; int i, j;
int M, N;
printf ("Give M and N \n"); p = (int **)malloc(h*sizeof (int *));
scanf ("%d%d", &M, &N); for (i=0; i<h; i++)
p = allocate (M, N); printf(“%10d”, &p[i]);
for (i=0;i<M;i++) { printf(“\n\n”);
for (j=0;j<N;j++) for (i=0;i<h;i++)
printf ("%10d", &p[i][j]); p[i] = (int *)malloc(w*sizeof(int));
printf(“\n”); return(p);
} }
return 0;
}
22
Output
Starting address of each
row, contiguous (pointers
33 are 8 bytes long)
31535120 31535128 31535136
31535152 31535156 31535160
Elements in each row
31535184 31535188 31535192 are contiguous
31535216 31535220 31535224
23