2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 
Сообщение13.12.2007, 14:29 
Помогите ,плиз .Написал прогу на Си с использыванием одномерних массивов , преподаватель потребовал переписать прогу с использованием двухмерных массивов.Приведите,пожалуйста пример, как переводится двухмерный массив в одномерный.
Буду очень благодарен,т.к. я попробывал сам это сделать и прога перестала компилироваться.
Вот прога ,которую надо переписать ,изменив одномерные массивы на двумерные:
#include <windows.h>

#include <stdio.h>

const int size = 8; // размер доски

int table[size*size]; // соственно сама доска

int point[2] = {0,1}, // точка, куда должен попасть конь
knightPos[2] = {4,2}, // начальная позиция коня
moves = 0; // сколько шагов нужно

void initTable(int* table, int size, int p[2]); // сначала таблица "не хожена", кроме точки
void movesKnight(int* table, int size); // сделать ходы из всех "хоженных" точек
int checkPass(int* table, int size, int kP[2]); // проверить, если путь пройден

int main()
{
initTable(table, size, point);
do
{
movesKnight(table, size);
}
while(checkPass(table, size, knightPos) == -1);

printf("\nresult = %d", moves);
return 0;
}

void initTable(int* table, int size, int p[2])
{
int i, j;
for(i = 0; i < size; i++)
{
for(j = 0; j < size; j++)
{
table[i*size + j] = -1;
}
}
table[p[0]*size + p[1]] = 0;
}

void movesKnight(int* table, int size)// делаем ходы из всех "хоженных точек"
{
int i, j;
for(i = 0; i < size; i++)
{
for(j = 0; j < size; j++)
{
if(table[i*size + j] == moves)
{
if(i+1 < 8 && j+2 < 8 && table[(i+1)*size + (j+2)] == -1)
{
table[(i+1)*size + (j+2)] = moves+1;
}
if(i+2 < 8 && j+1 < 8 && table[(i+2)*size + (j+1)] == -1)
{
table[(i+2)*size + (j+1)] = moves+1;
}
if(i+1 < 8 && j-2 >= 0 && table[(i+1)*size + (j-2)] == -1)
{
table[(i+1)*size + (j-2)] = moves+1;
}
if(i-1 >= 0 && j+2 < 8 && table[(i-1)*size + (j+2)] == -1)
{
table[(i-1)*size + (j+2)] = moves+1;
}
if(i+2 < 8 && j-1 >= 0 && table[(i+2)*size + (j-1)] == -1)
{
table[(i+2)*size + (j-1)] = moves+1;
}
if(i-1 >= 0 && j-2 >=0 && table[(i-1)*size + (j-2)] == -1)
{
table[(i-1)*size + (j-2)] = moves+1;
}
if(i-2 >= 0 && j+1 < 8 && table[(i-2)*size + (j+1)] == -1)
{
table[(i-2)*size + (j+1)] = moves+1;
}
if(i-2 >= 0 && j-1 >= 0 && table[(i-2)*size + (j-1)] == -1)
{
table[(i-2)*size + (j-1)] = moves+1;
}
}
}
}
moves++;
}

int checkPass(int* table, int size, int kP[2])// проверяем,если путь пройден .
{
return table[kP[0]*size + kP[1]];
}

}

 
 
 
 
Сообщение13.12.2007, 14:35 
Dmytro Sheludchenko писал(а):
Написал прогу на Си с использыванием одномерних массивов , преподаватель потребовал переписать прогу с использованием двухмерных массивов.
Странный какой-то преподаватель ... нас учат, наоборот, все в одномерных массивах хранить, так как они быстрее работают ... Ну аккуратно заменяем

int table[size*size]
на
int table[size][size],

int* table
на
int** table

и все надписи вида table[i*size + j]
на table[i][j] (ну или table[j][j], сообразите там).

об ошибках докладываем - я ведь не знаю, какой у вас там компилятор.

 
 
 
 
Сообщение13.12.2007, 14:37 
Аватара пользователя
Отделено в самостоятельную тему

 
 
 
 
