pkqbszs 发表于 2023-1-1 20:59:15

关于这段代码的几个问题

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

#define MAX_LIMIT_MATRIX 100

void welcome(void);
int get_ins(void);
int *create_matrix(void);
void init_matrix(int *ptr);
void print_matrix(int *ptr);
void write_matrix(int *ptr);
void read_matrix(int *ptr);

void welcome(void)
{
      printf("\n============================\n");
      printf("* 欢迎使用该程序,指令如下 *\n");
      printf("* 1.生成一个 M*N 的矩阵    *\n");
      printf("* 2.初始化矩阵             *\n");
      printf("* 3.给矩阵中某个元素赋值   *\n");
      printf("* 4.读取矩阵中某个元素   *\n");
      printf("* 5.打印整个矩阵         *\n");
      printf("* 6.结束程序               *\n");
      printf("============================\n");
}

int get_ins(void)
{
      int ins;

      printf("\n请输入指令:");
                scanf("%d", &ins);

      while (ins < 1 || ins > 6)
      {
                printf("\n指令错误,请重新输入:");
                scanf("%d", &ins);
      }

      return ins;
}

int *create_matrix(void)
{
      int m, n;
      static int created = 0; // 用于判断是否已经创建过矩阵
      static int *ptr = NULL;

      if (created)
      {
                printf("矩阵已存在,是否需要重新创建?(Y/N)-> ");
                getchar(); // 清除缓冲区残留的换行符
                while (getchar() == 'N')
                {
                        return ptr;
                }
      }

      printf("请输入新矩阵的规模(M*N)-> ");
      scanf("%d*%d", &m, &n);

      while (m < 1 || n < 1)
      {
                printf("规模太小,请重新输入:");
                scanf("%d*%d", &m, &n);
      }

      while (m > MAX_LIMIT_MATRIX || n > MAX_LIMIT_MATRIX)
      {
                printf("规模太大,请重新输入:");
                scanf("%d*%d", &m, &n);
      }

      // 虽然说是矩阵是二维数组,但在C语言中它的存放形式是“平铺”的
      // 这里用realloc,支持重新创建二维数组
      // 这里多申请了两个整形空间,用于存放矩阵的长和宽
      ptr = (int *)realloc(ptr, (m * n + 2)* sizeof(int));
      if (ptr == NULL)
      {
                printf("内存申请失败!\n");
                exit(1);
      }

      printf("%d*%d 的矩阵创建成功!\n", m, n);
      created = 1;

      // 将长和宽放在前两个元素中
      ptr = m;
      ptr = n;

      return ptr;
}

void init_matrix(int *ptr)
{
      int m = ptr;
      int n = ptr;
      int *matrix = ptr + 2;
      int num, i, j;

      if (ptr == NULL)
      {
                printf("未检测到矩阵,请先生成矩阵!\n");
                return ;
      }

      printf("请输入一个数字:");
      scanf("%d", &num);

      for (i = 0; i < m; i++)
      {
                for (j = 0; j < n; j++)
                {
                        matrix = num;
                }
      }
}

void print_matrix(int *ptr)
{
      int m = ptr;
      int n = ptr;
      int *matrix = ptr + 2;
      int i, j;

      if (ptr == NULL)
      {
                printf("未检测到矩阵,请先生成矩阵!\n");
                return ;
      }

      for (i = 0; i < m; i++)
      {
                for (j = 0; j < n; j++)
                {
                        printf("%d", matrix);
                }
                putchar('\n');
      }
}

void write_matrix(int *ptr)
{
      int m = ptr;
      int n = ptr;
      int *matrix = ptr + 2;
      int num, x, y;

      if (ptr == NULL)
      {
                printf("未检测到矩阵,请先生成矩阵!\n");
                return ;
      }

      printf("请输入要修改的位置(行,列)-> ");
      scanf("%d,%d", &x, &y);

      if (x > m || y > n || x < 1 || y < 1)
      {
                printf("坐标输入有误!\n");
                return ;
      }

      printf("请输入一个数字:");
      scanf("%d", &num);

      matrix[(x - 1) * n + (y - 1)] = num;
}

