Передача указателя на структуру в качестве параметра

У меня есть структура, которую я установил, и указатель на структуру, которая в основном представляет собой массив. Я хочу создать функцию, которая изменяет определенные значения в структуре, но не могу понять, как передать указатель структуры в качестве параметра.

struct deviations {
    int switch;
    int x;
    int y;
};

struct deviations *pdevs = malloc(24 * sizeof(int));

for(int i = 0; i < 8; i++) {
    (pdevs + i)->switchez = 1;
    (pdevs + i)->x = 0;
    (pdevs + i)->y = 0;
}

int top[3] = {0, 1, 2};
int bottom[3] = {5, 6, 7};
int left[3] = {0, 3 ,5};
int right[3] = {2, 4, 7};

for(int i = 0; i < 3; i++) {
   (pdevs + top[i])->y = -1; 
}

У меня есть несколько (8) for loops, как указано выше, и в каждом из них базовая структура одинакова, за исключением изменения массива ("верх"), lvalue ('y') и rvalue ('-1') в каждом. Я не могу понять, как правильно объявить функцию со структурой / указателем на структуру.

В настоящее время у меня есть около 26 строк кода (8 для повторяющихся циклов), и я почти уверен, что смогу сжать его до аккуратной маленькой функции, если я смогу выяснить, как передать указатель на структуру. Любая помощь приветствуется!

Этот фрагмент является частью более крупной функции / программы, которая определяет, нужно ли проверять окружающие элементы (3 вверху, 3 внизу, по одному с каждой стороны). Я установил структуру с переключателем включения / выключения в зависимости от положения базового элемента и смещения x / y. Я пытаюсь сдвинуть каждую отдельную ячейку на определенную величину + 1 / -1 / или 0 в позиции x или y. И я пытаюсь включить или выключить переключатель в зависимости от определенных условий относительно x или y исходной ячейки. Malloc, вероятно, не нужен, но я не уверен, будет ли этот массив структур использоваться снова позже, если нет, я удалю вызов malloc.

Спасибо!

Вы должны использовать sizeof(struct deviations) в вызове malloc().

Barmar 25.10.2018 04:34

предложенная вами декларация sizeof определенно подходит, спасибо!

Ali Z 25.10.2018 04:37

Упс ... Нажал не ту клавишу и отредактировал другой комментарий. Вместо этого вы должны использовать pdevs[top[i]]->y. А еще я предлагаю вам использовать макрос.

Hoblovski 25.10.2018 04:37

Было бы хорошо, если бы вы не пропустили код, который действительно демонстрирует, что вы пытаетесь сделать. Вместо этого вы пытались описать код словами, что сбивает с толку.

paddy 25.10.2018 04:37

И было бы легче понять, если бы вы написали pdevs[top[i]].y = -1

Barmar 25.10.2018 04:37

Кроме того, если вам нужно было установить элементы несколько в struct, вы могли бы сделать (например): for (int i = 0; i < 3; ++i) { struct deviations *pdev = &pdevs[top[i]]; pdev->y = -1; pdev->x = -1; pdev->switch = 0; }

Craig Estey 25.10.2018 04:42

@paddy отредактировал и добавил все, кроме повтора для петель, для которых я ищу направление. Буду иметь это в виду, продвигаясь вперед. Благодарность

Ali Z 25.10.2018 04:43

кроме цикла for я нигде не вижу закрывающих скобок }

Potato 25.10.2018 04:44

Что ж, вы снова пропустили код, поэтому мы не можем определить намерение вашей программы. Это выглядит, как будто вы пытаетесь настроить массив соседей статического размера и их смещение X / Y, например вверху-слева == (-1, -1), вправо == (1,0) и т. д. Зачем для этого нужны циклы или динамическое распределение, вызывает недоумение.

paddy 25.10.2018 04:45

@u__ Он находится в той же строке, что и задание - просто плохое форматирование.

Barmar 25.10.2018 04:46

не удержался - пошел дальше и немного отформатировал code

Potato 25.10.2018 04:50

@paddy включает больше контекста. не уверен, достаточно ли этого того, что вы ищете.

Ali Z 25.10.2018 04:57

спасибо @u__ до сих пор к этому привыкаешь!

Ali Z 25.10.2018 05:14

Обратите внимание, что struct deviations *pdevs = malloc(24 * sizeof(int)); - неправильный способ выделить массив из 8 структур. Вам нужен struct deviations *pdevs = malloc(8 * sizeof(struct deviations));, т.е. размер структуры НЕ всегда в 3 раза больше размера int. Иногда используется заполнение.