Сообщение14.12.2007, 18:22 
Аватара пользователя
:evil:
Dmytro Sheludchenko писал(а):
Написал прогу на Си с использыванием одномерних массивов , преподаватель потребовал переписать прогу с использованием двухмерных массивов.


AD писал(а):
Странный какой-то преподаватель ...

Поддерживаю. Странный какой-то преподаватель … И задание странное.

Дело в том, что в С в принципе нет двумерных массивов. «int table[size][size]» — это не двумерный массив, а массив массивов, что не одно и тоже. В частности, каждый из элементов table нужно проинициализировать, либо при помощи malloc(), либо отведя большой массив (size * size) и разместив в нём.

 
 
 
 
Сообщение15.12.2007, 13:48 
Аватара пользователя
незваный гость писал(а):
Дело в том, что в С в принципе нет двумерных массивов. «int table[size][size]» — это не двумерный массив, а массив массивов, что не одно и тоже.

Я не большой знаток Си, но рискну не согласиться. Это одно и то же. Когда я объявляю int table[size][size], то память выделяется под весь массив массивов статически (ну или в стеке, если это локальная переменная). Проверил в Borland C++ и в MSVC 6.0 — работает. Единственно, что — size должно быть константным выражением, т.е. const int не проходит, нужно #define size <Нужный_размер>.

Что касается исходного вопроса Dmytro Sheludchenko — то тут нужно подумать, как передавать массив. Просто int *table, как в исходной программе, не пройдёт, т.к. теряется информация о структуре (массив передаётся как одномерный). int **table — это вообще будет ошибкой, т.к. это указатель на массив указателей на массивы типа int, а у нас массив массивов — это, действительно, разные вещи.

Самый простой вариант — когда таблица table не передаётся в функции (initTable, movesKnight), а просто в функциях используется глобальная переменная table.
Может ещё сделать что-то типа typedef int[size] row; и передавать в функции row *table.

 
 
 
 
Сообщение15.12.2007, 18:15 
А теперь верно?
#include <windows.h>
#include <stdio.h>

const int size = 8; // ðàçìåð äîñêè

int table[size][size]; // ñîñòâåííî ñàìà äîñêà

int point[2] = {0,1}, // òî÷êà, êóäà äîëæåí ïîïàñòü êîíü
knightPos[2] = {4,2}, // íà÷àëüíàÿ ïîçèöèÿ êîíÿ
moves = 0; // ñêîëüêî øàãîâ íóæíî

void initTable(int** table, int size, int p[2]); // ñíà÷àëà òàáëèöà "íå õîæåíà", êðîìå òî÷êè
void movesKnight(int** table, int size); // ñäåëàòü õîäû èç âñåõ "õîæåííûõ" òî÷åê
int checkPass(int** table, int size, int kP[2]); // ïðîâåðèòü, åñëè ïóòü ïðîéäåí

int main()
{
initTable(table, size, point);
do
{
movesKnight(table, size);
}
while(checkPass(table, size, knightPos) == -1);

printf("\nresult = %d", moves);
return 0;
}

void initTable(int** table, int size, int p[2])
{
int i, j;
for(i = 0; i < size; i++)
{
for(j = 0; j < size; j++)
{
table[i][j] = -1;
}
}
table[p[0]][p[1]] = 0;
}

void movesKnight(int** table, int size)// äåëàåì õîäû èç âñåõ "õîæåííûõ òî÷åê"
{
int i, j;
for(i = 0; i < size; i++)
{
for(j = 0; j < size; j++)
{
if(table[i][j] == moves)
{
if(i+1 < 8 && j+2 < 8 && table[(i+1)][(j+2)] == -1)
{
table[(i+1)][(j+2)] = moves+1;
}
if(i+2 < 8 && j+1 < 8 && table[(i+2)][(j+1)] == -1)
{
table[(i+2)][(j+1)] = moves+1;
}
if(i+1 < 8 && j-2 >= 0 && table[(i+1)][(j-2)] == -1)
{
table[(i+1)][(j-2)] = moves+1;
}
if(i-1 >= 0 && j+2 < 8 && table[(i-1)][(j+2)] == -1)
{
table[(i-1)][(j+2)] = moves+1;
}
if(i+2 < 8 && j-1 >= 0 && table[(i+2)][(j-1)] == -1)
{
table[(i+2)][(j-1)] = moves+1;
}
if(i-1 >= 0 && j-2 >=0 && table[(i-1)][(j-2)] == -1)
{
table[(i-1)][(j-2)] = moves+1;
}
if(i-2 >= 0 && j+1 < 8 && table[(i-2)][(j+1)] == -1)
{
table[(i-2)][(j+1)] = moves+1;
}
if(i-2 >= 0 && j-1 >= 0 && table[(i-2)][(j-1)] == -1)
{
table[(i-2)][(j-1)] = moves+1;
}
}
}
}
moves++;
}