void read_matrix(int *ptr)
{
      int m = ptr;
      int n = ptr;
      int *matrix = ptr + 2;
      int num, x, y;

      if (ptr == NULL)
      {
                printf("未检测到矩阵,请先生成矩阵!\n");
                return ;
      }

      printf("请输入要读取的位置(行,列)-> ");
      scanf("%d,%d", &x, &y);

      if (x > m || y > n || x < 1 || y < 1)
      {
                printf("坐标输入有误!\n");
                return ;
      }

      printf("第%d行,第%d列的数字是:%d\n", x, y, matrix[(x - 1) * n + (y - 1)]);
}

int main(void)
{
      int ins;
      int *ptr = NULL;

      welcome();

      while((ins = get_ins()) != 6)
      {
                switch(ins)
                {
                        case 1: ptr = create_matrix(); break;
                        case 2: init_matrix(ptr); break;
                        case 3: write_matrix(ptr); break;
                        case 4: read_matrix(ptr); break;
                        case 5: print_matrix(ptr); break;
                }
      }

      printf("\n感谢使用本程序^_^\n\n");

      free(ptr);

      return 0;
}
1.我不太清楚为什么init_matrix和print_matrix函数中ptr要+2而不是+8,int不是一个4字节吗
2.这段代码如果第一次输入指令2 3 4 5会发生段错误,这是为什么呢

ba21 发表于 2023-1-1 21:58:43

pkqbszs 发表于 2023-1-1 22:30:43

ba21 发表于 2023-1-1 21:58


请问为什么会发生段错误,不太理解

pkqbszs 发表于 2023-1-1 22:32:37

ba21 发表于 2023-1-1 21:58


还想问一下你这个图里给指针赋值88是什么意思

ba21 发表于 2023-1-1 22:40:21

pkqbszs 发表于 2023-1-1 22:32
还想问一下你这个图里给指针赋值88是什么意思

.我不太清楚为什么init_matrix和print_matrix函数中ptr要+2而不是+8,int不是一个4字节吗

洋洋痒 发表于 2023-1-1 22:41:12

第一个问题,你还没看懂这段代码的整体设计。他的思路是让你输入m,n
但是实际操作的时候申请一段空间地址是ptr,这段空间第一个位子存储的是m,第二个位子存储的是n。真正的二维数组是从第三个位子开始存储的
代码写的清清楚楚
// 这里多申请了两个整形空间,用于存放矩阵的长和宽
      ptr = (int *)realloc(ptr, (m * n + 2)* sizeof(int));
      if (ptr == NULL)
      {
                printf("内存申请失败!\n");
                exit(1);
      }

      printf("%d*%d 的矩阵创建成功!\n", m, n);
      created = 1;

      // 将长和宽放在前两个元素中
      ptr = m;
      ptr = n;
所以才要ptr+2好指向二维数组的第一个元素。这是第一个问题的原因


第二个问题代码写错了。2 3 4 5功能函数里的
if (ptr == NULL)
      {
                printf("未检测到矩阵,请先生成矩阵!\n");
                return ;
      }
都应该写在对于函数的第一行。至少应该在int *matrix = ptr + 2;这句话的上面,按照这个代码,你的 int *matrix = ptr + 2; 写在上面,万一ptr是空指针代码直接崩溃不是很正常的吗?所以那几个函数都应该先判断是否为空指针

洋洋痒 发表于 2023-1-1 22:43:52

整形指针+2 是跳过两个整型,即8个地址位

pkqbszs 发表于 2023-1-1 23:15:57

洋洋痒 发表于 2023-1-1 22:41
第一个问题,你还没看懂这段代码的整体设计。他的思路是让你输入m,n
但是实际操作的时候申请一段空间地址 ...

谢谢哥,全明白了

学习编程中的Ben 发表于 2023-1-2 08:20:01

来看看
页: [1]
查看完整版本: 关于这段代码的几个问题