如何从函数返回矩阵,在c?

时间:2016-04-07 08:27:17

标签: c

我的c代码用于矩阵添加如下:

mat(int n,int a[][5],b[][5] ){
   int i,c[5][5];

   for(i=0;i<5;i++){
       for(j=0;j<5;j++)
           c[i][j]=a[i][j]+b[i][j];

    return c;
}

当我编译它时,我的编译器发现了错误:

||warning: command line option '-Wzero-as-null-pointer-constant' is valid for C++/ObjC++ but not for C [enabled by default]|
C:\Users\Amir Khasru\Desktop\retuturn_a_matrix.c|2|warning: return type defaults to 'int' [-Wreturn-type]|
C:\Users\Amir Khasru\Desktop\retuturn_a_matrix.c|2|warning: no previous declaration for 'mat' [-Wmissing-declarations]|
C:\Users\Amir Khasru\Desktop\retuturn_a_matrix.c||In function 'mat':|
C:\Users\Amir Khasru\Desktop\retuturn_a_matrix.c|8|error: return makes integer from pointer without a cast|
||=== Build failed: 1 error(s), 3 warning(s) (0 minute(s), 0 second(s)) ===|

3 个答案:

答案 0 :(得分:2)

你不能在C中返回一个数组! 您的调用函数需要定义输出矩阵(在您的示例中为c [] [])并将其作为参数传递给乘法函数。

您的代码中存在更多错误,您需要修复它们。

答案 1 :(得分:1)

这是你的代码(只是格式化并添加了一个缺少的右括号):

#include <stdio.h>

mat(int n, int a[][5], b[][5] )
{
    int i, c[5][5];

    for(i=0; i<5; i++) {
        for(j=0; j<5; j++) {
            c[i][j] = a[i][j] + b[i][j];
        }
        return c;
    }
}

我编译: $ gcc -std=c99 -Wall -Wextra -Wpedantic -Wconversion -Wno-sign-compare -Wshadow test.c -o test我得到的第一件事就是:

test.c:3:24: error: unknown type name ‘b’
 mat(int n, int a[][5], b[][5] )

让我们解决这个问题(在intb之前添加j):

#include <stdio.h>

mat(int n, int a[][5], int b[][5] )
{
    int i, c[5][5];

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

现在我们得到:

test.c:3:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
 mat(int n, int a[][5], int b[][5] )
 ^
test.c: In function ‘mat’:
test.c:11:10: warning: return makes integer from pointer without a cast [-Wint-conversion]
   return c;
          ^
test.c:11:10: warning: function returns address of local variable [-Wreturn-local-addr]
test.c:3:9: warning: unused parameter ‘n’ [-Wunused-parameter]
 mat(int n, int a[][5], int b[][5] )
         ^
test.c:13:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

那我们得到什么:

  • mat()返回int,因为它是一个默认回退,可以追溯到C99之前,但不再是标准。看来,您正在编译Visual Studio,它基本上实现了C89 +一些C99以实现C ++兼容性 - 但仍然可以修复它。
  • 然后您返回c,这绝对不是int类型。
  • 另外你不使用n,我想它的意思是行数?
  • 在第一个内部循环完成后返回 - 可能不需要。

该怎么做:
通常,您通常希望调用者为结果提供空间,因为您返回c mat()本地的mat(),这是mat()完成后发生的未定义行为。而是使用void mat(int r, int c, int m1[r][c], int m2[r][c], int mr[r][c]); 的以下声明:

r

其中c是行,m1是列,m2mr是输入矩阵,void mat(int r, int c, int m1[r][c], int m2[r][c], int mr[r][c]) { for(int i = 0; i < r; i++) { for(int j = 0; j < c; j++) { mr[i][j] = m1[i][j] + m2[i][j]; } } } 是结果矩阵。

代码将是:

m1 == NULL || m2 == NULL || mr == NULL

您不需要返回任何内容 - 您可以写入调用者提供的对象(希望如此)。如果您觉得自己很勇敢,可以先查看void print_mat(int r, int c, int m[r][c]); int main() { int m1[2][5] = { {0,1,2,3,4}, {1,2,3,4,5} }; int m2[2][5] = { {10,11,12,13,14}, {11,12,13,14,15} }; printf("printing matrix m1:\n"); print_mat(2,5,m1); printf("printing matrix m1:\n"); print_mat(2,5,m2); int c[2][5]; mat(2,5,m1,m2,c); printf("printing matrix m1+m2:\n"); print_mat(2,5,c); } void print_mat(int r, int c, int m[r][c]) { for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { printf("\t%d", m[i][j]); } printf("\n"); } return; }

让我们看一下使用此测试代码的方法:

printing matrix m1:
        0       1       2       3       4
        1       2       3       4       5
printing matrix m1:
        10      11      12      13      14
        11      12      13      14      15
printing matrix m1+m2:
        10      12      14      16      18
        12      14      16      18      20

我明白了:

{{1}}

这正是它应该是的。

最后:

  • 具体说明类型,有帮助。
  • 如果您不确定,请打开所有警告。
  • 通常不会在子功能中获取内存,让调用者执行此操作。
  • 如果您不确定指针/数组,请尽量避免使用它们并编写可理解的小测试用例;做研究!

答案 2 :(得分:-1)

您可以通过引用传递。

我不能用你的矩阵来做,因为我不认为代码是100%正确的。代码看起来像这样。

int mat(int x, int y, const int *m_a, const int *m_b, int *m_out);

其中:

    函数返回的
  • int是一种状态代码。
  • x和y是矩阵的宽度和高度。
  • m_a,m_b是输入矩阵。他们是常数。
  • m_out是输出矩阵。

您可以通过返回矩阵来“升级”该功能:

int *mat(int x, int y, const int *m_a, const int *m_b, int *m_out){
    // do some work
    if (something is not OK)
        return NULL;
    else
        return m_out;
}

// in main()
int a[5 * 6];
int b[5 * 6];
int result[5 * 6];
mat(5, 6, a, b, result);
// use result.

第三个选项,可能更糟糕的一个 - 分配内存,并返回分配的内存。后来的记忆需要被释放。

int *mat(int x, int y, const int *m_a, const int *m_b){
    int *m_out = malloc( x * y * sizeof int);

    if (m_out == NULL)
        return NULL;

    // do some work

    if (something is not OK){
        free(m_out);
        return NULL;
    }else
        return m_out;
}

// in main()
int *m = mat(5, 6, a, b);
// use m
free(m);

如果您有疑问,请发表评论。

在所有示例中,我假设单维数组。您可以轻松地将两个维度坐标转换为单个维度,请在此处查看:

How to map the indexes of a matrix to a 1-dimensional array (C++)?

这是完整的,工作的例子就像我一样。

#include <stdio.h>

int *mat(int x, int y, const int *m_a, const int *m_b, int *m_out){
    int i;
    for(i = 0; i < x * y; ++i)
        m_out[i] = m_a[i] + m_b[i];

    return m_out;
}

void print_mat(int x, int y, const int *m){
    int i, j;
    for(i = 0; i < x; ++i){
        for(j = 0; j < y; ++j)
            printf("| %4d ", m[i * y + j]);

        printf("|\n");
    }
}

#define X   2
#define Y   2

int main(){
    int a[X * Y] = { 1, 2, 3, 4 };
    int b[X * Y] = { 1, 2, 3, 4 };
    int result[X * Y];

    int *r = mat(X, Y, a, b, result);

    print_mat(X, Y, r);

    return 0;
}

以下是输出:

[nmmm@zenbook HM3]$ gcc -Wall -Wpedantic x.c
[nmmm@zenbook HM3]$ ./a.out 
|    2 |    4 |
|    6 |    8 |
[nmmm@zenbook HM3]$