在c中获取2D数组的元素?

时间:2015-05-06 20:13:23

标签: c arrays multidimensional-array

我似乎在从c中获取二维数组中的元素时遇到问题。对我来说这看起来非常简单,但我想有人不会看到他的一个错误:P。我相信我的代码是正确的,虽然我收到警告。

代码:

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

#define SIZE 2

int main() {
    int mat1[SIZE][SIZE] = {{2,3},{4,5}};
    int mat2[SIZE][SIZE] = {{6,7},{8,9}};

    int *res = multiply(mat1, mat2, SIZE);

    int i, j;
    for(i = 0; i < SIZE; i++) {
        for (j = 0; j < SIZE; j++) {
            int getEl = *(*(res + i) + j);
            printf("%d ", getEl);
        }
        printf("\n");
    }
    return 0;
}

我得到的错误:

  

一元'*'的无效类型参数(有'int')

我在这里看不到什么?

修改

对不起伙计们,这是.h文件:

#define SIZE 2

int* multiply(int mat1[][SIZE], int mat2[][SIZE], int size) {
    int res[size][size];

    int i,j, k;
    for (i = 0; i < size; i++) {
        for (j = 0; j < size; j++) {
            int sumElement = 0;
            for (k = 0; k < size; k++) {
                sumElement += mat1[i][k]*mat2[k][j];
            }
            res[i][j] = sumElement;
            printf("sumElement: %d\n", sumElement);
        }
    }
    return &res;
}

我还要补充一点,我也在这里定义SIZE,这似乎非常不合逻辑。但我别无选择,因为我必须指定2D阵列的大小。

3 个答案:

答案 0 :(得分:0)

这里的问题是变量

int *res =....

res的类型为int *。所以,对于像

这样的陈述
 *(*(res + i) + j);
  • *(res + i)提供int
  • *(res + i) + j也提供int

并且,int 不能用作一元*运算符的操作数。因此错误。

修改

您的multiply()调用未定义的行为,因为return是本地变量的地址。换句话说,在multiply()完成执行后,res的存在停止并尝试访问返回的值是UB。您应该使用动态内存分配[malloc() / calloc()]。

此外,return类型和return值不匹配。

那就是说,头文件理想情况下应该包含函数声明(原型),而不是函数定义

答案 1 :(得分:0)

C中的函数不能直接返回矩阵,你必须使用双指针。一个数组,指向每个数组,对应一行矩阵。

这会给你的问题增加相当不必要的复杂性,并且需要为返回的缓冲区分配内存,这是要避免的(并且你也不能返回指向局部变量的指针,它会崩溃)

我相信在你的情况下最好的解决方案是不返回任何价值。只需为multiply()提供一个可用于存储结果的缓冲区:

#define SIZE 2
void multiply(int res[SIZE][SIZE], int mat1[SIZE][SIZE], int mat2[SIZE][SIZE])
{
    int i, j, k, sumElement;
    for (i = 0; i < SIZE; i++) {
        for (j = 0; j < SIZE; j++) {
            sumElement = 0;
            for (k = 0; k < SIZE; k++) {
                sumElement += mat1[i][k] * mat2[k][j];
            }
            res[i][j] = sumElement;
            printf("sumElement: %d\n", sumElement);
        }
    }
}

并使用这样的功能:

int main()
{
    int mat1[SIZE][SIZE] = {{2,3},{4,5}};
    int mat2[SIZE][SIZE] = {{6,7},{8,9}};
    int res[SIZE][SIZE];

    multiply(res, mat1, mat2);

    int i, j;
    for(i = 0; i < SIZE; i++) {
        for (j = 0; j < SIZE; j++) {
            int getEl = res[i][j];
            printf("%d ", getEl);
        }
        printf("\n");
    }
    return 0;
}

请注意,原生矩阵不是非常通用,并且作为参数传递给其他函数可能是一件棘手的事情,因为该函数必须在编译时知道该矩阵的维数,否则它将无法工作。创建一个可以处理任何维度矩阵的函数的唯一方法是使它适用于双指针。

回答评论:

要将它们转换为指向指针的指针,并且能够将任何大小的矩阵传递给您的函数并允许此函数返回矩阵,您还必须执行以下操作:

int** multiply(int** mat1, int** mat2, int size)
{
    int i, j, k;

    // allocate the memory necessary to store the results
    int** res = malloc(size * sizeof(int*));
    for (i = 0; i < size; ++i)
        res[i] = malloc(size * sizeof(int));

    // populate res with values
    for (i = 0; i < size; i++)
        for (j = 0; j < size; j++)
        {
            res[i][j] = 0;

            for (k = 0; k < size; k++)
                res[i][j] += mat1[i][k] * mat2[k][j];

            printf("sumElement: %d\n", res[i][j]);
        }

    return res;
}

