矩阵中c指针中的练习

时间:2019-02-23 14:49:31

标签: c

我试图使我的程序在带有指针的矩阵上创建默认数字,但没有得到结果,没有任何错误。有人可以帮我吗?我正在使用“ Dev C”作为IDE。 ................................................... ................................................... .......................................

    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <Math.h>
    typedef struct S_Matrice
    {
            int L;
            int C;
            int * mat ;
            }Matrice;
            //creation du matrice
    Matrice *CreerMatrice(int l, int c)
    {
    Matrice *m ;
    m = (Matrice *)malloc(sizeof(Matrice)) ;
    m->L = l ;
    m->C = c ;
    m->mat = (int *)malloc(l * c* sizeof(int)) ;
      return m;
    }
    //remplir une matrice
    Matrice *remplirMat(int l, int c)
    {
    Matrice *m ;
    m->mat = (int *)malloc(l * c* sizeof(int)) ; 
    m->L = l ;
    m->C = c ;
        int i,j;
        for(i=0; i < l;i++)
        {
            for(j=0; j <c; j++)
            m->mat=(int *)(rand()%26 + 'a');
        }
        return m;
     }
     void afficher(Matrice *m, int l, int c) {
      int i, j;
    m->L = l ;
    m->C = c ;
      for (i = 0; i < m->L; i++) {
        for (j = 0; j < m->L; j++)
          printf("%d ",m);
        printf("\n");
      }
    }

    int main() {
      int c = 8;
      int l = 8;
       Matrice *mat= CreerMatrice(c,l);
      remplirMat(8,8);
      afficher(mat,8,8);
      printf("bravo");
      getch();
      return 0;
    }

3 个答案:

答案 0 :(得分:1)

在您的 remplirMat

Matrice *m ;
m->mat = (int *)malloc(l * c* sizeof(int)) ; 

您在未初始化 m 时执行m->mat

缺少m = (Matrice *)malloc(sizeof(Matrice));

之后:

pi@raspberrypi:/tmp $ ./a.out
11972616 11972616 11972616 11972616 11972616 11972616 11972616 11972616 
11972616 11972616 11972616 11972616 11972616 11972616 11972616 11972616 
11972616 11972616 11972616 11972616 11972616 11972616 11972616 11972616 
11972616 11972616 11972616 11972616 11972616 11972616 11972616 11972616 
11972616 11972616 11972616 11972616 11972616 11972616 11972616 11972616 
11972616 11972616 11972616 11972616 11972616 11972616 11972616 11972616 
11972616 11972616 11972616 11972616 11972616 11972616 11972616 11972616 
11972616 11972616 11972616 11972616 11972616 11972616 11972616 11972616 
bravo

由于 remplirMat

中的行,所有时间值始终相同
m->mat=(int *)(rand()%26 + 'a');

您忘记了要存储到 m-> mat 中存储的分配数组中的索引 i j ,可能必须是:

m->mat[i*c +j]=(rand()%26 + 'a');

写得不好之后,在 afficher

printf("%d ",m);

尝试写分配的数组地址,需要写元素:

printf("%d ",m->mat[i*c +j]);

但是只写0 ...,因为在 main 中:

  remplirMat(8,8);

并且填充的矩阵丢失了,必须是

  mat=remplirMat(8,8);

,实际上Matrice *mat= CreerMatrice(c,l);是无用的,因为分配的矩阵丢失了。 remplirMat 可能必须在参数中获取矩阵,而不是分配新的矩阵

最好替换:

Matrice *remplirMat(int l, int c)
{
  Matrice *m ;
  m = (Matrice *)malloc(sizeof(Matrice)) ;
  ...
  return m;
}

作者

void remplirMat(Matrice *m, int l, int c)
{
   ...
}

,当然还有 main 替换

 Matrice *mat= CreerMatrice(c,l);
 mat=remplirMat(8,8);

作者      矩阵* mat = CreerMatrice(c,l);

 remplirMat(mat, 8,8);

编译和执行:

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra ma.c
pi@raspberrypi:/tmp $ ./a.out
110 119 108 114 98 98 109 113 
98 104 99 100 97 114 122 111 
119 107 107 121 104 105 100 100 
113 115 99 100 120 114 106 109 
111 119 102 114 120 115 106 121 
98 108 100 98 101 102 115 97 
114 99 98 121 110 101 99 100 
121 103 103 120 120 112 107 108 
bravo

我建议您添加 FreeMatrice 以释放分配的资源

void FreeMatrice(Matrice *m)
{
  free(m->mat);
  free(m);
}

,然后在 main 中调用它:

pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra ma.c
pi@raspberrypi:/tmp $ valgrind --leak-check=full ./a.out
==12798== Memcheck, a memory error detector
==12798== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==12798== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==12798== Command: ./a.out
==12798== 
110 119 108 114 98 98 109 113 
98 104 99 100 97 114 122 111 
119 107 107 121 104 105 100 100 
113 115 99 100 120 114 106 109 
111 119 102 114 120 115 106 121 
98 108 100 98 101 102 115 97 
114 99 98 121 110 101 99 100 
121 103 103 120 120 112 107 108 
bravo
==12798== 
==12798== HEAP SUMMARY:
==12798==     in use at exit: 0 bytes in 0 blocks
==12798==   total heap usage: 4 allocs, 4 frees, 2,316 bytes allocated
==12798== 
==12798== All heap blocks were freed -- no leaks are possible
==12798== 
==12798== For counts of detected and suppressed errors, rerun with: -v
==12798== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)

