Arhn - архитектура программирования

изменить значение структуры с помощью указателя void

Я упростил свою проблему до этого:

Допустим, у меня есть структура (t_struct1), и если я передам эту структуру в функцию (do_something_with_struct(...)) значения другой структуры (t_struct2) будут скопированы в первую структуру (t_struct1). Так что в основном...

void do_something_with_struct(struct){
        struct = struct2;
}
do_something_with_struct(struct1);

... должно произойти.

Несколько вещей, которые не разрешены в моей программе: 1. функция ничего не знает о структуре, поэтому я в основном не могу привести указатель void к структуре внутри функции и 2. параметр функции должен быть пустой указатель.

Это «настоящая» программа, которую я использую, но она почему-то не работает.

struct test_struct {
        int test_int;
        char test_char;
};
struct test_struct t_struct1;
struct test_struct t_struct2;

void do_something_with_struct(void *p){
        void* temp = (void*)&t_struct2;
        p = temp; 
}

int main(void) {
        t_struct2.test_char = 'b';
        t_struct2.test_int  = 2;

        do_something_with_struct((void*)&t_struct1);

        // I want the values of t_struc1 to be the same as t_struct2 (so 2 and 'b'),
        // but they aren't. Instead t_struct1 is is filled with random/default values.

        while (1);
}

Как я уже говорил выше, программа не работает. У кого-нибудь есть решение/мысль, которая заставит мою программу работать.

Заранее спасибо,

Арджон

26.05.2020

  • Вы можете использовать memcpy, если знаете sizeof(struct test_struct). 26.05.2020
  • Кстати, на самом деле вы никогда не пишете t_struct1. Вы просто меняете местами адреса в p и temp. 26.05.2020
  • @FiddlingBits В этом проблема, я не знаю, что это за структура, поэтому я не могу узнать ее размер. 26.05.2020
  • Можете ли вы передать количество байтов в качестве переменной? 26.05.2020
  • Как вы думаете, что делает оператор while (1); в нижней части main()? 26.05.2020
  • @FiddlingBits Использование memcpy работает для меня, как вы и сказали, мне нужно где-то создать дополнительную переменную, которая хранит количество байтов. Так что спасибо за вашу помощь! 26.05.2020
  • @ryyker Я всегда так делаю, меня так учили. Так что да, без конкретной причины 26.05.2020
  • @ArjonArts - если его цель - просто отложить выполнение до выхода, вы также можете просто использовать getchar() с сообщением пользователю для <hit any key to exit> 26.05.2020
  • Вы также можете сделать это последовательно, просто создав экземпляр объекта внутри функции и присвоив значения из аргумента. Но тогда вы, вероятно, захотите также вернуть обновленную структуру. 26.05.2020

Ответы:


1

Я хочу, чтобы значения t_struc1 были такими же, как t_struct2 ...

void * обычно используется в качестве аргумента функции, когда эта функция должна обрабатывать несколько типов ввода. И, как правило, поскольку функции важно знать тип данных, также должен быть аргумент, сообщающий функции, как преобразовать void * данные. В этом случае мы знаем, что такое тип приема, поэтому преобразование будет эквивалентно:

struct test_struct *new = (struct test_struct *)p;  

Как показано ниже:

Простите мои typedefs (предпочтение удобочитаемости), но ниже показано, как вы можете назначать значения из одной структуры в другую:

typedef struct test_struct {
        int test_int;
        char test_char;
}TEST;
TEST t_struct1;
TEST t_struct2;

void do_something_with_struct(void *p){

    TEST *new = (TEST *)(p);    //create a temporary pointer and with a cast
                                //assign it to point to the argument `p`
    new->test_char = t_struct2.test_char;//make assignments of values
    new->test_int =  t_struct2.test_int;
    p = new; //update p
}

int main(void) {
    t_struct2.test_char = 'b';
    t_struct2.test_int  = 2;

    do_something_with_struct((void*)&t_struct1);
    t_struct1;//because of global scope, changes made in function 
              //are visible here. (t_struct1 == t_struct2)
    printf("t_struct2.test_char: %c\nt_struct2.test_int: %d\n" \
        "t_struct1.test_char: %c\nt_struct1.test_int: %d\n" \
        "(Hit any key to exit.)", \
        t_struct2.test_char,t_struct2.test_int,  \        
        t_struct1.test_char,t_struct1.test_int);

    return 0;
}
26.05.2020
Новые материалы

Коллекции публикаций по глубокому обучению
Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

Представляем: Pepita
Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

Советы по коду Laravel #2
1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

3 способа решить квадратное уравнение (3-й мой любимый) -
1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

Создание VR-миров с A-Frame
Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

Демистификация рекурсии
КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..