在C语言中使用双指针传递到函数中的矩阵乘法

z31licg0  于 2022-12-11  发布在  其他
关注(0)|答案(1)|浏览(108)

我想知道为什么我不能得到函数中的值,它总是导致分段错误...'

void multiply(int M, int N, int K, int **matrixA, int **matrixB, int **matrixC){
    for (int i = 0; i < M; i++){
        for (int j = 0; j < K; j++){
            int sum = 0;
            for (int k = 0; k < N; k++){
                sum += (*(*(matrixA + j) + k)) * (*(*(matrixB + k) + j));
            }
            *(*(matrixC + i) + j) = sum;
        }
    }
    
}

int main(){
    int M, N, K;
    scanf("%d%d%d", &M, &N, &K);
    int matrixA[M][N];
    int matrixB[N][K];
    int matrixC[M][K];
    for(int i=0; i<M; i++){
        for(int j=0; j<N; j++){
            scanf("%d", matrixA[i]+j);
        }
    }

    for(int i=0; i<N; i++){
        for(int j=0; j<K; j++){
            scanf("%d", matrixB[i]+j);
        }
    }

    multiply(M, N, K, (int **)matrixA, (int **)matrixB, (int **)matrixC);
    for(int i=0; i<M; i++){
        for(int j=0; j<K; j++){
            printf("%d ", matrixC[i][j]);
        }
        printf("\n");
    }
    return 0;
}

`
我想打印出结果“matrixC”,但是在函数中,这会导致分段错误。我试了几次,似乎会错过双指针下的指针地址。

iszxjhcz

iszxjhcz1#

将函数multiply的原型更改为:

void multiply(int M, int N, int K, int matrixA[M][N], int matrixB[N][K], int matrixC[M][K]);

让你的生活变得更简单,就像这样(函数体倍增):

for (int i = 0; i < M; i++) { //for each row of matrixA
    for (int j = 0; j < K; j++) { //for each column of matrixB
        matrixC[i][j] = 0; //set field to zero
        for (int k = 0; k < N; k++) { //for each col of A and each row of B
            //take the dot product of row i (matrixA) and col j (matrixB)
            matrixC[i][j] += matrixA[i][k] * matrixB[k][j];
        }
    }
}

此行有错误

sum += (*(*(matrixA + j) + k)) * (*(*(matrixB + k) + j));

其已被校正为

matrixA[i][k] //index 'i' not 'j'

不需要var sum,因此选择退出。

基于您在下面的评论

请考虑以下代码:

int arr[2][2];
int n=0;

for (int i=0; i < 2; ++i) {
    for (int j=0; j < 2; ++j) {
        arr[i][j] = ++n;
        printf("%p (%d)  ", &arr[i][j], arr[i][j]);
    }
    printf("\n");
}

可能的输出:

0x7fff7c729470 (1)  0x7fff7c729474 (2)  
0x7fff7c729478 (3)  0x7fff7c72947c (4)

正如你所看到的,很好地打包成连续的整数(基本上是一个整数数组--但这并不保证)。
现在看看这个:

int **parr = (int**) arr;

for (int i=0; i < 2; ++i) {
    for (int j=0; j < 2; ++j) {
        printf("%p ", *(parr + i) + j);
    }
    printf("\n");
}

可能的输出:

0x200000001 0x200000005 
0x400000003 0x400000007

现在,这看起来(危险地)丑陋。
指针指向指针意味着另一个地址的地址,而数组是一个连续的类型块(例如,你可以取第一个元素的地址,如果数组衰减为指针,就可以这样做)。
您必须为编译器提供足够的信息,例如:

int (*parr)[2] = arr;

另请参阅:https://en.cppreference.com/w/c/language/array#Multidimensional_arrays

相关问题