Rishikesh Raje 25.10.2018 06:03
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
14
75
2

Ответы 2

Итак, вам нужна универсальная функция, которая может принимать массив из 3 индексов, член структуры для заполнения и значение.

Массив и значение просты. Для общей обработки члена структуры можно использовать макрос offsetof().

void fill_structs(struct deviations *pdevs, size_t offset, int indexes[3], int value) {
    for (int i = 0; i < 3; i++) {
        *((int *)((char *)&pdevs[indexes[i]] + offset)) = value;
    }
}

Тогда вы называете это так:

fill_structs(pdevs, offsetof(struct deviations, y), top, -1);

offsetof() возвращает смещение в байтах элемента структуры от основания структуры. Итак, в функции вы должны преобразовать адрес элемента массива в char *, чтобы вы могли добавить к нему смещение, а затем преобразовать его в int *, чтобы вы могли разыменовать его и назначить там члену int.

Кстати, вы должны отказаться от привычки использовать такие вещи, как

(pdevs + i) -> x

Если вы используете указатель в качестве основы массива, используйте синтаксис массива:

pdevs[i].x

Таким образом, намного проще определить, что i является индексом массива.

согласен, pdevs [i] - это то, как я должен был его использовать, не знаю, что заставило меня пойти другим путем. Я не знаком с макросами, проведу небольшое исследование и посмотрю, смогу ли я обдумать это, а также это: * ((int *) ((char *) & pdevs [indexes [i]] + offset)) = value; Новичок в C, поэтому пытаюсь разобраться в декларациях this.

Ali Z 25.10.2018 05:00

Всегда рекомендуется использовать typedefs при работе с structs, например. typedef struct _deviations deviations. Затем вы можете использовать его, как и любые другие типы, например. int, char. size_t, etc без необходимости каждый раз упоминать struct

Sisir 25.10.2018 05:24

@Sisir LOL, ранее сегодня я отвечал на вопрос, который использовал typedef, и кто-то еще сказал, что это НЕ хорошая идея, и направил меня к руководству по стилю ядра Linux.

Barmar 25.10.2018 05:26

Объявлять typedef struct _deviations* deviations нехорошо, но объявлять typedef struct _deviations deviations абсолютно нормально. Фактически, если вы не будете делать это каждый раз, когда захотите использовать тип, вам придется написать очевидное ключевое слово struct. Однако я согласен с тем, что эта концепция зависит от индивидуального восприятия и ваших текущих руководящих принципов проекта.

Sisir 25.10.2018 05:38

Некоторые интересные обсуждения по этой конкретной теме можно найти по ссылкам ниже softwareengineering.stackexchange.com/questions/147545/…stackoverflow.com/questions/516237/…

Sisir 25.10.2018 05:39

@Sisir Я знаю о совете "не вводите указатели" и согласен. Это был первый раз, когда мне сказали «вообще не печатать», и я согласен с вами. Но я не собираюсь давать советы тем или иным способом в своих ответах, я просто придерживаюсь того, что сделал OP.

Barmar 25.10.2018 05:42

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

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

const struct deviations devs[8] = {
    { 1, -1, -1 },  // top-left
    { 1,  0, -1 },  // top
    { 1,  1, -1 },  // top-right
    { 1, -1,  0 },  // left
    { 1,  1,  0 },  // right
    { 1, -1,  1 },  // bottom-left
    { 1,  0,  1 },  // bottom
    { 1,  1,  1 }   // bottom-right
};

Если вы затем решите, что вам действительно нужно выделять это динамически, вы можете просто скопировать его:

struct deviations *pdevs = malloc(sizeof(devs));
if (pdevs) memcpy(pdevs, devs, sizeof(devs));

Но если вы действительно хотели сгенерировать этот материал в цикле, почему бы не сделать что-то подобное?

int ii = 0;
for(int y = -1; y <= 1; ++y) {
    for(int x = -1; x <= 1; ++x) {
        if (x == 0 && y == 0) continue;
        pdevs[ii].switch = 1;
        pdevs[ii].x = x;
        pdevs[ii].y = y;
        ++ii;
    }
}

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

Ali Z 25.10.2018 05:10

Не стоит беспокоиться. Кстати, я подталкивал вас добавить дополнительные детали к вашему вопросу, потому что подозревал, что он пострадал от XY проблема.

paddy 25.10.2018 05:16

Вы были правы, это точно ... ой.

Ali Z 25.10.2018 05:20

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