#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 проще, тогда я поддерживаю ваш ответ 🙂