2016-11-06 2 views
-2

У меня есть эти две структуры:Как передать сложный массив структур функции?

const int fleetSize = 5; 
const int fieldSize = 5; 

struct Location { 
    int x; // 1 through fieldSize 
    char y; // 'a' through fieldSize 
}; 

struct Ship { 
    Location loc; 
    bool sunk; 
}; 

У меня также есть этот прототип в файле заголовка:

void initialize(Ship[]); 

В основном, я вызываю функцию из отдельного исходного файла, который должен назначить - 1 для всех значений «х» расположение и «*» для всех «у» значений, обозначаемых здесь:

int main() 
{ 
    Ship myFleet[fleetSize]; 
    initialize(myFleet); 
} 

Моя проблема, я понятия не имею, куда идти отсюда. Все у меня есть это:

void initialize (int a[]) 
{ 
    for (int i = 0; i < fleetSize; i++) 
    { 
     a[i] = -1; 
    } 
} 

Я понятия не имею, что это даже делать, если что-нибудь, потому что я не могу отлаживать в связи с большим количеством ошибок LNK я не могу понять, как. Так что мой вопрос в том, правильно ли это? И если да, то как мне начать присваивать звездочку каждому «y»?

Итак, каждый элемент x должен быть -1, и каждый элемент y должен быть *.

+6

Использование 'зЬй :: VECTOR' или' зЬй :: array'; их легче передать, чем массив. –

+0

Прошу прощения, я должен был отметить, что это проект для школы. Мне грустно нужно использовать структуры :( – Inert

+2

Так что используйте структуры. 'Vector' не останавливается на этом.' Std :: vector myFleet; 'Также читайте о конструкторах, которые сделают вашу работу намного проще даже с массивом – user4581301

ответ

0
a[i].loc.x = -1; 
a[i].loc.y = '*'; 
+0

Я получаю сообщение об ошибке, что мое выражение должно иметь тип класса? Что все это значит? Разве это не массив, обозначенный параметром функции? – Inert

+0

О, я пропустил, что вы ожидаете массив ints.Это никогда не будет работать.Мы должны принять массив корабля.И нет, это не массив, а указатель.Тем не менее, массивы и указатели принимают тот же синтаксис. 'a [i]' то же самое, что ' * (a + i) '. –

+1

Кроме того, ответ user48something лучше и правильный способ сделать это на C++. Но если вы отвечаете на домашнюю проблему, вы можете застрять в этом так. Просто имейте в виду, что это не idiomatic C++. –

1

Использовать конструкторы.

struct Location { 
    int x; // 1 through fieldSize 
    char y; // 'a' through fieldSize 

    // constructor 
    Location(): x(-1), y(`*`) 
    { 
    ) 
}; 

Теперь каждый раз, когда вы делаете место, он всегда будет выходить с x == -1 и y == '*' без каких-либо дополнительных усилий. С

struct Ship { 
    Location loc; 
    bool sunk; 
    Ship(): sunk(false) 
    { 
    } 
}; 

каждый Ship выходит из фабрики unsunk и на -1, '*'.

Так

Ship myFleet[fleetSize]; 

Просто сделал и инициализируется fleetSize unsunk Ship с при -1, '*' без каких-либо дополнительных усилий с вашей стороны.

Что касается передачи массива, то при вызове функции с массивом размер массива теряется. Прочтите What is array decaying?.

Так

void initialize(Ship[]); 

может быть

void initialize(Ship ships[fleetsize]); 

если fleetsize является константой времени компиляции, значение, заданное в коде и не может быть изменен таким образом, что компилятор может генерировать индексы массива, и знать размер, позволяющий некоторые оптимизации.

Или

void initialize(Ship * ships, size_t fleetsize); 

если fleetsize не является фиксированной величиной и может изменяться во время выполнения. Динамический fleetsize может привести к тому, что программа должна управлять динамической памятью, и это может быть сложнее, чем кажется.

Но ...

C++ предлагает ряд «контейнеров», которые могут использоваться вместо массивов. Эти контейнеры знают свой размер, управляют динамической памятью для вас и, как правило, облегчают жизнь с помощью массива инструментов просеивания, поиска и сортировки, построенных прямо в or in the <algorithm> library. Два, которые выглядят особенно полезными для вашего использования, - std::vector, a dynamic array и std::array, a statically-sized array.

Edit: Случайное МЕСТОПОЛОЖЕНИЕ

RNG установить код злорадно похищенное из: std::uniform_int_distribution

#include <random> 

std::random_device rd; // cannot be trusted with mingw. Use time(null) instead 
std::mt19937 gen(rd()); 
std::uniform_int_distribution<> dis(1, 5); 

struct Location { 
    int x; // 1 through fieldSize 
    char y; // 'a' through fieldSize 

    // constructor. Note 
    Location() 
    { 
     do 
     { 
      x = dis(gen); // number 
      y = 'a'+dis(gen)-1; // requires sequentially ordered character set like ASCII 
     } while(locIsOccupied(x,y)); // ensure x and y are unused. 
    ) 
}; 

Я оставил locIsOccupied невыполненным.

Еще один глупый трюк является

vector<Location> locations, содержащий все возможные Locations. random_shufflelocations и

struct Ship { 
    Location loc; 
    bool sunk; 

    // construct Ship with location from available pool 
    // using locations.back() because it's cheapest to remove the last item 
    Ship(): loc(locations.back()), sunk(false) 
    { 
     locations.pop_back(); // remove location so it can't be chosen again 
    } 
}; 
+0

Спасибо за совет. Я предполагаю, что проблема не в том, чтобы опубликовать весь мой код в Интернете или просить помощи в Интернете в целом, так это отсутствие контекста. Я действительно должен установить местоположение в -1 и *, но затем случайным образом создать местоположение для 5 кораблей в сетке 5x5 1-5 и a-e. Подобно реальной игре линкора. Независимо от того, благодарю вас за то, что вы нашли время, чтобы помочь мне. – Inert

+0

Не проблема. Нет причин, по которым вы не можете выполнять случайное позиционирование внутри конструктора. Вам просто нужно убедиться, что вы не разместите два корабля в одном месте. – user4581301

+0

@ChristianVokurka добавил пару простых идей о том, как рандомизировать места – user4581301

0
void initialize(Ship[]); 

обозначает функция называется initialize, который принимает массив Ship с неизвестного размера и ничего не возвращает.

Вы не можете перебрать массив, если вы не знаете его размер:

void initialize(Ship[] array, std::size_t size) 
{ 
    for (std::size_t i = 0; i < size; ++i) 
    { 
     array[i].loc.x = -1; 
     array[i].loc.y = '*'; 
    } 
} 
+0

Да, я понимаю, что вы говорите. Весь этот код был предоставлен мне моим инструктором, который специально сказал нам не изменять свой код, а только добавлять наши собственные, чтобы заставить его работать. Я все еще новичок во всем этом, но я готов поспорить, что здесь есть связь размера. В основном это так; Корабль myFleet [fleetSize]; - это действительно корабль myfleet [5], поскольку fleetsize является константой.Затем он написал инициализацию (myFleet); что заставляет меня поверить, что где-то в другом месте предполагается, что размер объявляется, поскольку он не передается функции. По крайней мере, я думаю ... – Inert

+0

Является ли это постоянным глобальным? Если да, функция будет иметь к нему доступ. –

Смежные вопросы