Matrix in C

Overview

最近在看Data Stuctures Using C,在做Arrays的作业时涉及到 pass 2D array (matrix) in a function的问题,这里作下总结,参考这里.

Code

这里要实现在函数中传递二维数组有三种方法。

Use an array of arrays

相对来说,这种方法是最容易实现的,也是最好理解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

//
// Created by shensir on 18-1-8.
//

#include <stdio.h>

void readMatrix(int nrow, int ncol, int matrix[nrow][ncol]);
void showMatrix(int nrow, int ncol, int matrix[nrow][ncol]);

void addMatrix(int nrow, int ncol, int matrix1[nrow][ncol], int matrix2[nrow][ncol],
int matrix3[nrow][ncol]);

void mulMatrix(int nrow1, int ncol1, int nrow2, int ncol2,
int matrix1[nrow1][ncol1], int matrix2[nrow2][ncol2], int matrix3[nrow1][ncol2]);

void transMatrix(int nrow, int ncol, int matrix[nrow][ncol], int matrix3[ncol][nrow]);

// test data
// 1 3 5 7 9 1 2 3 4
// 2 4 6 8 0 1 2 3 4
int main(){
int nrow, ncol;
nrow = 3;
ncol = 3;
int matrix1[nrow][ncol];
int matrix2[nrow][ncol];
int matrix3[nrow][ncol];

readMatrix(nrow, ncol, matrix1);
showMatrix(nrow, ncol, matrix1);

readMatrix(nrow, ncol, matrix2);
showMatrix(nrow, ncol, matrix2);

printf("m1 + m2 = ");
addMatrix(nrow, ncol, matrix1, matrix2, matrix3);
showMatrix(nrow, ncol, matrix3);

printf("m1 X m2 = ");
mulMatrix(nrow, ncol, nrow, ncol, matrix1, matrix2, matrix3);
showMatrix(nrow, ncol, matrix3);

printf("transform matrix: ");
transMatrix(nrow, ncol, matrix1, matrix3);
showMatrix(ncol, nrow, matrix3);

return 0;
}

void readMatrix(int nrow, int ncol, int matrix[nrow][ncol]){
printf("Enter matrix data: ");
for (int i = 0; i < nrow; ++i) {
for (int j = 0; j < ncol; ++j) {
scanf("%d", &matrix[i][j]);
}
}
}

void showMatrix(int nrow, int ncol, int matrix[nrow][ncol]){
for (int i = 0; i < nrow; ++i) {
printf("\n");
for (int j = 0; j < ncol; ++j) {
printf("%4d ", matrix[i][j]);
}
}
printf("\n");
}


