简体   繁体   English

在 C 中使用指针乘以二次矩阵

[英]Multiplying Quadratic Matrices Using Pointers In C

I have a task where I'm supposed to multiply two quadratic matrices of size n in C, using pointers as function parameters and return value.我有一个任务,我应该在 C 中将两个大小为n二次矩阵相乘,使用指针作为函数参数和返回值。 This is the given function head: int** multiply(int** a, int** b, int n) .这是给定的函数头: int** multiply(int** a, int** b, int n) Normally, I would use three arrays (the two matrices and the result) as parameters, but since I had to do it this way, this is what I came up with:通常,我会使用三个数组(两个矩阵和结果)作为参数,但由于我必须这样做,这就是我想出的:

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

int** multiply(int** a, int** b, int n) {
  int **c = malloc(sizeof(int) * n * n);
  // Rows of c
  for (int i = 0; i < n; i++) {
    // Columns of c
    for (int j = 0; j < n; j++) {
      // c[i][j] = Row of a * Column of b
      for (int k = 0; i < n; k++) {
        *(*(c + i) + j) += *(*(a + i) + k) * *(*(b + k) + j);
      }
    }
  }
  return c;
}

int main() {
  int **a = malloc(sizeof(int) * 2 * 2);
  int **b = malloc(sizeof(int) * 2 * 2);

  for (int i = 0; i < 2; i++) {
    for (int j = 0; i < 2; j++) {
      *(*(a + i) + j) = i - j;
      *(*(b + i) + j) = j - i;
    }
  }
  
  int **c = multiply(a, b, 2);

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

  free(a);
  free(b);
  free(c);

  return 0;
}

I have not worked much with pointers before, and am generally new to C, so I have no idea why this doesn't work or what I'd have to do instead.我以前很少使用指针,而且通常是 C 的新手,所以我不知道为什么这不起作用或我必须做什么。 The error I'm getting when trying to run this program is segmentation fault (core dumped) .尝试运行此程序时遇到的错误是segmentation fault (core dumped) I don't even know exactly what that means... :(我什至不知道这到底是什么意思... :(

Can someone please help me out?有人可以帮我吗?

There's lots of fundamental problems in the code.代码中有很多基本问题。 Most notably, int** is not a 2D array and cannot point at one.最值得注意的是, int**不是二维数组,不能指向一个。

  • i<2 typo in the for(int j... loop. i<2 for(int j...循环中的错字。
  • i < n in the for(int k... loop. i < nfor(int k...循环中。
  • To allocate a 2D array you must do: int (*a)[2] = malloc(sizeof(int) * 2 * 2);要分配一个二维数组,你必须这样做: int (*a)[2] = malloc(sizeof(int) * 2 * 2); . . Or if you will malloc( sizeof(int[2][2]) ) , same thing.或者,如果您将malloc( sizeof(int[2][2]) ) ,同样的事情。
  • To access a 2D array you do a[i][j] .要访问二维数组,您可以执行a[i][j]
  • To pass a 2D array to a function you do void func (int n, int arr[n][n]);要将二维数组传递给函数,请执行void func (int n, int arr[n][n]);
  • Returning a 2D array from a function is trickier, easiest for now is just to use void* and get that working.从函数返回二维数组比较棘手,目前最简单的方法是使用void*并使其工作。
  • malloc doesn't initialize the allocated memory. malloc不会初始化分配的内存。 If you want to do += on c you should use calloc instead, to set everything to zero.如果你想在c上做+=你应该改用calloc ,把所有的东西都设置为零。
  • Don't write an unreadable mess like *(*(c + i) + j) .不要写像*(*(c + i) + j)这样难以理解的混乱。 Write c[i][j] .c[i][j]

I fixed these problems and got something that runs.我解决了这些问题并得到了一些可以运行的东西。 You check if the algorithm is correct from there.您从那里检查算法是否正确。

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

void* multiply(int n, int a[n][n], int b[n][n]) {
  int (*c)[n] = calloc(1, sizeof(int[n][n]));

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < n; k++) {
        c[i][j] += a[i][k] * b[k][j];
      }
    }
  }
  return c;
}

int main() {
  int (*a)[2] = malloc(sizeof(int[2][2]));
  int (*b)[2] = malloc(sizeof(int[2][2]));

  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
      a[i][j] = i - j;
      b[i][j] = j - i;
    }
  }
  
  int (*c)[2] = multiply(2, a, b);

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

  free(a);
  free(b);
  free(c);

  return 0;
}

You need to fix multiple errors here:您需要在这里修复多个错误:

1/ line 5/24/28: int **c = malloc(sizeof(int*) * n ) 1/ 行 5/24/28: int **c = malloc(sizeof(int*) * n )

2/ line 15: k<n 2/ 第 15 行: k<n

3/ Remark: use a[i][j] instead of *(*(a+i)+j) 3/ 备注:使用a[i][j]代替*(*(a+i)+j)

4/ line 34: j<2 4/ 第 34 行: j<2

5/ check how to create a 2d matrix using pointers. 5/ 检查如何使用指针创建二维矩阵。

#include <stdio.h>
#include <stdlib.h>
  
int** multiply(int** a, int** b, int n) {
  int **c = malloc(sizeof(int*) * n );
  for (int i=0;i<n;i++){
    c[i]=malloc(sizeof(int) * n );
  }
  
  // Rows of c
  for (int i = 0; i < n; i++) {
    // Columns of c
    for (int j = 0; j < n; j++) {
      // c[i][j] = Row of a * Column of b
      for (int k = 0; k < n; k++) {
    c[i][j] += a[i][k] * b[k][j];
      }
    }
  }
  return c;
}

int main() {
  int **a = malloc(sizeof(int*) * 2);
  for (int i=0;i<2;i++){
    a[i]=malloc(sizeof(int)*2);
  }
  int **b = malloc(sizeof(int) * 2);
  for (int i=0;i<2;i++){
    b[i]=malloc(sizeof(int)*2);
  }

  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
      a[i][j] = i - j;
      b[i][j] = i - j;
    }
  }

  int **c = multiply(a, b, 2); 

  for (int i = 0; i < 2; i++) { 
    for (int j = 0; j < 2; j++) { 
      printf("c[%d][%d] = %d\n", i, j, c[i][j]); 
    } 
  } 
  free(a);
  free(b);
  free(c);
  return 0;
}

