Мне нужно выполнить 9 различных операций с координатой, в зависимости от положения координаты. У меня есть функция, которая возвращает координаты позиции вокруг данной координаты (вниз, вверх, влево, вправо или по диагонали). 9 различных операций представляют собой различные возможные «типы» координат; если я имею дело с координатой (0, 0), единственные допустимые операции - right, down-right и down.
У меня есть структура, в которой я храню направления, действительные для каждого типа координат. 4 для угловых координат, 1 для всех внутренних координат и 4 для неугловых столбцов строк ребер.
Поле в структуре, где я храню все направления, представляет собой динамический двумерный массив, называемый «библиотекой». Каждая строка библиотеки будет соответствовать типу координат, содержащему все допустимые направления для этого типа координат. Я не нашел способа назначать значения по одной строке за раз, и я не могу назначать их индивидуально с помощью цикла.
Я пробовал:
searches->library[0][0] = {2, 3, 4, -1};
searches->library[1][0] = {4, 5, 6, -1};
searches->library[2][0] = {2, 3, 4, 5, 6, -1};
searches->library[3][0] = {0, 1, 2, 3, 4, 5, 6, 7, -1};
searches->library[4][0] = {0, 1, 2, -1};
searches->library[5][0] = {0, 6, 7, -1};
searches->library[6][0] = {0, 1, 2, 6, 7, -1};
searches->library[7][0] = {0, 1, 2, 3, 4, -1};
searches->library[8][0] = {0, 4, 5, 6, 7, -1};
Но это дает мне p2AdjacencyMatrix.c:179: error: parse error before '{' token для каждой строки.
Я также пробовал:
searches->library[][9] = {{2, 3, 4, -1},
{4, 5, 6, -1},
{2, 3, 4, 5, 6, -1},
{0, 1, 2, 3, 4, 5, 6, 7, -1},
{0, 1, 2, -1},
{0, 6, 7, -1},
{0, 1, 2, 6, 7, -1},
{0, 1, 2, 3, 4, -1},
{0, 4, 5, 6, 7, -1}};
И результат это p2AdjacencyMatrix.c:189: error: parse error before ']' token
Вот определение структуры:
typedef struct{
int active_length; // Size of active array of searches
int* active; // Active array of searches
int** library; // Library of array of searches
} SearchLibrary;
И выделение памяти для динамического массива:
SearchLibrary* searches;
searches = (SearchLibrary *) malloc(sizeof(SearchLibrary*));
int search_cases = 9, search_directions = 9;
searches->library = (int **) malloc(search_cases * sizeof(int *));
searches->active = (int *) malloc(search_directions * sizeof(int));
int i;
for(i = 0; i < search_cases; i++){
searches->library[i] = (int *) malloc(search_directions * sizeof(int));
}
Как я могу добавить эти значения в каждую строку массива? Я попытался изменить определение своей структуры на статический массив, но это тоже не сработало. Это происходит потому, что я использую указатель на структуру?
Не могли бы вы объяснить, почему это ошибка (и каковы последствия)? Мне пришлось выделить память аналогично другому указателю на структуру в другой части программы, иначе программа вылетела бы. Я не пробовал sizeof (SearchLibrary), так что завтра попробую.
Вы хотите выделить память для объекта SearchLibrary, но sizeof (SearchLibrary *) - это размер указателя или 4 байта (при условии 32-разрядной архитектуры). Размер объекта не менее 12. Когда вы вводите значения в «search->», вы будете писать за небольшим 4-байтовым блоком, который вы выделили, разрушая память.





