Как присвоить значения всей строке динамического двумерного массива?

Мне нужно выполнить 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));
}

Как я могу добавить эти значения в каждую строку массива? Я попытался изменить определение своей структуры на статический массив, но это тоже не сработало. Это происходит потому, что я использую указатель на структуру?

ОШИБКА ЗДЕСЬ: search = (SearchLibrary ) malloc (sizeof (SearchLibrary)); должен быть размером (SearchLibrary) !!!

Die in Sente 21.01.2009 18:25

Не могли бы вы объяснить, почему это ошибка (и каковы последствия)? Мне пришлось выделить память аналогично другому указателю на структуру в другой части программы, иначе программа вылетела бы. Я не пробовал sizeof (SearchLibrary), так что завтра попробую.

bob esponja 22.01.2009 02:42

Вы хотите выделить память для объекта SearchLibrary, но sizeof (SearchLibrary *) - это размер указателя или 4 байта (при условии 32-разрядной архитектуры). Размер объекта не менее 12. Когда вы вводите значения в «search->», вы будете писать за небольшим 4-байтовым блоком, который вы выделили, разрушая память.

Die in Sente 24.01.2009 05:44
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
3
3 234
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы не можете этого сделать в C. Нет литералов массива, которые можно назначить, есть только выражения инициализации массива.

Я думаю, что решение состоит в том, чтобы просто вычислить требуемое значение по координатам и размеру поля, насколько я понимаю, это должно быть просто.

Кроме того, наличие литерального значения инициализации постоянного размера, по-видимому, противоречит цели динамического распределения всего этого.

Также:

  • Не приводите возвращаемое значение malloc () в C
  • Не используйте sizeof для типов, когда вам это не нужно, например search = malloc (sizeof * search); и так далее

Да, приведите возвращаемое значение malloc () - обычно это требуется. Да, используйте sizeof, даже когда вам не нужно - это значительно упрощает поддержку вашего кода.

Die in Sente 21.01.2009 18:23

в C вам не нужно возвращать malloc. это обычно добавляет к вашему коду бесполезную избыточность (знание того, какой тип вы назначаете). Я согласен, что опускать sizeof - плохая идея

Johannes Schaub - litb 21.01.2009 18:26

Нет, не приводить malloc к C: он возвращает void *, который может быть неявно преобразован в указатель любого (нефункционального) типа.

Christoph 21.01.2009 18:26

подождите, он не рекомендовал опускать sizeof. он просто рекомендует опустить тип и заменить его выражением. я думаю, что это хорошая рекомендация.

Johannes Schaub - litb 21.01.2009 18:33

Вчера я прочитал несколько вопросов, пытаясь решить эту проблему, и увидел несколько комментариев о том, что не следует возвращать malloc, я буду иметь это в виду, спасибо. Завтра мне нужно будет еще раз подумать над вашим решением, структура должна была не вычислять направления на основе координат

bob esponja 22.01.2009 02:32
Ответ принят как подходящий
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;

Обновлено: исправлена ​​синтаксическая ошибка.

вы где-нибудь скучаете по []?

Christoph 21.01.2009 18:25

Возможно, мне тоже не хватает квалификаторов const.

Die in Sente 21.01.2009 18:35

Я получаю ту же ошибку, что и в другом решении, поэтому мне что-то не хватает: предупреждение: лишние элементы в скалярном инициализаторе предупреждение: (рядом с инициализацией для `Библиотеки ')

bob esponja 22.01.2009 02:39

За [] все еще не хватает пары int * Library

Christoph 22.01.2009 03:51

Спасибо, что обнаружил мои синтаксические ошибки, Чистоф - мне не следовало делать это до утреннего кофе.

Die in Sente 24.01.2009 05:37

Предполагая, что C99, вы можете использовать составной литерал и memcpy() над своей строкой. Для k-й строки это могло бы выглядеть так:

#define SEARCH_DIRECTIONS 9

memcpy(searches->library[k], ((int [SEARCH_DIRECTIONS]){ 1, 2, 3 }),
    sizeof(int) * SEARCH_DIRECTIONS);

Я не заметил, что числа представляют максимум 9 направлений. Я думаю, что ваш ответ лучше, учитывая это (так что вам не нужно выполнять динамическое распределение). +1

Johannes Schaub - litb 21.01.2009 19:11

Мне нужно будет прочитать составные литералы, чтобы увидеть, не упускаю ли я чего-то очевидного, но использование этой строки в моем коде дает следующее: предупреждение: избыточные элементы в инициализаторе массива предупреждение: (около инициализации для `(анонимный) ') для каждый элемент составного литерала. Я попробую еще завтра.

bob esponja 22.01.2009 02:23

Какой компилятор вы используете? Если gcc, вы указали параметры -std = c99 (или -std = gnu99)?

Christoph 22.01.2009 03:47

Да, я использую gcc и пробовал указать -std = c99, но ему все равно не понравилось. Я думаю, что c99 может быть стандартом по умолчанию, потому что я пробовал с c89, и он выдал еще тонны ошибок. Поскольку другое решение работает, я счастлив оставить его здесь, если только это не что-то действительно простое, чего мне не хватает. Спасибо

bob esponja 23.01.2009 01:25

hm - компилируется здесь ... В этом решении содержимое строк будет вычисляться во время выполнения, тогда как в решении Die in Sente они должны быть известны во время компиляции.

Christoph 23.01.2009 17:04

Чтобы уточнить: если значения известны во время компиляции, используйте Die в решении Sente по соображениям производительности. Но помните, что тогда все структуры будут использовать одну и ту же библиотеку!

Christoph 23.01.2009 17:06

Да, значения известны во время компиляции, на самом деле они никогда не меняются. И есть только одна структура, которая использует библиотеку, так что проблем нет. Я даже не уверен, что структура мне действительно нужна, я новичок в C и программировании. Но это работает, так что я счастлив. Спасибо за ваши комментарии.

bob esponja 23.01.2009 20:35

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

Die in Sente 24.01.2009 05:36

Другие вопросы по теме