首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用指针添加2个矩阵

使用指针添加2个矩阵
EN

Stack Overflow用户
提问于 2017-10-01 13:03:51
回答 3查看 4.3K关注 0票数 2

我可以通过将(c,a,b)传递给add_mat函数来实现,其中a,b的结果存储在c中,

void add_mat(int c[][3], int a[][3], int b[][3], int m, int n)

如果要以这种方式构造函数,add_mat的返回类型应该是什么?

?? add_mat(int a[][3], int b[][3], int m, int n)

下面是一个示例代码

代码语言:javascript
复制
#include<stdio.h>

void read_mat(int a[][3], int m, int n){
    //scan data
    for(int i=0; i<m; i++){
        for(int j=0; j<n; j++){
            printf("[%d][%d] : ",i,j);
            a[i][j]=i+j;
        }
    }   
}
int* add_mat(int a[][3], int b[][3], int m, int n){
    int c[3][3];
    for(int i=0; i<m; i++){
        for(int j=0; j<n; j++){
            c[i][j]=a[i][j]+b[i][j];
        }
    }
    return c;
}

int main(){
    int a[3][3];
    int m=2,n=2; //mxn of a matrix

    read_mat(a, m, n);

    //add
    int b[3][3];
    read_mat(b, m, n);
    int* c[3][3];
    c = add_mat(a,b,m,n);

    return 0;
}

类似于将计算值cadd_mat函数中传递或指向main函数中的变量。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-10-01 13:10:55

您不能这样做,因为当函数终止时,c矩阵的内存将消失。

您需要用malloc()动态地分配它,以便内存不被释放,除非您调用free()。我在二维动态阵列(C)中有一些例子,如果您想看一看的话。

使用前面的函数,您将在函数外部创建矩阵c (在main()中),这就是不需要动态内存分配的原因。

PS:您应该在启用警告的情况下进行编译:

代码语言:javascript
复制
prog.c: In function 'add_mat':
prog.c:19:12: warning: returning 'int (*)[3]' from a function with incompatible return type 'int *' [-Wincompatible-pointer-types]
     return c;
            ^
prog.c:19:12: warning: function returns address of local variable [-Wreturn-local-addr]
prog.c: In function 'main':
prog.c:32:7: error: assignment to expression with array type
     c = add_mat(a,b,m,n);
       ^
prog.c:31:10: warning: variable 'c' set but not used [-Wunused-but-set-variable]
     int* c[3][3];
          ^

下面是一个有用的示例,它只是为了演示目的:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>

void read_mat(int a[][2], int n, int m){
    //scan data
    for(int i=0; i<n; i++){
        for(int j=0; j<m; j++){
            a[i][j] = i + j ;
        }
    }
}

int **get(int N, int M) /* Allocate the array */
{
    /* Check if allocation succeeded. (check for NULL pointer) */
    int i, **table;
    table = malloc(N*sizeof(int *));
    for(i = 0 ; i < N ; i++)
        table[i] = malloc( M*sizeof(int) );
    return table;
}

void print(int** p, int N, int M) {
    int i, j;
    for(i = 0 ; i < N ; i++)
        for(j = 0 ; j < M ; j++)
            printf("array[%d][%d] = %d\n", i, j, p[i][j]);
}

void free2Darray(int** p, int N) {
    int i;
    for(i = 0 ; i < N ; i++)
        free(p[i]);
    free(p);
}

int** add_mat(int a[][2], int b[][2], int m, int n){
    int** c = get(n, m);
    for(int i=0; i<n; i++){
        for(int j=0; j<m; j++){
            c[i][j]=a[i][j]+b[i][j];
        }
    }
    return c;
}

int main(){

    int n = 2, m = 2; //nxm of a matrix
    int a[n][m];

    read_mat(a, n, m);

    //add
    int b[n][m];
    read_mat(b, n, m);
    int** c;
    c = add_mat(a, b, n, m);

    print(c, n, m);
    free2Darray(c ,n);

    return 0;
}

输出:

代码语言:javascript
复制
array[0][0] = 0
array[0][1] = 2
array[1][0] = 2
array[1][1] = 4

如果您真的想使用静态数组,那么我建议您使用int c[3][3]; add_mat(c, a, b, m, n);

票数 2
EN

Stack Overflow用户

发布于 2017-10-01 13:24:18

哦,是的,指点..。

