【问题标题】:input and print static matrix with functions in C使用 C 语言输入和打印带有函数的静态矩阵
【发布时间】:2017-04-16 19:34:08
【问题描述】:

感谢您的帮助,抱歉我的英语不好 我正在尝试使用具有函数的矩阵从用户输入或用随机数填充矩阵然后打印它,但我只能打印最后一行,我认为问题与指针有关,请帮助我 用户选择是否要填充矩阵或使用随机数来完成, 这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 25
#define MIN 10

int i, j, y, x, n;
int mat [MAX] [MAX];
int main ()
{   
  int x, y, i, j, user, n;
  printf ("Goodmorning, insert matrix dims (y,x): ");
  scanf ("%d %d",&y,&x);
  for (i=0;i<y;i++)
   for (j=0;j<x;j++)
    mat [i] [j] = 0;
  printf ("\nInsert '0' for random, insert '1' for manual: ");
  scanf ("%d", &user);
  if (!user)
  rand_matrix (mat [x], x, y);
  if (user)
  input_matrix (mat [x], x, y);
  stampa_matrix (mat  [x], x, y);
  return 0;
}

  rand_matrix (int matrix  [y] [x] , int b, int a)
 {
 srand(time(NULL));
 for (i=0;i<a;i++)
 for (j=0;j<b;j++)
  {
   n = rand () % MAX + MIN;
   matrix [i] [j] = n;
  }
 }

input_matrix (int matrix [y] [x], int b, int a)
{
for (i=0;i<a;i++)
 for (j=0;j<b;j++)
 scanf ("%d", &matrix[i] [j]);
}

stampa_matrix (int matrix [y] [x] , int b, int a)
{
 for (i=0;i<a;i++) 
 {
  printf ("\n");
  for (j=0;j<b;j++)
  printf ("%3d ", matrix [i] [j] );
 }
}

【问题讨论】:

  • rand_matrix (mat [x], x, y); --> rand_matrix (mat, x, y);
  • rand_matrix (int matrix [y] [x] , int b, int a) --> rand_matrix (int matrix [y] [MAX] , int b, int a)
  • 在调用任何scanf() 系列函数时,始终检查返回值(而不是参数值)以确保操作成功。
  • 发布的代码无法检查 xy 值以确保它们在 1...MAX 范围内,因此用户可以输入大于 MAX 的值对于这些值中的任何一个,都会导致(最终)缓冲区溢出。这种溢出是未定义的行为,可能导致段错误事件。

标签: c function pointers matrix


【解决方案1】:

我认为我发现您的代码存在各种问题。我将在下面详细说明:

1) 您正在定义函数(rand_matrix、input_matrix、stampa_matrix)发布在 main() 中的函数调用。这可能在 gcc 中编译良好,但在 VC 中失败。函数原型也是一个好主意。

2) 所有三个函数都不存在返回类型(隐式 int 已被弃用;请参阅此 - C function calls: Understanding the "implicit int" rule

3) 正如mab所指出的,您需要在声明中使用双指针,如下所示: 空白 rand_matrix(int matrix[][MAX], int b, int a) 要么 void rand_matrix(int matrix[MAX][MAX], int b, int a)

4) 函数调用应如下所示: rand_matrix(mat, x, y); 而不是 rand_matrix (mat [x], x, y); 在第一次调用中,您传递的是第 0 行的地址,而第二次传递的是第 x 行的地址,其中 x 是行本身,导致访问边界冲突(请记住数组元素从索引 0 开始)

最后,请按照代码缩进进行正确理解。祝你好运!

【讨论】:

    【解决方案2】:

    在代码中,matint mat[MAX][MAX]; 声明为指向整数的指针。因此,声明中[MAX] 的每个后缀都会在底层C 数据类型中添加另一个指针。

    当引用对象时,例如mat[i][j] = 3,类似的事情发生了。每个后缀[i] 解析一个指向底层 C 数据类型的指针。当所有层的指针都被删除后,实际上可以访问该存储位置的int

    代码中函数input_matrix()stampa_matrix()的参数是mat[x]。那将是一个指向 int 数据类型的指针。

    但是,matrix[i][j] 在函数中删除了两层指针。因此,mat 的声明数据类型与其在函数input_matrix()stampa_matrix() 中的实际使用之间存在不匹配。

    要解决问题,请像这样给出mat 参数:

    /* ... */
    if(user)
        input_matrix(mat, x, y);
    
    stampa_matrix(mat, x, y);
    /* ... */
    

    所以现在你将一个指向 int 的指针传递给函数。在函数中,您可以通过 matrix[i][j] 正确解析指向指针的指针,并访问实际的 int

    在函数的声明中,方括号中的xy 不是必需的。此外,最好在函数名前添加返回数据类型(此处为:void)。

    void input_matrix (int matrix[][], int b, int a)
    {
        /* ... */
    }
    
    void stampa_matrix (int matrix[][] , int b, int a)
    {
        /* ... */
    }
    

    在函数参数列表中,重要的只是它们的数据类型。在这种情况下,int matrix[][] 再次表示指向 int 的指针。

    代码中还有一件事让我印象深刻:

    缩进不一致,部分只有1个空格。我建议使用 4 个空格或 1 个制表符以获得清晰的可见性。如果这导致行的剩余长度出现问题,则表明代码应该被分成不同的文件或模块。

    尽早采用一致的风格是一种很好的做法。那么后续的代码维护就容易多了。

    【讨论】:

    • 所有这些文本,仍然没有指出真正的问题:作为参数传递的二维数组必须在原型中指定它们的大小,正如 BLUEPIXY 评论的那样。
    猜你喜欢
    • 1970-01-01
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多