2009-04-21 3 views
3

Это такой глупый вопрос, который вызывает разочарование, даже спрашивая об этом. Пожалуйста, медведь со мной, я чувствую себя особенно тупой над этим сегодня ....C жесткое кодирование массива typedef struct

У меня есть библиотека с определенной структурой typedef. в основном:

typedef struct {int x; int y;} coords; 

То, что я действительно хотел сделать, это объявить в моем заголовке переменного массива следующим образом:

coords MyCoords[]; 

(я недавно перешел его просто coords *MyCoords;, а затем побежал MyCoords = new coords[4];)

, а затем в моем init я хотел бы записать в нем некоторые значения.

MyCoords[] = {{0, 0}, {2, 2} etc. 

Я просто должен быть brainfarting сегодня, потому что не позволил мне сделать какой-либо способ просто положить в еще что-то простое, как MyCoords[0] = {0, 0}

жалком о некоторых из выше синтаксиса. Спасибо за любую помощь. Я даже не забочусь о жестком кодировании всех значений сразу. Теперь я отлично справляюсь с работой MyCoords[0] = {0, 0}. Я мог бы сделать MyCoords[0].x = 0; MyCoords[0].y = 0, но тогда я бы никогда не понял, что я делаю неправильно. Спасибо большое любому.

+0

Это похоже на C, а не на C++. Синтаксис typedef необходим только в C, а переменные массивы являются только законными в C. Я изменил название и тег, чтобы отразить это. Это должно дать вам более релевантные ответы :) – jalf

+0

Я воспринял это как C++, потому что он говорит о «новых коордах [4]», а в C допустимо, чтобы такой гибкий член массива появился только в конце структуры. Если оно появляется в filescope, это предварительное определение. –

+0

Хм, правда о «новом». Не заметил этого. Но он также упоминает массивы переменной длины, которые определенно не являются C++. Некоторые разъяснения будут полезны. :) – jalf

ответ

5

Ну, что вы создали не является переменным массивом. Это массив, размер которого неизвестен. Этот массив имеет неполный тип и поэтому не может быть определен в C++. Вы можете сделать это просто декларацией, поставив перед ним extern.

extern coords MyCoords[]; 

Затем в файл .cpp, который инициализирует его, вы можете создать (определить), что массив - будьте осторожны, вы должны сделать это в области видимости пространства имен, вне любой функции, конечно:

coords MyCoords[] = {{1, 2}, {3, 4}, ... }; 

Если то, что вы хотите, это массив, размер которого не известен во время компиляции еще, а во время выполнения, вы должны использовать std::vector:

std::vector<coords> MyCoords; 

Тогда позже, если вы заполнить его, сделать

MyCoords.push_back(coords(1, 2)); 
MyCoords.push_back(coords(3, 4)); 
.... 

Или создать локальный массив, а затем инициализировать вектор с использованием копии элементов этого массива:

coords c[] = ....; 
MyCoords.insert(MyCoords.end(), c, c + sizeof c/sizeof *c); 

Ну, в C, она немного отличается, чем в C++. Вы можете определить массив, размер которого неизвестен. Что происходит, так это то, что принято считать «предварительным» определением.Если в конце файла (точнее, его единицы перевода, который является этим файлом, и всех файлов, которые он включает в себя, что означает все, что компилятор переводит вместе), нет последующего определения его, которое включает размер, тогда размер принимается равным 1. Однако в C++ нет предварительных определений, а определение, которое не включает размер и не содержит инициализатор, который может определить размер, является недопустимой программой на C++.

По той причине, почему ваш код идет Grazy, вы делаете

MyCoords[0] = {0, 0} 

Какой компилятор будет читаться как:

-> Set LHS to RHS 
-> -> LHS is a variable of type `coords`. Fine 
-> -> RHS is... hmm, `{0, 0}`. What the heck is it?? 

Вы видите, компилятор не имеет понятия, что правая рука подразумевается. C99, по этой причине (версия С версии 1999 г.) введены так называемые сложные литералы. Это позволяет писать

MyCoords[0] = (coords){0, 0}; 

И это будет на самом деле делать то, что вы хотите, чтобы это сделать, - создание правой частью значения типа coord и присваивает его левую сторону. Но вы должны просто, уже из соображений совместимости (многие компиляторы C не являются разумными C99-совместимыми, и ни C++, ни C89 не поддерживают сложные литералы), используйте один из предыдущих способов, которые я показал вам.

9

Вы можете инициализировать массив только в том месте, где вы его объявляете. Форма, которая будет работать в:

coords MyCoords[] = {{0, 0}, {2, 2}}; 

Если вам нужно объявить MyCoords в заголовке, так что многие модули могут получить доступ к нему, я думаю, что следующий будет работать:

extern coords MyCoords[]; 
2

Я не уверен, является ли это также проблема в Вашем коде, но:

typedef struct coords {int x, int y}; 

не полная декларация ЬурейеЕ в C, так как он не дает имя к типа , только для структуры (теги структуры не находятся в том же пространстве имен, что и имена типов в стандарте C). Для того, чтобы сделать заявление ЬурейеЕ правильно, вы должны указать имя для всего типа struct coords {int x, int y}, как если бы вы были объявить переменную этого типа, например, так:

typedef struct coords {int x, int y} coords; 
0

Оно должно быть:

typedef struct coords {int x, int y} coords; 
coords MyCoords[] = {{0, 0}, {2, 2}, {3, 4}}; 
Смежные вопросы