2014 dxdy logo

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

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




Начать новую тему Ответить на тему
 
 
Сообщение13.12.2007, 14:29 


06/10/07
68
Sverige
Помогите ,плиз .Написал прогу на Си с использыванием одномерних массивов , преподаватель потребовал переписать прогу с использованием двухмерных массивов.Приведите,пожалуйста пример, как переводится двухмерный массив в одномерный.
Буду очень благодарен,т.к. я попробывал сам это сделать и прога перестала компилироваться.
Вот прога ,которую надо переписать ,изменив одномерные массивы на двумерные:
#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 
Экс-модератор


17/06/06
5004
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 
Супермодератор
Аватара пользователя


29/07/05
8248
Москва
Отделено в самостоятельную тему

 Профиль  
                  
 
 
Сообщение14.12.2007, 18:22 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:
Dmytro Sheludchenko писал(а):
Написал прогу на Си с использыванием одномерних массивов , преподаватель потребовал переписать прогу с использованием двухмерных массивов.


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

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

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

 Профиль  
                  
 
 
Сообщение15.12.2007, 13:48 
Заслуженный участник
Аватара пользователя


01/08/06
3054
Уфа
незваный гость писал(а):
Дело в том, что в С в принципе нет двумерных массивов. «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 


06/10/07
68
Sverige
А теперь верно?
#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 
Заслуженный участник
Аватара пользователя


01/08/06
3054
Уфа
Нет. У Вас компилятора нету, что ли? Не компилируется же :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 


06/10/07
68
Sverige
Компилятор у меня,есть только он заглючил,когда я нажал на компиляцию переделанной программы.У Вас получился правильный результат.Не могли показать хотя бы часть кода ? :D

 Профиль  
                  
 
 
Сообщение16.12.2007, 08:29 
Заслуженный участник
Аватара пользователя


17/10/05
3709
worm2 писал(а):
Я не большой знаток Си, но рискну не согласиться.

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

 Профиль  
                  
 
 
Сообщение16.12.2007, 11:14 
Заслуженный участник
Аватара пользователя


01/08/06
3054
Уфа
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 


06/10/07
68
Sverige
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 
Заслуженный участник
Аватара пользователя


01/08/06
3054
Уфа
Ну да. Только ещё в реализации:
Код:
void initTable(int p[2])
{как раньше}
void movesKnight(void)
{как раньше}
int checkPass(int kP[2])
{как раньше}

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

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 12 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group