在C中,通常在堆栈(而不是堆上)上分配本地声明的数组,这意味着它们在各自的作用域之外无效。

换句话说,在您的函数add_mat()中,技术上可以返回c,但是只要函数被执行,它指向的地址就会包含有意义的矩阵数据。

函数返回后,函数的返回值是一个指针,该指针仍然包含(指向)在执行函数期间存储矩阵的地址,但该位置的内容(即矩阵数据)现在可以包含任意垃圾。

因此,您所做的工作在技术上是可能的(即不会抛出编译错误),但绝对不是您想要的。

其次,您的行int* c[3][3];可能不是您想要的那样。您在这里声明c是指向int的二维数组(矩阵)。这是不正确的,因为您希望处理int值,但不希望处理指向int值(即地址)的指针。

要解决这两个问题,只需编写int c[3][3];而不是int* c[3][3];,并按如下方式更改add_mat()函数:

代码语言:javascript
复制
void add_mat(int a[][3], int b[][3], int c[][3], int m, int n){

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

然后像这样调用这个函数:

代码语言:javascript
复制
add_mat(a,b,c,m,n);
票数 1
EN

Stack Overflow用户

发布于 2017-10-01 14:52:14

在您的代码中,add_mat返回指向变量的指针,该变量仅在函数执行时存在。您可以通过动态分配矩阵来完成您的目标。

在C中,通常通过指针将动态分配的矩阵作为第一个参数传递给指向矩阵行的指针:

代码语言:javascript
复制
void foo(int** matrix, size_t m, size_t n);

这里,matrix是指向指针数组的指针。此数组中的每个指针都指向矩阵行。因此,matrix[0]指向包含第一行矩阵的数组。

对于任意大小的数组,通常使用size_t类型。

如果您需要动态创建矩阵,请小心内存。应该释放每个动态分配的块。否则,您将得到内存泄漏,这可能导致程序崩溃。因此,在分配矩阵行时,应检查当前行的分配是否成功。如果没有,则应该释放以前分配的所有行。

对于您的问题,有一个工作代码:

代码语言:javascript
复制
#include <stdio.h>
#include <stddef.h>
#include <malloc.h>

void free_mat(int** a, size_t m) {
    if (!a) {
        return;
    }

    for (size_t i = 0; i < m; ++i) {
        free(a[i]);
    }

    free(a);
}

int** create_mat(size_t m, size_t n) {
    int** rows = calloc(m, sizeof(int*));
    if (!rows) {
        return NULL;
    }

    for (size_t i = 0; i < m; i++) {
        rows[i] = malloc(n * sizeof(int));
        if (!rows[i]) {
            free_mat(rows, m);
            return NULL;
        }
    }

    return rows;
}

void read_mat(int** a, size_t m, size_t n) {
    for (size_t i = 0; i < m; i++) {
        for (size_t j = 0; j < n; j++) {
            printf("[%d][%d]: ", i, j);
            scanf("%d", a[i] + j);
        }
    }
}

void print_mat(const int* const* a, size_t m, size_t n) {
    for (size_t i = 0; i < m; ++i) {
        for (size_t j = 0; j < n; ++j) {
            printf("[%d][%d]: %d\n", i, j, a[i][j]);
        }
    }
}

int** add_mat(const int* const* a, const int* const* b, size_t m, size_t n) {
    int** c = create_mat(m, n);
    if (c) {
        for (size_t i = 0; i < m; ++i) {
            for (size_t j = 0; j < n; ++j) {
                c[i][j] = a[i][j] + b[i][j];
            }
        }
    }
    return c;
}

int main() {
    size_t m = 3;
    size_t n = 3;

    int** a = create_mat(m, n);
    int** b = create_mat(m, n);

    if (!a || !b) {
        printf("error when allocating matrix\n");
    }
    else {
        read_mat(a, m, n);
        read_mat(b, m, n);

        int** c = add_mat(a, b, m, n);
        if (!c) {
            printf("error when allocating matrix\n");
        }
        else {
            print_mat(c, m, n);
            free_mat(c, m);
        }
    }

    free_mat(a, m);
    free_mat(b, m);

    return 0;
}

但是,如果add_mat不创建一个新的矩阵,您将更加灵活。通常将指向结果矩阵的指针作为函数参数传递:

代码语言:javascript
复制
void add_mat(int** c, const int* const* a, const int* const* b, size_t m, size_t n);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46512633

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档