void addMatrix(int nrow, int ncol, int matrix1[nrow][ncol], int matrix2[nrow][ncol],
int matrix3[nrow][ncol]){
for (int i = 0; i < nrow; ++i) {
for (int j = 0; j < ncol; ++j) {
matrix3[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
}


void mulMatrix(int nrow1, int ncol1, int nrow2, int ncol2,
int matrix1[nrow1][ncol1], int matrix2[nrow2][ncol2], int matrix3[nrow1][ncol2]){
for (int i = 0; i < nrow1; ++i) {
for (int j = 0; j < ncol2; ++j) {
matrix3[i][j] = 0;
for (int k = 0; k < nrow1; ++k) {
matrix3[i][j] += matrix1[i][k] * matrix2[k][j];
}
}
}
}

void transMatrix(int nrow, int ncol, int matrix[nrow][ncol], int matrix3[ncol][nrow]){
for (int i = 0; i < nrow; ++i) {
for (int j = 0; j < ncol; ++j) {
matrix3[j][i] = matrix[i][j];
}
}
}

输出

Enter matrix data: 1 3 5 7 9 1 2 3 4

   1    3    5 
   7    9    1 
   2    3    4 
Enter matrix data: 2 4 6 8 0 1 2 3 4

   2    4    6 
   8    0    1 
   2    3    4 
m1 + m2 = 
   3    7   11 
  15    9    2 
   4    6    8 
m1 X m2 = 
  36   19   29 
  88   31   55 
  36   20   31 
transform matrix: 
   1    7    2 
   3    9    3 
   5    1    4 

Use an array of pointers to arrays

用二重指针实现二维数组也是差不多的,只不过当中涉及动态分配内存的问题。而这里又涉及到多次分配和释放内存的问题,所以定义了分配和释放内存的函数,然后就变成了三重指针,感觉可读性不如上面的好…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

#include <stdio.h>
#include <stdlib.h>

void allocateMemory(int ***pmatrix, int nrow, int ncol);
void freeMemory(int ***pmatrix, int nrow, int ncol);
void readMatrix(int **matrix, int nrow, int ncol);
void showMatrix(int **matrix, int nrow, int ncol);
void addMatrix(int **matrix1, int **matrix2, int **matrix3, int nrow, int ncol);
void mulMatrix(int **matrix1, int **matrix2, int **matrix3,
int nrow1, int ncol1, int nrow2, int ncol2);
void transMatrix(int **matrix, int **matrix3, int nrow, int ncol);

// test data
// 1 3 5 7 9 1 2 3 4
// 2 4 6 8 0 1 2 3 4


int main(){
int nrow = 3;
int ncol = 3;
int **matrix1;
int **matrix2;
int **matrix3;
allocateMemory(&matrix1, nrow, ncol);
allocateMemory(&matrix2, nrow, ncol);
allocateMemory(&matrix3, nrow, ncol);

readMatrix(matrix1, nrow, ncol);
showMatrix(matrix1, nrow, ncol);
readMatrix(matrix2, nrow, ncol);
showMatrix(matrix2, nrow, ncol);

printf("m1 + m2 = ");
addMatrix(matrix1, matrix2, matrix3, nrow, ncol);
showMatrix(matrix3, nrow, ncol);

printf("m1 X m2 = ");
mulMatrix(matrix1, matrix2, matrix3, nrow, ncol, nrow, ncol);
showMatrix(matrix3, nrow, ncol);

printf("transform matrix = ");
transMatrix(matrix1, matrix3, nrow, ncol);
showMatrix(matrix3, ncol, nrow);

freeMemory(&matrix1, nrow, ncol);
freeMemory(&matrix2, nrow, ncol);
freeMemory(&matrix3, nrow, ncol);

return 0;
}


void allocateMemory(int ***pmatrix, int nrow, int ncol){
*pmatrix = malloc(nrow * sizeof * *pmatrix);
for (int i = 0; i < nrow; ++i) {
(*pmatrix)[i] = malloc(ncol * sizeof * (*pmatrix)[i]);
}
}

void freeMemory(int ***pmatrix, int nrow, int ncol){
for (int j = 0; j < nrow; ++j) {
free((*pmatrix)[j]);
}
free(*pmatrix);
}

void readMatrix(int **matrix, int nrow, int ncol){
printf("Enter matrix data: ");
for (int i = 0; i < nrow; ++i) {
for (int j = 0; j < ncol; ++j) {
scanf("%d", *(matrix+i)+j);
}
}
}



void showMatrix(int **matrix, int nrow, int ncol){
for (int i = 0; i < nrow; ++i) {
printf("\n");
for (int j = 0; j < ncol; ++j) {
printf("%3d ", *(*(matrix + i) + j));
}
}
printf("\n");
}


void addMatrix(int **matrix1, int **matrix2, int**matrix3,
int nrow, int ncol){
for (int i = 0; i < nrow; ++i) {
for (int j = 0; j < ncol; ++j) {
matrix3[i][j] = matrix1[i][j]+matrix2[i][j];
}
}
}

void mulMatrix(int **matrix1, int **matrix2, int **matrix3,
int nrow1, int ncol1, int nrow2, int ncol2){
for (int i = 0; i < nrow1; ++i) {
for (int j = 0; j < ncol2; ++j) {
matrix3[i][j] = 0;
for (int k = 0; k < ncol1; ++k) {
matrix3[i][j] += matrix1[i][k] * matrix2[k][j];
}
}
}
}


void transMatrix(int **matrix, int **matrix3, int nrow, int ncol){
for (int i = 0; i < nrow; ++i) {
for (int j = 0; j < ncol; ++j) {
matrix3[j][i] = matrix[i][j];
}
}
}

输出:

Enter matrix data: 1 3 5 7 9 1 2 3 4

  1   3   5 
  7   9   1 
  2   3   4 
Enter matrix data: 2 4 6 8 0 1 2 3 4

  2   4   6 
  8   0   1 
  2   3   4 
m1 + m2 = 
  3   7  11 
 15   9   2 
  4   6   8 
m1 X m2 = 
 36  19  29 
 88  31  55 
 36  20  31 
transform matrix = 
  1   7   2 
  3   9   3 
  5   1   4 

Use a 1-dimensional array and fixup the indices

一开始还没有看到这种方法的特别之处,但是看前面两种方法就能看出。第一种是用的静态的数组,第二种是动态的数组,而且这两种方法,也只能对应选择静态和动态。而第三种却是两者都可以——This can be used with both statically allocated (fixed-size) and dynamically allocated arrays, 而本质上C considers a two-dimensional array as an array of one-dimensional arrays

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

#include <stdio.h>
#include <stdlib.h>

void readMatrix(int *array, int nrow, int ncol);

void showMatrix(int *array, int nrow, int ncol);

void addMatrix(int *array1, int *array2, int *array3, int nrow, int ncol);

void mulMatrix(int *array1, int *array2, int *array3,
int nrow1, int ncol1, int nrow2, int ncol2);

void transMatrix(int *array1, int *array3, int nrow, int ncol);

// test data
// 1 3 5 7 9 1 2 3 4
// 2 4 6 8 0 1 2 3 4

int main() {
int nrow, ncol;
nrow = 3;
ncol = 3;
int *array1;
int *array2;
int *array3;
// get memory
array1 = malloc(nrow * ncol * sizeof *array1);
array2 = malloc(nrow * ncol * sizeof *array2);
array3 = malloc(nrow * ncol * sizeof *array3);

readMatrix(array1, nrow, ncol);
showMatrix(array1, nrow, ncol);
readMatrix(array2, nrow, ncol);
showMatrix(array2, nrow, ncol);

printf("\nm1+m2: \n");
addMatrix(array1, array2, array3, nrow, ncol);
showMatrix(array3, nrow, ncol);

printf("\nm1xm2: \n");
mulMatrix(array1, array2, array3, nrow, ncol, nrow, ncol);
showMatrix(array3, nrow, ncol);

printf("\ntrans m1: \n");
transMatrix(array1, array3, nrow, ncol);
showMatrix(array3, ncol, nrow);

// free memory
free(array1);
free(array2);
free(array3);

}

void readMatrix(int *array, int nrow, int ncol) {
printf("Enter Matrix data: ");
for (int i = 0; i < nrow; ++i) {
for (int j = 0; j < ncol; ++j) {
scanf("%d", &array[i * ncol + j]);
}
}
}

void showMatrix(int *array, int nrow, int ncol) {
for (int i = 0; i < nrow; ++i) {
printf("\n");
for (int j = 0; j < ncol; ++j) {
printf("%3d", array[i * ncol + j]);
}
}
printf("\n");
}


void addMatrix(int *array1, int *array2, int *array3, int nrow, int ncol) {
for (int i = 0; i < nrow; ++i) {
for (int j = 0; j < ncol; ++j) {
array3[i * ncol + j] = array1[i * ncol + j] + array2[i * ncol + j];
}
}

}


void mulMatrix(int *array1, int *array2, int *array3,
int nrow1, int ncol1, int nrow2, int ncol2) {

for (int i = 0; i < nrow1; ++i) {
for (int j = 0; j < ncol2; ++j) {
array3[i * ncol2 + j] = 0;
for (int k = 0; k < ncol1; ++k) {
array3[i * ncol2 + j] += array1[i * ncol1 + k] * array2[k * ncol2 + j];
}
}
}

}


void transMatrix(int *array1, int *array3, int nrow, int ncol) {
for (int i = 0; i < nrow; ++i) {
for (int j = 0; j < ncol; ++j) {
array3[j * nrow + i] = array1[i * ncol + j];
}
}
}


输出:

Enter Matrix data: 1 3 5 7 9 1 2 3 4

  1  3  5
  7  9  1
  2  3  4
Enter Matrix data: 2 4 6 8 0 1 2 3 4

  2  4  6
  8  0  1
  2  3  4

m1+m2: 

  3  7 11
 15  9  2
  4  6  8

m1xm2: 

 36 19 29
 88 31 55
 36 20 31

trans m1: 

  1  7  2
  3  9  3
  5  1  4

本文标题:Matrix in C

文章作者:不秩稚童

发布时间:2018年01月08日 - 13:49:27

最后更新:2018年01月09日 - 09:47:37

原始链接:http://datahonor.com/2018/01/08/Matrix-in-C/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

击蒙御寇