你能用C语言把两个二维数组相乘吗?

你能用C语言把两个二维数组相乘吗?,c,C,我有两个像这样的2D数组,inta[3][3]和intb[3][3],我必须将它们相乘。我可以这样做吗?创建一个函数并将它们发送到它?我知道我可以,但这就是二维数组的乘法吗 void mult(int *C,int *A,int *B){ for(int i = 0;i<9;i++){ *C = (*A) * (*B); C++; A++; B++; } } void mult(int*C,int*A,int

我有两个像这样的2D数组,
inta[3][3]
intb[3][3]
,我必须将它们相乘。我可以这样做吗?创建一个函数并将它们发送到它?我知道我可以,但这就是二维数组的乘法吗

void mult(int *C,int *A,int *B){
    for(int i = 0;i<9;i++){
        *C = (*A) * (*B);
        C++;
        A++;
        B++;
    }
}
void mult(int*C,int*A,int*B){

对于(inti=0;iElementwise乘法,这样做是可以的。如果出于某种原因使用索引,gcc不希望发出向量代码

void mult(int C[3][3],int A[3][3],int B[3][3]){
    for(int i = 0;i<3;i++)
        for(int j = 0;j<3;j++)
        {
            C[i][j] = A[i][j] * B[i][j];
        }
}

void mult1(int *C,int *A,int *B){
    for(int i = 0;i<9;i++){
        *C = (*A) * (*B);
        C++;
        A++;
        B++;
    }
}
void mult(int C[3][3]、int A[3][3]、int B[3][3]){

对于(inti=0;iElementwise乘法,这样做是可以的。如果出于某种原因使用索引,gcc不希望发出向量代码

void mult(int C[3][3],int A[3][3],int B[3][3]){
    for(int i = 0;i<3;i++)
        for(int j = 0;j<3;j++)
        {
            C[i][j] = A[i][j] * B[i][j];
        }
}

void mult1(int *C,int *A,int *B){
    for(int i = 0;i<9;i++){
        *C = (*A) * (*B);
        C++;
        A++;
        B++;
    }
}
void mult(int C[3][3]、int A[3][3]、int B[3][3]){
对于(int i=0;i您可以使用VLAs:

void mult(int r, int c, int C[r][c], int A[r][c], int B[r][c]) {
    for(int i = 0; i < r; i++)
        for(int j = 0; j < c; j++)
            C[i][j] = A[i][j] * B[i][j];
}
...

int A[3][3], B[3][3], C[3][3];
mult(3, 3, C, A, B); 
void mult(int r,int c,int c[r][c],int A[r][c],int B[r][c]){
对于(int i=0;i
您可以使用VLA:

void mult(int r, int c, int C[r][c], int A[r][c], int B[r][c]) {
    for(int i = 0; i < r; i++)
        for(int j = 0; j < c; j++)
            C[i][j] = A[i][j] * B[i][j];
}
...

int A[3][3], B[3][3], C[3][3];
mult(3, 3, C, A, B); 
void mult(int r,int c,int c[r][c],int A[r][c],int B[r][c]){
对于(int i=0;i
我们需要真正弄清楚您在这里的意思-您的意思是要将每个
a[i][j]
乘以每个
b[i][j]
,并将结果分配给
c[i][j]

+---+---+   +---+---+   +-----+-----+     +----+----+
| 1 | 2 |   | 5 | 6 |   | 1*5 | 2*6 |     |  5 | 12 |
+---+---+ x +---+---+ = +-----+-----+  =  +----+----+
| 3 | 4 |   | 7 | 8 |   | 3*7 | 4*8 |     | 21 | 32 |
+---+---+   +---+---+   +-----+-----+     +----+----+
或者你想在哪里实现矩阵乘法

哪一个是非常不同的

如果是前者,那么根据调用函数的方式,您编写的内容基本上是可以的-请记住,在大多数情况下,“N-element array of
T
”类型的表达式将“衰减”为“pointer to
T
”类型的表达式,表达式的值将是数组的第一个元素的地址。类型为“int
int
的3元素数组的3元素数组”(
int[3][3]
)的表达式将衰减为类型“指向int
int
的3元素数组的指针”(
int(*)[3]
),而不是
int*

如果将数组声明为

int a[3][3], b[3][3], c[3][3];
并将函数调用为

mult( &a[0][0], &b[0][0], &c[0][0] ); // explicitly pass a pointer to the
                                      // first element of each array
mult( a, b, c );
那么你的一切都很好。有点难看,但很好

如果,OTOH,你调用的函数是

mult( &a[0][0], &b[0][0], &c[0][0] ); // explicitly pass a pointer to the
                                      // first element of each array
mult( a, b, c );
那么你所拥有的是不是好的,因为参数类型不匹配(编译器应该对你大喊大叫)

void mult( int A[3][3], int B[3][3], int C[3][3] )

这在函数参数声明1的上下文中都意味着相同的事情。但这也意味着您不能仅仅通过增加和取消引用指针来“遍历”数组,因为您基本上会遍历
a[0][0]
a[1][0]
,和
a[2][0]
,您会得到一个类型错误,因为
*a
不是
int
,而是
int[3]
。代码的实际内容需要

for ( size_t i = 0; i < 3; i++ )
  for ( size_t j = 0; j < 3; j++ )
    C[i][j] = A[i][j] * B[i][j];
对于一般用途的矩阵乘法函数,如果您不只是拥有3x3矩阵,类似的方法可能会起作用(假设支持可变长度数组,如果您使用的是C99或更高版本的实现,则应该是):


  • 而且只适用于函数参数声明-对于常规声明,它们的含义完全不同。
    我们需要真正弄清楚你在这里的意思-你的意思是想将每个
    a[i][j]
    乘以每个
    b[i][j]
    ,并将结果分配给
    c[i][j]
    ,这样

    +---+---+   +---+---+   +-----+-----+     +----+----+
    | 1 | 2 |   | 5 | 6 |   | 1*5 | 2*6 |     |  5 | 12 |
    +---+---+ x +---+---+ = +-----+-----+  =  +----+----+
    | 3 | 4 |   | 7 | 8 |   | 3*7 | 4*8 |     | 21 | 32 |
    +---+---+   +---+---+   +-----+-----+     +----+----+
    
    或者你想在哪里实现矩阵乘法

    哪一个是非常不同的

    如果是前者,那么根据调用函数的方式,您编写的内容基本上是可以的-请记住,在大多数情况下,“N-element array of
    T
    ”类型的表达式将“衰减”为“pointer to
    T
    ”类型的表达式,表达式的值将是数组的第一个元素的地址。类型为“int
    int
    的3元素数组的3元素数组”(
    int[3][3]
    )的表达式将衰减为类型“指向int
    int
    的3元素数组的指针”(
    int(*)[3]
    ),而不是
    int*

    如果将数组声明为

    int a[3][3], b[3][3], c[3][3];
    
    并将函数调用为

    mult( &a[0][0], &b[0][0], &c[0][0] ); // explicitly pass a pointer to the
                                          // first element of each array
    
    mult( a, b, c );
    
    那么你的一切都很好。有点难看,但很好

    如果,OTOH,你调用的函数是

    mult( &a[0][0], &b[0][0], &c[0][0] ); // explicitly pass a pointer to the
                                          // first element of each array
    
    mult( a, b, c );
    
    那么你所拥有的是不是好的,因为参数类型不匹配(编译器应该对你大喊大叫)

    void mult( int A[3][3], int B[3][3], int C[3][3] )
    

    这在函数参数声明1的上下文中都意味着相同的事情。但这也意味着您不能仅仅通过增加和取消引用指针来“遍历”数组,因为您基本上会遍历
    a[0][0]
    a[1][0]
    ,和
    a[2][0]
    ,您会得到一个类型错误,因为
    *a
    不是
    int
    ,而是
    int[3]
    。代码的实际内容需要

    for ( size_t i = 0; i < 3; i++ )
      for ( size_t j = 0; j < 3; j++ )
        C[i][j] = A[i][j] * B[i][j];
    
    对于一般用途的矩阵乘法函数,如果您不只是拥有3x3矩阵,类似的方法可能会起作用(假设支持可变长度数组,如果您使用的是C99或更高版本的实现,则应该是):


  • 而且只适用于函数参数声明-对于常规声明,它们的含义完全不同。
    你测试过吗?这可能在代码审查SE上更好。你是在问这是否符合语言,还是这是一种好的风格?如果你是在问,你可能会想读一读,因为你所做的不是这样。然后你的问题的答案是-不,这不是你乘矩阵的方式。你测试过吗?这可能是b在代码审查中,您是y吗