void function(a, m, n) { int m, n; double a[m][n]; . . .are illegal (unlike in FORTRAN 77, where variable size matrix declarations are perfectly acceptable). Indeed, this unfortunate (and quite unnecessary!) omission in the C language definition is often put forward as a reason why C should not be used for scientific purposes. Fortunately, we can get around the absence of variable size multi-dimensional arrays in C by making use of a freely available C++ package called the Blitz++ library--see http://www.oonumerics.org/blitz/.
The program listed below illustrates the use of the Blitz++ library. The program adds together two matrices whose dimensions and elements are input by the user, and then prints out the result.
/* addmatrix.c */ /* Program to add two variable dimension matrices input by user */ #include <stdio.h> #include <stdlib.h> #include <blitz/array.h> using namespace blitz; /* Function prototypes */ void readin(Array<double,2>); void writeout(Array<double,2>); void addmatrices(Array<double,2>, Array<double,2>, Array<double,2>); int main() { int n, m; /* Input number of rows and columns */ printf("\nPlease input number of rows, n, and number of columns, m: "); scanf("%d %d", &n, &m); /* Check that n, m are positive integers */ if (n <= 0 || m <= 0) { printf("\nError: invalid values for n and/or m\n"); exit(1); } /* Array declarations */ Array<double,2> A(n, m), B(n, m), C(n, m); /* Read in elements of A, row by row */ printf("\nReading in elements of A:\n"); readin(A); /* Read in elements of B, row by row */ printf("\nReading in elements of B:\n"); readin(B); /* Write out elements of A, row by row */ printf("\nWriting out elements of A:\n"); writeout(A); /* Write out elements of B, row by row */ printf("\n\nWriting out elements of B:\n"); writeout(B); /* Add matrices A and B */ addmatrices(A, B, C); /* Write out matrix C = A + B, row by row */ printf("\n\nWriting out elements of C = A + B:\n"); writeout(C); printf("\n"); return 0; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /* Read in elements of matrix M, row by row */ void readin(Array<double,2> M) { int n = M.extent(0); int m = M.extent(1); for (int i = 0; i < n; i++) { printf("\nRow %d: ", i + 1); for (int j = 0; j < m; j++) scanf("%lf", &M(i, j)); } return; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /* Write out elements of matrix M, row by row */ void writeout(Array<double,2> M) { int n = M.extent(0); int m = M.extent(1); for (int i = 0; i < n; i++) { printf("\nRow %d: ", i + 1); for (int j = 0; j < m; j++) printf("%7.2f ", M(i, j)); } return; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /* Add matrices M and N and store result in matrix P */ void addmatrices(Array<double,2> M, Array<double,2> N, Array<double,2> P) { int n = M.extent(0); int m = M.extent(1); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) P(i, j) = M(i, j) + N(i, j); return; }Typical output from the program looks like
Please input number of rows, n, and number of columns, m: 3 3 Reading in elements of A: Row 1: 1 4 5 Row 2: 6 7 8 Row 3: 3 6 0 Reading in elements of B: Row 1: 1 6 0 Row 2: 4 7 8 Row 3: 4 8 8 Writing out elements of A: Row 1: 1.00 4.00 5.00 Row 2: 6.00 7.00 8.00 Row 3: 3.00 6.00 0.00 Writing out elements of B: Row 1: 1.00 6.00 0.00 Row 2: 4.00 7.00 8.00 Row 3: 4.00 8.00 8.00 Writing out elements of C = A + B: Row 1: 2.00 10.00 5.00 Row 2: 10.00 14.00 16.00 Row 3: 7.00 14.00 8.00The header file for the Blitz++ library is called blitz/array.h. Moreover, any program file which makes use of Blitz++ must include the cryptic line using namespace blitz; before the first call, otherwise compilation errors will ensue. The declaration Array<double,2> A(n, m) declares a two-dimensional n by m array of doubles. The generalization to an array of integers, or a higher dimension array, is fairly obvious. Note that the i, j element of matrix A is refered to simply as A(i,j). The function call M.extent(0) returns the size of array M in its first dimension. Likewise, M.extent(1) returns the size of array M in its second dimension, etc. More details of the operation of Blitz++ can be found by reading the extensive documentation which accompanies this library. Unfortunately, the Blitz++ library slows down compilation considerably since it makes use of some very advanced templating features of the C++ language.