答案 1 :(得分:0)

欢迎您!请注意,函数remplirMat返回的矩阵结构由于未捕获返回值而丢失。

由于实际数据位于整数数组中,因此需要在该数组中插入行m->mat=(int *)(rand()%26 + 'a');,以不断重新定义m->mat是什么。看来您正在尝试制作一个二维数组来保存矩阵数据,因此要插入到矩阵中,我会做类似的事情:

int i,j;
for(i = 0; i < m->L, i++)     // assuming m->L is the number of rows
    for(j=0; j< m->C, j++)        // assuming m-C is the number of columns
        m[i*(m->L) + j] = (rand()%26 + 'a');

好,那么这是怎么回事?

  1. m->mat = (int *)malloc(l * c* sizeof(int)) ;行正在分配足够的内存来容纳l * c个整数,实际上m->mat是一个整数数组。现在,如何将矩阵数据存储到数组中完全由您决定,您只需要保持一致即可。从代码的外观上,您将以行优先的形式存储数据,即。将第一行的元素放入数组,然后将第二行的元素放入数组。

  2. 术语i*(m->L) + j是将(行,列)形式的索引转换为单个索引的惯用方式。例如,如果我有一个4x4数组,则需要弄清楚在您拥有的一维数组中可以找到说A(3,4)的元素(第三行和第四列的元素)的位置创建。我们使用公式row*MAX_ROWS + col

请考虑以下转换(假设您正在使用嵌套循环),其中变量行是变量i,变量col是变量'j'。 MAX_ROWS设置为4

element         linear index    row      col        row*MAX_ROWS + col   
A(1,1)             0             0        0           0*4 + 0 = 0
A(1,2)             1             0        1           0*4 + 1 = 2
A(1,3)             2             0        2           0*4 + 2 = 2
A(1,4)             3             0        3           0*4 + 3 = 4
A(2,1)             4             1        0           1*4 + 0 = 4

因此,您可以看到从行,列到单个索引的映射如何工作。

鉴于所有这些,我将按照以下方式修改程序(我也摆脱了一个字符变量名),将CreerMatrice和remplierMat的功能合并为一个功能。我还必须删除getch(),因为它是Windows专用的API,并且在Linux机器上进行了测试。

typedef struct S_Matrice
{
        int rows;
        int cols;
        int * mat ;
} Matrice;

//creation du matrice
Matrice *CreerMatrice(int rows, int cols )
{
    Matrice *m ;
    int ndx,jdx;

    m = (Matrice *)malloc(sizeof(Matrice)) ;
    m->rows = rows ;
    m->cols = cols ;
    m->mat = (int *)malloc(rows * cols * sizeof(int)) ;


    for(ndx=0; ndx < rows; ndx++)
    {
        for(jdx=0; jdx < cols; jdx++)
        m->mat[ndx*rows + jdx] = (rand()%26 + 'a');
    }

    return m;
 }

void afficher(Matrice *m) 
{
  int ndx, jdx;
  for (ndx = 0; ndx < m->rows; ndx++) 
  {
      for (jdx = 0; jdx < m->cols; jdx++)
          printf("%d ", m->mat[ndx*n->rows + jdx]);
      printf("\n");
  }
}

int main() 
{
    int c = 8;
    int l = 8;
    Matrice *mat= CreerMatrice(c,l);
    afficher(mat);
    printf("bravo");
    //getch();
    return 0;
}

以上代码使用gcc 5.4.0在命令行gcc -std=c99 -pedantic -Wall上在ubuntu上编译并产生输出:

110 119 108 114 98 98 109 113 
98 104 99 100 97 114 122 111 
119 107 107 121 104 105 100 100 
113 115 99 100 120 114 106 109 
111 119 102 114 120 115 106 121 
98 108 100 98 101 102 115 97 
114 99 98 121 110 101 99 100 
121 103 103 120 120 112 107 108 
bravo

答案 2 :(得分:-1)

问题出在remplirMat中。应该是:

Matrice *remplirMat(int l, int c)
{
    Matrice *m= malloc(sizeof(Matrice));
    m->mat = (int *)malloc(l * c* sizeof(int)); 
    m->L = l;
    m->C = c;
    for(int i=0; i < l;i++)
    {
        for(int j=0; j <c; j++)
            m->mat + (i*m->C) + j= (int)(rand()%26 + 'a');
    }
    return m;
 }

首先,必须将内存分配给m。接下来,您要将m->mat[i][j]设置为随机字母。但是由于编译器不知道行和列的大小,因此您必须自己进行地址计算:地址为mat加行数(i*m->C)加上当前列{ {1}}。