4/1/14
2D Arrays
int A[m][n];
The number of bytes: m*n*sizeof(int).
2D Arrays and #define n 2
Double Pointers #define m 3
int A[n][m];
int A[2][3]={{1,2,3},{4,5,6}};
Bryn Mawr College
CS246 Programming Paradigm For 1D array, to access array elements:
A[i]
*(A+i)
Access 2D Arrays Using Array Name Access 2D Arrays Using Array Name
int A[m][n]; int A[m][n];
We can think of A dereference of A : *A
A[0] as the address of row 0, the address of row 0 or A[0]
A[1] as the address of row 1
A[0] is an int*
In general: A[i][j] = *(A[i] + j) = *(*(A+i)+j)
A dereference of A[0] : *A[0]
Example: A[0][2] = *(A[0] + 2)
the first element of row 0 or A[0][0]
o Note that: A[0] = *A
**A = A[0][0] is an int
Hence, if A is a 2D int array, we can think of A as a
pointer to a pointer to an integer. That is, int**
Array Equation Types
int A[4][3]; Different types:
&A: address of the entire array of arrays of ints, i.e int[m][n]
A00 A01 A02 A10 A11 A12 A20 A21 A22 A30 A31 A32
&A[0]: same as A, address of the first element, i.e., int[n]
A==A[0] A[1] A[2] A[3]
&A[0][0]: address of the first element of the first element,
i.e., int.
For an int array A[m][n]: A: int (*)[n]
address(A[i][j]) = address(A[0][0]) + (i n + j) size(int) *A: int *
An array is treated as a pointer that points to the first
A[i] is equivalent to *(A+i) element of the array.
&A[i][0] = &(*(A[i]+0)) = &*A[i] = A[i] 2D array is NOT equivalent to a double pointer!
2D array is "equivalent" to a "pointer to row".
1
4/1/14
Double Pointer and 2D Array Pointers as Arguments
int A[m][n], *ptr1, **ptr2; WRONG
All arguments in C functions are passed by value.
ptr2 = &ptr1; To change the value of a variable passed to a
ptr1 = (int *)A; function, the variables address must be given to the
The information on the array "width" (n) is lost. function.
A possible way to make a double pointer work with a int foo (int* ptr){
2D array notation:
o use an auxiliary array of pointers, }
o each of them points to a row of the original matrix. The function foo can be called as foo(&x).
int A[m][n], *aux[m], **ptr2; The function foo changes the value of x by
ptr2 = (int **)aux; dereferenceing x.
for (i = 0 ; i < m ; i++) aux[i] = (int *)A+ i * n;
Pointers as Arguments Passing a 2D Array to a Function
int main()
int allocate(int* A, int n){ {
int A[3][3],i,j;
if ((A=malloc(n*sizeof(int))) != NULL)
for(i = 0 ; i < 3 ; i++)
return 0; for(j = 0 ; j < 3 ; j++)
A[i][j] = i*10 + j;
return 1;
} printf(" Initialized data to: ");
for(i = 0 ; i < 3 ; i++) {
int* ptr; printf("\n");
for(j = 0 ; j < 3 ; j++)
if (allocate(ptr,10)! = 1) printf("%4.2d", A[i][j]);
}
do_something; printf("\n");
f1(A);
f2(A);
f3(A);
f4(A);
f5(A);
}
Passing a 2D Array to a Function Passing a 2D Array to a Function
Declare as matrix, explicitly specify second dimension A pointer to array, second dimension is explicitly
You don't have to specify the first dimension! specified
void f1(int A[][3]) { void f2(int (*A)[3]) {
int i, j; int i, j;
for(i = 0 ; i < 3 ; i++) { for(i = 0 ; i < 3 ; i++) {
printf("\n"); printf("\n");
for(j = 0 ; j < 3 ; j++) for(j = 0 ; j < 3 ; j++)
printf("%4.2d", A[i][j]); printf("%4.2d", A[i][j]);
} }
printf("\n"); printf("\n");
} }
2
4/1/14
Passing a 2D Array to a Function Passing a 2D Array to a Function
Using a single pointer, the array is "flattened" A double pointer, using an auxiliary array of pointers
Add the dimensions to the formal argument list if you
void f3(int *A) {
int i, j; allocate "index" at run-time.
for(i = 0 ; i < 3 ; i++) { void f4(int **A) {
printf("\n"); int i, j, *index[3];
for(j = 0 ; j < 3 ; j++) for (i = 0 ; i < 3 ; i++)
index[i] = (int *)A + 3*i;
printf("%4.2d", *(A+ 3*i + j));
for(i = 0 ; i < 3 ; i++) {
}
printf("\n");
printf("\n");
for(j = 0 ; j < 3 ; j++)
}
printf("%4.2d", index[i][j]);
}
printf("\n");
}
Passing a 2D Array to a Function Protecting Pointers
A single pointer, using an auxiliary array of pointers int foo(const int* ptr){
/* *ptr cannot be changed */
void f5(int *A[3]) { }
int i, j, *index[3];
for (i = 0 ; i < 3 ; i++)
index[i] = (int *)A + 3*i; int foo(int* const ptr){
for(i = 0 ; i < 3 ; i++) { /* ptr cannot be changed */
printf("\n"); }
for(j = 0 ; j < 3 ; j++)
printf("%4.2d", index[i][j]);
} int foo(const int* const ptr){
printf("\n");
/* neither ptr nor *ptr cannot be changed */
}
}
Exercise
Write a function that int foo(char* filename, int A[], int* countptr){
takes FILE* fp=NULL;
int num=0;
o the name of a file (char*) that contains ints, if ((fp=fopen(filename, r)) != NULL){
o an array of ints while (fscanf(fp, %d,&num)>0) {
o the address of a variable count A[*countptr]= num;
*countptr += 1;
reads the file into the array. } return 0;
Assume that the array has enough space to hold the file. } else
count should be updated to the number of entries in return 1;
the file. }
3
4/1/14
Consider the following declaration.
int** matrix;
Write a function matrixAllocate that
takes two integers, m and n and
allocate an m by n block of memory.
int matrixAllocate(int*** Mptr, int n, int m){
*Mptr = (int**)malloc(m*sizeof(int*));
int i=0;
for (i=0; i<m; i++)
(*Mptr)[i] = malloc(n*sizeof(int));
}