现在,此函数可以处理任何大小的任何矩阵,将自动分配存储结果所需的内存,并返回一个可以使用res[i][j]访问的指针。用法:

int main()
{
    int mat1[][SIZE] = { { 2, 3 }, { 4, 5 } };
    int mat2[][SIZE] = { { 6, 7 }, { 8, 9 } };

    // map them into double pointer matrixes so they can be used by multiply()
    int* pmat1[SIZE] = { mat1[0], mat1[1] };
    int* pmat2[SIZE] = { mat2[0], mat2[1] };

    int** res = multiply(pmat1, pmat2, SIZE);

    int i, j;
    for(i = 0; i < SIZE; i++) {
        for (j = 0; j < SIZE; j++) {
            int getEl = res[i][j];
            printf("%d ", getEl);
        }
        printf("\n");
    }
    return 0;
}

此代码只有一个问题,分配在同一函数结束前不会发布的内存被认为是不好的做法。相反,main()应该分配res使用的内存并将此缓冲区传递给multiply()以供使用,并且还负责在使用后释放此内存。不释放您不再需要的内存是一个称为memory leak的问题。阅读维基百科artigle了解详情。

在这样一个简单的代码中,程序将在计算矩阵后不久终止,但这并不重要,但是你应该记住以后的项目。

更新2:

这是一种方法:

void multiply(int** res, int** mat1, int** mat2, int size)
{
    int i, j, k;

    // populate res with values
    for (i = 0; i < size; i++)
        for (j = 0; j < size; j++)
        {
            res[i][j] = 0;

            for (k = 0; k < size; k++)
                res[i][j] += mat1[i][k] * mat2[k][j];

            printf("sumElement: %d\n", res[i][j]);
        }
}

int main()
{
    int mat1[][SIZE] = { { 2, 3 }, { 4, 5 } };
    int mat2[][SIZE] = { { 6, 7 }, { 8, 9 } };
    int res[][SIZE]  = { { 0, 0 }, { 0, 0 } };

    // map them into double pointer matrixes so they can be used by multiply()
    int* pmat1[SIZE] = { mat1[0], mat1[1] };
    int* pmat2[SIZE] = { mat2[0], mat2[1] };
    int* pres[SIZE]  = { res[0],  res[1] };

    multiply(pres, pmat1, pmat2, SIZE);

    int i, j;
    for(i = 0; i < SIZE; i++) {
        for (j = 0; j < SIZE; j++) {
            int getEl = res[i][j];
            printf("%d ", getEl);
        }
        printf("\n");
    }
    return 0;
}

答案 2 :(得分:0)

首先永远不要将数组定义为函数参数,因为这会产生误导(它们会神奇地调整为指针)。

我的意思是:

int* multiply(int mat1[][SIZE], int mat2[][SIZE], int size)

自动成为:

int* multiply(int (*mat1)[SIZE], int (*mat2)[SIZE], int size)

这显然不是你想要的,因为这样修改这些参数实际上会修改传递的参数,而这并不是通过值传递的。语法表明了什么。

第二个指向“SIZE&#39;”的二维数组的指针。写成如下:

int (*)[SIZE][SIZE]

而不是:

int *

所以你的整个代码都非常错误。在这里,我将正确的版本:

#define SIZE 2

struct _2dimensarrayofSIZE { int d[SIZE][SIZE]; }; //*1

struct _2dimensarrayofSIZE multiply(int (*pmat1)[SIZE][SIZE], int (*pmat2)[SIZE][SIZE]) {
    struct _2dimensarrayofSIZE res;

    int i,j, k;
    for (i = 0; i < size; i++) {
        for (j = 0; j < size; j++) {
            int sumElement = 0;
            for (k = 0; k < size; k++) {
                sumElement += (*pmat1)[i][k]*(*pmat2)[k][j];
            }
            res.d[i][j] = sumElement;
            printf("sumElement: %d\n", sumElement);
        }
    }
    return res;
}

主要来源:

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

//#define SIZE 2 supposing that this is defined in your 'multiply'
//function header

int main() {
    int mat1[SIZE][SIZE] = {{2,3},{4,5}};
    int mat2[SIZE][SIZE] = {{6,7},{8,9}};

    struct _2dimensarrayofSIZE res = multiply(&mat1, &mat2); //*2

    int i, j;
    for(i = 0; i < SIZE; i++) {
        for (j = 0; j < SIZE; j++) {
            int getEl = *(*(res.d + i) + j);
            printf("%d ", getEl);
        }
        printf("\n");
    }
    return 0;
}

注意:

* 1:这里我们使用数组进入结构黑客,否则&#39; C&#39;不允许我们返回数组。

* 2:这里我们使用&#39;&amp;&#39;传递二维数组指针。 (地址运营商)。