我是 C 語言的新手,試圖通過將指標傳遞給函式來乘以 2d 陣列。
程式在乘法函式內部時退出,只列印“我在函式中”。
如果我通過指標傳遞二維陣列是否正確,請告訴我?
我已經提到了一些警告和輸出
謝謝
#include <stdio.h>
int m, n; // rows and columns matrix 1
int x, y; // rows and columns matrix 2
void multiplication(int **arr, int **arr1)
{
printf("I am in function");
int result[m][y];
for (int i = 0; i < m; i )
{
for (int j = 0; j < n; j )
{
result[i][j] = (arr[i][j]) * (arr1[i][j]);
}
printf("calculating");
}
for (int i = 0; i < m; i )
{
for (int j = 0; i < n; j )
{
printf("printing");
printf("%d", result[i][j]);
printf("\t");
}
printf("\n");
}
}
int main()
{
printf("Enter the rows and column for matrix 1\n");
scanf("%d %d", &m, &n);
printf("Enter the rows and column for matrix 2\n");
scanf("%d %d", &x, &y);
if (n != x)
{
printf("Cant multiply matrix");
}
else if (n == x)
{
int a1[m][n], a2[x][y];
printf("Enter the value for matrix 1 \n\n");
for (int i = 0; i < m; i )
{
for (int j = 0; j < n; j )
{
scanf("%d", &a1[i][j]);
}
}
printf("Enter the value for matrix 2 \n\n");
for (int i = 0; i < x; i )
{
for (int j = 0; j < y; j )
{
scanf("%d", &a2[i][j]);
}
}
multiplication(a1, a2);
return 0;
}
}
一些警告:
matrixmult.c:59:24: warning: passing argument 1 of 'multiplication' from incompatible pointer type [-Wincompatible-pointer-types]
59 | multiplication(a1, a2);
| ^~
| |
| int (*)[n]
matrixmult.c:5:27: note: expected 'int **' but argument is of type 'int (*)[n]'
5 | void multiplication(int **arr, int **arr1)
| ~~~~~~^~~
matrixmult.c:59:28: warning: passing argument 2 of 'multiplication' from incompatible pointer type [-Wincompatible-pointer-types]
59 | multiplication(a1, a2);
| ^~
| |
| int (*)[y]
matrixmult.c:5:38: note: expected 'int **' but argument is of type 'int (*)[y]'
5 | void multiplication(int **arr, int **arr1)
| ~~~~
輸出:
Enter the rows and column for matrix 1
2
2
Enter the rows and column for matrix 2
2
2
Enter the value for matrix 1
1
2
1
2
Enter the value for matrix 2
1
2
1
2
I am in function
uj5u.com熱心網友回復:
- 避免全域變數。也就是說, 的宣告
x, y, m, n應該放在 main() 中,然后作為引數傳遞給函式。 - 指標對指標與二維陣列完全無關。
解決這些問題后,您的函式可能看起來像這樣:
void multiplication (int x, int y, int arr1[x][y], int arr2[x][y])
如果該函式不打算修改任一陣列,則自定義使用const 正確性宣告它:
void multiplication (int x, int y, const int arr1[x][y], const int arr2[x][y])
uj5u.com熱心網友回復:
您將陣列視為與指標相同。這不是真的。
您的陣列包含n*m存盤在記憶體中連續地址的整數。你告訴編譯器引數arr保存一個指向整數的指標的地址。這意味著,如果你寫arr[i][j]將取消參考你的指標并從記憶體中讀取一個也被取消參考的地址。這個地址實際上是int記憶體中的一個,而不是一個指標。取整數并用作地址會導致未定義的行為。
幸運的是,您的編譯器已經告訴您這些型別不匹配。它還提供了正確的論點型別。使用此資訊,您可以修復簽名:
void multiplication(int n, int y, int (*arr)[n], int (*arr1)[y])
或(受 Lundin 的回答啟發)
void multiplication(int x, int y, int z, int arr1[x][y], int arr2[y][z])
然后相應地更新您的函式呼叫。
此外,您的一個回圈中有一個錯字:
for (int j = 0; i < n; j )
那應該是j < n。
此外,回圈中的范圍不正確。您創建了 2 個不同維度的陣列。你只需要那個n==x。這意味著您的陣列被定義為int arr[x][y]and int arr1[y][z]。結果陣列也定義為int result[x][z].
沒有跡象表明x==y或y==z可能是真的。
然而,您對所有陣列使用相同的范圍:
result[i][j] = (arr[i][j]) * (arr1[i][j]);
這只有在所有范圍都相同時才有效。否則,您將要么越界訪問,要么不觸及所有元素。
用于矩陣乘法的正確版本應用演算法可能如下所示(未經測驗):
void multiplication(int x, int y, int z, int arr1[x][y], int arr2[y][z])
{
printf("I am in function");
int result[x][z];
printf("calculating");
for (int i = 0; i < x; i )
{
for (int j = 0; j < z; j )
{
int cell = 0;
for (int k = 0; k < y; k )
{
cell = arr1[i][k] * arr2[k][j];
}
result[i][j] = cell;
}
}
printf("printing");
for (int i = 0; i < x; i )
{
for (int j = 0; j < z; j )
{
printf("%d", result[i][j]);
printf("\t");
}
printf("\n");
}
}
uj5u.com熱心網友回復:
除了上面兩個很好的答案:
由于您是新手,
C因此可以完全避免使用指標,C因此對此有規定。將問題拆分為多個部分以供重復使用。定義一個函式來列印矩陣,如:
void matrix_print (const int rows, const int cols, const int mat[rows][cols]) {
for (int ri = 0; ri < rows; ri) {
for (int ci = 0; ci < cols; ci)
printf ("d ", mat[ri][ci]);
putchar ('\n'); // for pretty matrix print
}
}
正如@gerhardh & @lundin 所指出的,rows&cols應該在mat[rows][cols].
- 然后要讀取一個矩陣,您將擁有:注意,我們需要如何檢查回傳值
scanf()以檢測輸入中的錯誤。
#define ERR_INV_NUM_STR "ERROR: Invalid Number\n"
int matrix_read (const int rows, const int cols, int mat[rows][cols]) {
for (int ri = 0; ri < rows; ri) {
for (int ci = 0; ci < cols; ci)
if (1 != scanf("%d", &mat[ri][ci])) {
fputs (ERR_INV_NUM_STR, stderr);
return 1;
}
}
return 0;
}
- 如前所述,您的矩陣乘法邏輯是錯誤的。正確的方法是:
// Note: we've established 'acols = brows'
void matrix_multiply (const int arows, const int acols, int A[arows][acols],
const int bcols, const int B[acols][bcols], int C[arows][bcols]) {
for (int ri = 0; ri < arows; ri ) {
for (int ci = 0; ci < bcols; ci ) {
C[ri][ci] = 0;
for (int ki = 0; ki < acols; ki )
C[ri][ci] = A[ri][ki] * B[ki][ci];
}
}
}
- 然后總結一下,你的
main()變成:
int main() {
printf ("Enter the order of Matrix A (p x q):\n");
int arows, acols;
if (2 != scanf ("%d %d", &arows, &acols)) {
fputs (ERR_INV_NUM_STR, stderr);
return 1;
}
printf ("Enter the order of Matrix B (r x s):\n");
int brows, bcols;
if (2 != scanf ("%d %d", &brows, &bcols)) {
fputs (ERR_INV_NUM_STR, stderr);
return 2;
}
if (acols != brows) {
printf ("Cant multiply these matrices\n");
return 3;
}
int A[arows][acols]; // using VLA, nice
printf ("Enter the values for Matrix A:\n");
if (matrix_read (arows, acols, A)) {
printf ("ERROR: Reading Matrix A\n");
return 4;
}
int B[brows][bcols]; // using VLA, nice
printf ("Enter the values for Matrix B:\n");
if (matrix_read (brows, bcols, B)) {
printf ("ERROR: Reading Matrix B\n");
return 5;
}
int C[arows][bcols]; // A(p,q) * B(r,s) = C(p,s) when q = r
matrix_multiply (arows, acols, A, bcols, B, C);
printf ("\nMatrix A:\n");
matrix_print (arows, acols, A);
printf ("\nMatrix B:\n");
matrix_print (brows, bcols, B);
printf ("\nMatrix C: (A * B) \n");
matrix_print (arows, bcols, C);
return 0;
}
樣本測驗:
Enter the order of Matrix A (p x q):
1 5
Enter the order of Matrix B (r x s):
5 1
Enter the values for Matrix A:
1 2 3 4 5
Enter the values for Matrix B:
5 4 3 2 1
Matrix A:
1 2 3 4 5
Matrix B:
5
4
3
2
1
Matrix C: (A * B)
35
和
Enter the order of Matrix A (p x q):
5 1
Enter the order of Matrix B (r x s):
1 5
Enter the values for Matrix A:
1 2 3 4 5
Enter the values for Matrix B:
5 4 3 2 1
Matrix A:
1
2
3
4
5
Matrix B:
5 4 3 2 1
Matrix C: (A * B)
5 4 3 2 1
10 8 6 4 2
15 12 9 6 3
20 16 12 8 4
25 20 15 10 5
注意:編譯器const對陣列的限定符拋出警告:
warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic]
78 | matrix_print (arows, acols, A);
...
warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic]
75 | matrix_multiply (arows, acols, A, bcols, B, C);
GCC(GNU C 編譯器)尊重它,但 ISO C 標準沒有涵蓋它。SO - 在 C 和 C 中使用 const 限定符指向陣列的指標
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/465492.html
標籤:C