int checkPass(int** table, int size, int kP[2])// ïðîâåðÿåì,åñëè ïóòü ïðîéäåí .
{
return table[kP[0]][kP[1]];
}

 
 
 
 
Сообщение15.12.2007, 19:10 
Аватара пользователя
Нет. У Вас компилятора нету, что ли? Не компилируется же :roll:
int table[size][size]; — expected constant expression (надо #define Size 8, и разделить Size и size)

initTable(table, size, point); — int ** ' differs in levels of indirection from 'int [8][8]' (то, о чём я писал в предыдущем сообщении:
я писал(а):
int **table — это вообще будет ошибкой, т.к. это указатель на массив указателей на массивы типа int, а у нас массив массивов — это, действительно, разные вещи.
)

Ну и как результат — Unhandled exception...

Добавлено спустя 4 минуты 24 секунды:

Самый простой вариант — это избавиться от параметров table и size в функциях initTable, movesKnight и checkPass вообще (использовать глобальную переменную table, и #define size 8 — тогда не понадобится разделять size и Size).

Добавлено спустя 3 минуты 26 секунд:

У меня получилось:
Код:
result = 3

 
 
 
 
Сообщение15.12.2007, 21:01 
Компилятор у меня,есть только он заглючил,когда я нажал на компиляцию переделанной программы.У Вас получился правильный результат.Не могли показать хотя бы часть кода ? :D

 
 
 
 
Сообщение16.12.2007, 08:29 
Аватара пользователя
worm2 писал(а):
Я не большой знаток Си, но рискну не согласиться.

Думаю, что Вы правы. :oops: К стыду своему. :oops: :oops: Хотя (технически) int a[5][5] — это массив массивов, по существу Вы правы.

 
 
 
 
Сообщение16.12.2007, 11:14 
Аватара пользователя
Dmytro Sheludchenko писал(а):
Компилятор у меня,есть только он заглючил,когда я нажал на компиляцию переделанной программы.У Вас получился правильный результат.Не могли показать хотя бы часть кода ? :D


Код:
...

#define size 8

int table[size][size];

void initTable(int p[2]); // в реализации так же
void movesKnight(void); // в реализации так же
int checkPass(int kP[2]); // в реализации так же

...

initTable(point);
do
{
movesKnight();
}
while(checkPass(knightPos) == -1);

...

Остальное как у Вас.

 
 
 
 
Сообщение16.12.2007, 11:46 
worm2 писал(а):
Dmytro Sheludchenko писал(а):
Компилятор у меня,есть только он заглючил,когда я нажал на компиляцию переделанной программы.У Вас получился правильный результат.Не могли показать хотя бы часть кода ? :D


Код:
...

#define size 8

int table[size][size];

void initTable(int p[2]); // в реализации так же
void movesKnight(void); // в реализации так же
int checkPass(int kP[2]); // в реализации так же

...

initTable(point);
do
{
movesKnight();
}
while(checkPass(knightPos) == -1);

...

Остальное как у Вас.

А дальше код будет такой же,как в программа ,что я отправлял вчера?Только я теперь везде буду использовать глобальные переменные.верно ?

 
 
 
 
Сообщение17.12.2007, 13:23 
Аватара пользователя
Ну да. Только ещё в реализации:
Код:
void initTable(int p[2])
{как раньше}
void movesKnight(void)
{как раньше}
int checkPass(int kP[2])
{как раньше}

и всё. Больше ничего не надо переделывать. Глобальные переменные "автоматически" будут использоваться вместо локальных.

 
 
 [ Сообщений: 12 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group