Handling nXn matrices --------------------- // allocating the matrix int i,j,n; double **a; a = calloc(n,sizeof(double *)); for (i=0; i #include #include #include #include typedef double dbl; // could be substituted with other types void check_cmd_line(int argc, char **argv); void fill_matrix(dbl **a, int m, int n); dbl ** get_matrix_space(int m, int n); void release_matrix_space(dbl **a); dbl trace(dbl **a, int m, int n); void wrt_info(const char *pgm_name); void wrt_matrix(const char *s, dbl **a, int m, int n); ------------------------------------------------- // main.c #include "trace.h" int main(int argc, char **argv) { int m; /* number of rows */ int n; /* number of columns */ int val; dbl **a; /* matrix */ srand(time(NULL)); /* seed the random number generator */ check_cmd_line(argc, argv); printf("%s\n", "---\n" "This program creates space for an mxn matrix A, fills it with\n" "randomly distributed digits from -9 to +9, and then prints\n" "the matrix A and its trace.\n"); for ( ; ; ) { printf("Input m and n: "); val = scanf("%d%d", &m, &n); if (val != 2 || m < 1 || n < 1) break; putchar('\n'); a = get_matrix_space(m, n); fill_matrix(a, m, n); wrt_matrix("A", a, m, n); printf("trace(A) = %.1f\n\n", trace(a, m, n)); release_matrix_space(a); } printf("\nBye!\n\n"); return 0; } ------------------------------------------------- // check-cmd-line.c #include "trace.h" void check_cmd_line(int argc, char **argv) { if (argc > 1 && strcmp(argv[1], "-h") == 0) { wrt_info(argv[0]); exit(1); } if (argc > 1) { printf("\nERROR: No command line arguments needed.\n\n"); wrt_info(argv[0]); exit(1); } } ------------------------------------------------- // allocate-free.c #include "trace.h" dbl **get_matrix_space(int m, int n) { int i; dbl *p; dbl **a; p = malloc(m * n * sizeof(dbl)); /* get the space all at once */ a = malloc(m * sizeof(dbl *)); assert(p != NULL); assert(a != NULL); /* // Offset pointers to change the indexing. */ --a; /* index from 1, not 0 */ for (i = 1; i <= m; ++i) a[i] = p + ((i - 1) * n) - 1; /* index from 1, not 0 */ return a; } void release_matrix_space(dbl **a) { dbl *p; /* // The effects of offsetting the pointers // must be undone before releasing space. */ p = a[1] + 1; /* base address in memory */ free(p); free(a + 1); } ------------------------------------------------- // write.c #include "trace.h" void wrt_info(const char *pgm_name) { printf("%s%s%s\n", "---\n" "Usage: ", pgm_name, " [-h]\n" "\n" "This program creates space for an mxn matrix A, fills the matrix A\n" "with randomly distributed integers from -9 to +9, and then prints\n" "the matrix A along with the value of its trace.\n" "\n" "---\n" "Options:\n" " -h help option, print this message\n"); } void wrt_matrix(const char *s, dbl **a, int m, int n) { int i, j; printf("%s =\n", s); for (i = 1; i <= m; ++i) { for (j = 1; j <= n; ++j) printf("%6.1f", a[i][j]); putchar('\n'); } putchar('\n'); } ------------------------------------------------- // fill-matrix.c #include "trace.h" void fill_matrix(dbl **a, int m, int n) { int i, j; for (i = 1; i <= m; ++i) for (j = 1; j <= n; ++j) a[i][j] = rand() % 19 - 9; /* from -9 to +9 */ } ------------------------------------------------- // compute-trace.c #include "trace.h" dbl trace(dbl **a, int m, int n) { int i; int k; dbl sum = 0.0; k = (m < n) ? m : n; for (i = 1; i <= k; ++i) sum += a[i][i]; return sum; }