/*
 *  This file shows how to pass arbitrary size matrix to function.
 */
#include <stdio.h>

// Function that accepts arbitrary-size matrix
void printMatrix1(int *pmatrix, int rows, int cols);
void printMatrix2(int **ppmatrix, int rows, int cols);

int main(int argc, char *argv[])
{
	// matrix with pre-loaded values 
	int mat[3][4] = {
		{1, 2, 3, 4},
		{5, 6, 7, 8,},
		{9, 10, 11, 12},
	};

	printf("Addr of mat in main: %p\n", mat);
	printf("Addr of mat[0] in main: %p\n", mat[0]);
	printf("Addr of mat[1] in main: %p\n", mat[1]);
	printf("Addr of mat[2][3] in main: %p\n\n", &mat[2][3]);

	// print matrix 
	printMatrix1(mat, 3, 4);
	printMatrix2(mat, 3, 4);

	return 0;
}

void printMatrix1(int *pmatrix, int rows, int cols)
{
	int i=0, j=0;   // index variables

	printf("-----------printMatrix1---------\n"); 
        // Here, we will 'reconstruct' the original matrix dimensions
        // using a simple formula:
        //           pmatrix + cols*i + j
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
			printf("%d ", *(pmatrix + cols*i + j)); 
		printf("\n"); 
	}
	printf("\n"); 
	return;
}

void printMatrix2(int **ppmatrix, int rows, int cols)
{
	int i=0, j=0;   // index variables

	printf("-----------printMatrix2---------\n"); 

	// In the following printf functions, notice that ppmatrix[0] and 
	// ppmatrix[1] do not contain the same address as matrix[0] and 
	// matrix[1]. 
	//
	// Therefore, accessing the matrix using the normal matrix form 
	// (i.e. ppmatrix[2][1]) will not work. 
	printf("Addr of ppmatrix in printMatrix2: %p\n", ppmatrix);
	printf("Addr of ppmatrix[0] in printMatrix2: %p\n", ppmatrix[0]);
	printf("Addr of ppmatrix[1] in printMatrix2: %p\n", ppmatrix[1]);
	printf("Addr of ppmatrix[2][3] in printMatrix2: %p\n", &ppmatrix[2][3]);

	// We need to reconstruct the address of each row using pointer 
	// arithmetic   
	int *matrix_reloaded[rows];
	for (i = 0; i < rows; i++)
		matrix_reloaded[i] = (int*)ppmatrix + cols*i;

	// And then print matrix using the normal matrix form such as 
	// matrix_reloaded[i][j] below. 
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
			printf("%d ", matrix_reloaded[i][j]); 
		printf("\n"); 
	}
	printf("\n"); 
	return;
}