Вы не можете этого сделать в C. Нет литералов массива, которые можно назначить, есть только выражения инициализации массива.
Я думаю, что решение состоит в том, чтобы просто вычислить требуемое значение по координатам и размеру поля, насколько я понимаю, это должно быть просто.
Кроме того, наличие литерального значения инициализации постоянного размера, по-видимому, противоречит цели динамического распределения всего этого.
Также:
Да, приведите возвращаемое значение malloc () - обычно это требуется. Да, используйте sizeof, даже когда вам не нужно - это значительно упрощает поддержку вашего кода.
в C вам не нужно возвращать malloc. это обычно добавляет к вашему коду бесполезную избыточность (знание того, какой тип вы назначаете). Я согласен, что опускать sizeof - плохая идея
Нет, не приводить malloc к C: он возвращает void *, который может быть неявно преобразован в указатель любого (нефункционального) типа.
подождите, он не рекомендовал опускать sizeof. он просто рекомендует опустить тип и заменить его выражением. я думаю, что это хорошая рекомендация.
Вчера я прочитал несколько вопросов, пытаясь решить эту проблему, и увидел несколько комментариев о том, что не следует возвращать malloc, я буду иметь это в виду, спасибо. Завтра мне нужно будет еще раз подумать над вашим решением, структура должна была не вычислять направления на основе координат
static const int Library0[] = {2, 3, 4, -1};
static const int Library1[] = {4, 5, 6, -1};
static const int Library2[] = {2, 3, 4, 5, 6, -1};
static const int Library3[] = {0, 1, 2, 3, 4, 5, 6, 7, -1};
static const int Library4[] = {0, 1, 2, -1};
static const int Library5[] = {0, 6, 7, -1};
static const int Library6[] = {0, 1, 2, 6, 7, -1};
static const int Library7[] = {0, 1, 2, 3, 4, -1};
static const int Library8[] = {0, 4, 5, 6, 7, -1};
static const int * Library[] = {
Library0, Library1, Library2,
Library3, Library4, Library5,
Library6, Library7, Library8,
};
typedef struct{
int active_length; // Size of active array of searches
const int* active; // Active array of searches
const int** library; // Library of array of searches
} SearchLibrary;
searches->library = Library;
Обновлено: исправлена синтаксическая ошибка.
вы где-нибудь скучаете по []?
Возможно, мне тоже не хватает квалификаторов const.
Я получаю ту же ошибку, что и в другом решении, поэтому мне что-то не хватает: предупреждение: лишние элементы в скалярном инициализаторе предупреждение: (рядом с инициализацией для `Библиотеки ')
За [] все еще не хватает пары int * Library
Спасибо, что обнаружил мои синтаксические ошибки, Чистоф - мне не следовало делать это до утреннего кофе.
Предполагая, что C99, вы можете использовать составной литерал и memcpy() над своей строкой. Для k-й строки это могло бы выглядеть так:
#define SEARCH_DIRECTIONS 9
memcpy(searches->library[k], ((int [SEARCH_DIRECTIONS]){ 1, 2, 3 }),
sizeof(int) * SEARCH_DIRECTIONS);
Я не заметил, что числа представляют максимум 9 направлений. Я думаю, что ваш ответ лучше, учитывая это (так что вам не нужно выполнять динамическое распределение). +1
Мне нужно будет прочитать составные литералы, чтобы увидеть, не упускаю ли я чего-то очевидного, но использование этой строки в моем коде дает следующее: предупреждение: избыточные элементы в инициализаторе массива предупреждение: (около инициализации для `(анонимный) ') для каждый элемент составного литерала. Я попробую еще завтра.
Какой компилятор вы используете? Если gcc, вы указали параметры -std = c99 (или -std = gnu99)?
Да, я использую gcc и пробовал указать -std = c99, но ему все равно не понравилось. Я думаю, что c99 может быть стандартом по умолчанию, потому что я пробовал с c89, и он выдал еще тонны ошибок. Поскольку другое решение работает, я счастлив оставить его здесь, если только это не что-то действительно простое, чего мне не хватает. Спасибо
hm - компилируется здесь ... В этом решении содержимое строк будет вычисляться во время выполнения, тогда как в решении Die in Sente они должны быть известны во время компиляции.
Чтобы уточнить: если значения известны во время компиляции, используйте Die в решении Sente по соображениям производительности. Но помните, что тогда все структуры будут использовать одну и ту же библиотеку!
Да, значения известны во время компиляции, на самом деле они никогда не меняются. И есть только одна структура, которая использует библиотеку, так что проблем нет. Я даже не уверен, что структура мне действительно нужна, я новичок в C и программировании. Но это работает, так что я счастлив. Спасибо за ваши комментарии.
Если значения представляют собой а также времени компиляции, указатели имеют правильный константный тип, данные могут использоваться любым количеством объектов или даже потоков.
ОШИБКА ЗДЕСЬ: search = (SearchLibrary ) malloc (sizeof (SearchLibrary)); должен быть размером (SearchLibrary) !!!