Как вставить элемент в 2d массив в C без потери предыдущего значения?В чем проблема с моей программой?

#c

#c

Вопрос:

 #include<stdio.h>
int main()
{
    int a[4][3],i,j,k,row,col;
    puts("Enter the elemennts");
    for(i=0;i<3;i  )
        for(j=0;j<3;j  )
            scanf("%d",amp;a[i][j]);
    puts("Enter the number:");
    scanf("%d",amp;k);
    puts("Enter row and column:");
    scanf("%d %d",amp;row,amp;col);
    row--; col--;
/**    row-2 col-2*/

    for(i=2;i>=0;i--)
    {
        for(j=2;j>=0;j--)
        {
                a[i 1][j 1]=a[i][j];
                if(i==row amp;amp; j==col-1)
                    break;
        }
    }
        a[row][col]=k;
    for(i=0;i<4;i  )
    {
        for(j=0;j<3;j  )
            printf("%d ",a[i][j]);
        printf("n");
    }
}
  

Здесь, пожалуйста, помогите мне, где я ошибаюсь.

Поскольку я хочу получить вывод, подобный этому образцу вывода:

 1 2 3
4 5 6
6 7 8
Enter the number:32
Enter row and column:2 2
1 2 3
4 32 5
6 6 7
8
  

Комментарии:

1. Массив не лучше всего подходит, если вы ищете «вставку» и «удаление». Просто говорю.

2. Одна ошибка, которую я вижу, заключается в индексации строк в первом цикле for, измените 3 на 4, чтобы получить доступ к 4-й строке

3. Я думаю, что ваш пример вывода неверен. 6 удваивается в качестве входных данных, и после вставки размер массива увеличивается. Это то, чего вы хотите, чтобы произошло?

4. вы перемещаете значение из ячейки a[i][j] в ячейку a[i 1][j 1] , это неверно, смотрите мой ответ

5. @aragon Pehaps вы не заметили, что в примере вывода я ввел ДВА раза 6 на ВХОДЕ, поэтому он должен оставаться там, куда он пойдет? И в моей программе массив НЕ является динамическим, поэтому, когда я пишу int a[4][3], память выделяется, поэтому размер массива не увеличивается

Ответ №1:

В чем проблема с моей программой?

Ваша ошибка в том, a[i 1][j 1]=a[i][j]; что ячейка сразу после i,j не i 1,j 1

Предложение :

 #include<stdio.h>

#define NROW 4
#define NCOL 3

int main()
{
  int a[NROW][NCOL] = { 0};
  int i,j,k,row,col;
  puts("Enter the elements");
  for(i = 0; i<(NROW - 1);   i) {
    for(j = 0; j<NCOL;   j) {
      if (scanf("%d", amp;a[i][j]) != 1) {
        puts("invalid value");
        return -1;
      }
    }
  }
  puts("Enter the number:");
  if (scanf("%d", amp;k) != 1) {
    puts("invalid value");
    return -1;
  }
  printf("Enter row (1..%d) and column (1..%d):", NROW - 1, NCOL);
  if ((scanf("%d %d", amp;row, amp;col) != 2) ||
      (row < 1) || (row >= NROW) || (col < 1) || (col > NCOL)) {
    puts("invalid value");
    return -1;
  }
  row--;
  col--;

  /* i,j at the new last cell position */
  i = NROW - 1;
  j = 0;

  do {
    int previ, prevj; /* the cell before i,j */

    if (j == 0) {
      previ = i - 1;
      prevj = NCOL - 1;
    }
    else {
      previ = i;
      prevj = j - 1;
    }

    a[i][j] = a[previ][prevj];
    i = previ;
    j = prevj;
  } while ((i != row) || (j != col));

  a[row][col] = k;

  for(i = 0; i < NROW;   i)
    {
      for(j = 0; j < NCOL;   j)
        printf("%d ",a[i][j]);
      printf("n");
    }
}
  

Компиляция и выполнение :

 /tmp % gcc -pedantic -Wextra i.c
/tmp % ./a.out
Enter the elements
1 2 3
4 5 6
6 7 8
Enter the number:
32
Enter row (1..3) and column (1..3):
2 2
1 2 3 
4 32 5 
6 6 7 
8 0 0 

/tmp % ./a.out
Enter the elements
1 2 3
4 5 6
6 7 8
Enter the number:
32
Enter row (1..3) and column (1..3):
1 2
1 32 2 
3 4 5 
6 6 7 
8 0 0 
  

Как вы можете видеть, я также проверяю правильность входных данных и использую определения препроцессора NROW и NCOL, чтобы легко изменять размеры массива

Комментарии:

1. спасибо, могу я узнать ваше настоящее имя? кстати, еще раз спасибо за отличную программу. Почему условие row-col в scanf в строке 26 — -> col> NCOL 1 почему 1?

Ответ №2:

Поскольку 2D массив (он же array of array) основан на последовательной памяти, вы можете упростить код, используя memmove .

Функция для вставки значения с индексом r, c может быть такой простой, как:

 #define ROWS 4
#define COLS 3

void insert_arr(int r, int c, int a[][COLS], int v)
{
  size_t elements_to_move = ROWS * COLS - (r * COLS   c   1);
  memmove(amp;a[r][c]   1, amp;a[r][c], sizeof(int) * elements_to_move);
  a[r][c] = v;
}
  

Пример программы:

 void print_arr(int a[][COLS])
{
  for (int i=0; i<ROWS;   i)
  {
    for (int j=0; j<COLS;   j) printf("M ", a[i][j]);
    printf("n");
  }
}

int  main()
{
  int a[ROWS][COLS];
  for (int i=0; i<ROWS;   i)
  {
    for (int j=0; j<COLS;   j) a[i][j] = 10*i   j;
  }

  print_arr(a);
  printf("------------------n");
  insert_arr(1, 1, a, 9);
  print_arr(a);
}
  

Вывод:

    0    1    2
  10   11   12
  20   21   22
  30   31   32
------------------
   0    1    2
  10    9   11
  12   20   21
  22   30   31
  

Комментарии:

1. Я не следую этому пути, потому что я не помню, указано ли в норме явно, что все ячейки в памяти являются последовательными… и мне было лень проверять ^^. Конечно, если это верно, использовать это свойство упрощает работу и дает лучшее решение.

2. @bruno Стандарт требует последовательной компоновки. Поэтому я думаю, memmove что это простое решение. Однако, я думаю, ваш ответ более полезен для OP, поскольку он сообщает, что OP сделал неправильно. То есть… OP может узнать больше из вашего ответа 🙂 Это также то, что говорит голосование. Я только что опубликовал это решение в качестве альтернативы (которое я считаю более простым).

3. Спасибо, что ответили мне, и я согласен с вами в этих условиях, memmove проще, тогда я поддерживаю ваш ответ 🙂