Reputation: 1175
I am trying to check whether two matrix are equal via function. But I am confused how to write argument for the function EqualMatrices
. Since the logic is to compare equality or rows and columns how to pass such array in function argument.
#include <stdio.h>
void EqualMatrices(int A[][10], int B[][10]) // how to write arguments for this function
{
/* Comparing two matrices for equality: this is the logic */
if (row1 == row2 && column1 == column2)
{
printf("Matrices can be compared \n");
for (i = 0; i < row1; i++)
{
for (j = 0; j < column2; j++)
{
if (a[i][j] != b[i][j])
{
flag = 0;
break;
}
}
}
}
else
{
printf(" Cannot be compared\n");
exit(1);
}
if (flag == 1)
printf("Two matrices are equal \n");
else
printf("But, two matrices are not equal \n");
}
void main()
{
int a[10][10], b[10][10];
int i, j, row1, column1, row2, column2, flag = 1;
printf("Enter the order of the matrix A \n");
scanf("%d %d", &row1, &column1);
printf("Enter the order of the matrix B \n");
scanf("%d %d", &row2, &column2);
printf("Enter the elements of matrix a \n");
for (i = 0; i < row1; i++)
{
for (j = 0; j < column1; j++)
{
scanf("%d", &a[i][j]);
}
}
printf("Enter the elements of matrix b \n");
for (i = 0; i < row2; i++)
{
for (j = 0; j < column2; j++)
{
scanf("%d", &b[i][j]);
}
}
printf("MATRIX a is \n");
for (i = 0; i < row1; i++)
{
for (j = 0; j < column1; j++)
{
printf("%d", a[i][j]);
}
printf("\n");
}
printf("MATRIX b is \n");
for (i = 0; i < row2; i++)
{
for (j = 0; j < column2; j++)
{
printf("%d", b[i][j]);
}
printf("\n");
}
EqualMatrices(a, b);
return 0;
}
Upvotes: 0
Views: 511
Reputation: 2180
Hope this will work. I have done this without using pointer.
#include <stdio.h>
void EqualMatrices(int A[][10], int B[][10], int row1, int column1, int row2, int column2)
{
/* Comparing two matrices for equality */
int i,j, flag = 1;
if (row1 == row2 && column1 == column2)
{
printf("Matrices can be compared \n");
for (i = 0; i < row1; i++)
{
for (j = 0; j < column2; j++)
{
if (A[i][j] != B[i][j])
{
flag = 0;
break;
}
}
}
}
else
{
printf("\n Cannot be compared\n");
exit(1);
}
if (flag == 1)
{
printf("\n Two matrices are equal \n");
}
else
{
printf("\n Two matrices are not equal \n");
}
}
int main()
{
int a[10][10], b[10][10];
int i, j, row1, column1, row2, column2;
printf ("Enter the order of the matrix A (mxn):\n");
printf ("Row of matrix (mxn): ");
scanf ("%d", &row1);
printf ("Column of matrix (mxn): ");
scanf ("%d", &column1);
printf ("Enter the order of the matrix B (mxn):\n");
printf ("Row of matrix (mxn): ");
scanf ("%d", &row2);
printf ("Column of matrix (mxn): ");
scanf ("%d", &column2);
printf("Enter the elements of matrix a \n");
for (i = 0; i < row1; i++)
{
for (j = 0; j < column1; j++)
{
printf("Enter a[%d][%d]: ",i,j);
scanf("%d", &a[i][j]);
}
}
printf("Enter the elements of matrix b \n");
for (i = 0; i < row2; i++)
{
for (j = 0; j < column2; j++)
{
printf("Enter b[%d][%d]: ",i,j);
scanf("%d", &b[i][j]);
}
}
printf("\n MATRIX a is \n");
for (i = 0; i < row1; i++)
{
printf("\n");
for (j = 0; j < column1; j++)
{
printf("%d\t", a[i][j]);
}
}
printf("\n MATRIX b is \n");
for (i = 0; i < row2; i++)
{
printf("\n");
for (j = 0; j < column2; j++)
{
printf("%d\t", b[i][j]);
}
printf("\n");
}
EqualMatrices(a, b, row1, column1, row2, column2);
return 0;
}
Upvotes: 1
Reputation: 794
The question is related to more general ones that have been answered there: How are multi-dimensional arrays formatted in memory? / How to pass a 2D array by pointer in C?
Here, an attempt to create simple matrix comparison functions, that illustrate how plain arrays can be used directly:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
/* VARIANT 0: compare elements of arrays in a nested loop
-> no obvious advantages over VARIANT 1 */
bool matrix_equal0(
const int *a, const int *b, unsigned int rows, unsigned int columns)
{
for (unsigned int i = 0; i < rows; i++) {
for (unsigned int j = 0; j < columns; j++) {
if (a[i * columns + j] != b[i * columns + j]) {
return false;
}
}
}
return true;
}
/* VARIANT 1: compare elements of matrices one by one,
simpler and more performant than VARIANT 0 */
bool matrix_equal1(
const int *a, const int *b, unsigned int rows, unsigned int columns)
{
unsigned int i = rows * columns;
while (i--) {
if (*a++ != *b++) {
return false;
}
}
return true;
}
/* VARIANT 2:
compare both arrays as a chunk of memory (possible but not recommended) */
bool matrix_equal2(
const int *a, const int *b, unsigned int rows, unsigned int columns)
{
return (memcmp(a, b, rows * columns * sizeof(int)) == 0);
}
int main(void)
{
const int mat0[3][3] = {
{ 1, 2, 3, },
{ 4, 5, 6, },
{ 7, 8, 9, },
};
const int mat1[3][3] = {
{ 1, 2, 3, },
{ 4, 5, 6, },
{ 7, 8, 9, },
};
const int mat2[3][3] = {
{ 1, 2, 3, },
{ 4, 5, 6, },
{ 7, 8, 9999, },
};
if (matrix_equal0(&mat0[0][0], &mat1[0][0], 3, 3)) {
printf("VARIANT 0: mat0 and mat1 are equal!\n");
}
if (matrix_equal0(&mat0[0][0], &mat2[0][0], 3, 3) == false) {
printf("VARIANT 0: mat0 and mat2 are NOT equal!\n");
}
if (matrix_equal1(&mat0[0][0], &mat1[0][0], 3, 3)) {
printf("VARIANT 1: mat0 and mat1 are equal!\n");
}
if (matrix_equal1(&mat0[0][0], &mat2[0][0], 3, 3) == false) {
printf("VARIANT 1: mat0 and mat2 are NOT equal!\n");
}
if (matrix_equal2(&mat0[0][0], &mat1[0][0], 3, 3)) {
printf("VARIANT 2: mat0 and mat1 are equal!\n");
}
if (matrix_equal2(&mat0[0][0], &mat2[0][0], 3, 3) == false) {
printf("VARIANT 2: mat0 and mat2 are NOT equal!\n");
}
return 0;
}
Output:
VARIANT 0: mat0 and mat1 are equal!
VARIANT 0: mat0 and mat2 are NOT equal!
VARIANT 1: mat0 and mat1 are equal!
VARIANT 1: mat0 and mat2 are NOT equal!
VARIANT 2: mat0 and mat1 are equal!
VARIANT 2: mat0 and mat2 are NOT equal!
NOTE: Caution should be taken when 2D matrices are treated as plain arrays. How the columns and rows relate to the 1D memory layout of the array can be a source of confusion and cause bugs. - Here a quick example, that illustrates the relationship:
#include <stdio.h>
/* print the elements of a 2D matrix */
void matrix_print(const int *mat, unsigned int rows, unsigned int columns)
{
for (unsigned int i = 0; i < rows; i++) {
for (unsigned int j = 0; j < columns; j++) {
printf("%d ", mat[i * columns + j]);
}
printf("\n");
}
printf("\n");
}
int main(void)
{
const int mat[2][3] = {
{ 1, 2, 3, },
{ 4, 5, 6, },
};
matrix_print(&mat[0][0], 2, 3);
return 0;
}
Output:
1 2 3
4 5 6
If your project requires lots of matrix math, it might make sense to use a custom type to make them easier to handle and to build up a library-esque set of utility functions. - Here an example that illustrates how a compare function might look like in that case:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
/* VARIANT 3: instead of using a 2D array to represent a matrix,
a custom type is used. That makes it easier/nicer to pass
matrices around various places in your code. */
typedef struct {
unsigned int rows;
unsigned int columns;
int *elements;
} matrix;
matrix matrix_new(unsigned int rows, unsigned int columns)
{
matrix mat;
mat.rows = rows;
mat.columns = columns;
mat.elements = calloc(rows * columns, sizeof(int)); /* zero matrix */
return mat;
}
bool matrix_clear(matrix *mat)
{
if (mat == NULL)
return false;
mat->rows = 0;
mat->columns = 0;
free(mat->elements);
mat->elements = NULL;
return true;
}
bool matrix_elem(matrix *mat, unsigned int row, unsigned int column, int val)
{
if (mat == NULL)
return false;
if (row >= mat->rows || column >= mat->columns)
return false;
if (mat->elements == NULL)
return false;
mat->elements[row * mat->columns + column] = val;
return true;
}
bool matrix_compare(const matrix *mat0, const matrix *mat1)
{
if (mat0 == NULL || mat1 == NULL)
return false;
if (mat0->rows != mat1->rows)
return false;
if (mat0->columns != mat1->columns)
return false;
int *a = mat0->elements;
int *b = mat1->elements;
unsigned int i = mat0->rows * mat0->columns;
while (i--) {
if (*a++ != *b++) {
return false;
}
}
return true;
}
int main(void)
{
matrix mat3 = matrix_new(3, 3);
matrix mat4 = matrix_new(3, 3);
matrix mat5 = matrix_new(3, 3);
matrix_elem(&mat3, 1, 1, 12);
matrix_elem(&mat4, 1, 1, 12);
matrix_elem(&mat5, 1, 1, 13);
//matrix_copy_from_2d_array(&mat6, mat0); // todo
if (matrix_compare(&mat3, &mat4)) {
printf("VARIANT 3: mat3 and mat4 are equal!\n");
}
if (matrix_compare(&mat3, &mat5) == false) {
printf("VARIANT 3: mat3 and mat5 are NOT equal!\n");
}
matrix_clear(&mat3);
matrix_clear(&mat4);
matrix_clear(&mat5);
return 0;
}
Output:
VARIANT 3: mat3 and mat4 are equal!
VARIANT 3: mat3 and mat5 are NOT equal!
Upvotes: 0