From the updated requirement, the actual function prototype is int *multiply(int *a, int *b, int n);从更新的需求来看,实际的函数原型是int *multiply(int *a, int *b, int n); so the code should use a "flattened" matrix representation consisting of a 1-D array of length n * n .所以代码应该使用由长度为n * n的一维数组组成的“扁平化”矩阵表示。

Using a flattened representation, element ( i , j ) of the n * n matrix m is accessed as m[i * n + j] or equivalently using the unary * operator as *(m + i * n + j) .使用扁平化表示, n * n矩阵m元素 ( i , j ) 被访问为m[i * n + j]或等效地使用一元*运算符作为*(m + i * n + j) (I think the array indexing operators are more readable.) (我认为数组索引运算符更具可读性。)

First, let us fix some errors in the for loop variables.首先,让我们修复for循环变量中的一些错误。 In multiply :multiply

      for (int k = 0; i < n; k++) {

should be:应该:

      for (int k = 0; k < n; k++) {

In main :main

    for (int j = 0; i < 2; j++) {

should be:应该:

    for (int j = 0; j < 2; j++) {

The original code has a loop that sums the terms for each element of the resulting matrix c , but is missing the initialization of the element to 0 before the summation.原始代码有一个循环,它对结果矩阵c每个元素的项求和,但在求和之前缺少元素初始化为 0。

Corrected code, using the updated prototype with flattened matrix representation:更正代码,使用具有扁平矩阵表示的更新原型:

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

int* multiply(int* a, int* b, int n) {
  int *c = malloc(sizeof(int) * n * n);
  // Rows of c
  for (int i = 0; i < n; i++) {
    // Columns of c
    for (int j = 0; j < n; j++) {
      // c[i][j] = Row of a * Column of b
      c[i * n + j] = 0;
      for (int k = 0; k < n; k++) {
        c[i * n + j] += a[i * n + k] * b[k * n + j];
      }
    }
  }
  return c;
}

int main() {
  int *a = malloc(sizeof(int) * 2 * 2);
  int *b = malloc(sizeof(int) * 2 * 2);

  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
      a[i * 2 + j] = i - j;
      b[i * 2 + j] = j - i;
    }
  }
  
  int *c = multiply(a, b, 2);

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

  free(a);
  free(b);
  free(c);

  return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM