Гость
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Работа с void указателями в С / 21 сообщений из 21, страница 1 из 1
12.05.2019, 12:32
    #39812190
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
Есть структура

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
typedef struct 
{  
    void *l_var;      
    void *r_var;    
}EXPR;

EXPR expr;



Инициализирую
Код: sql
1.
2.
expr.l_var = &motor_rt_params[0].position;
expr.r_var = &motor_rt_params[1].position;



Но теперь если я хочу выполнить операцию
Код: plaintext
1.
result = *(expr.l_var) – *( expr.r_var);



я получаю исключение
Error[Pe041]: expression must have arithmetic or pointer type

Нужно явно привести к типу
Код: plaintext
1.
result = *((int32_t *) expr.l_var) - *((int32_t *)expr.r_var);



Но не все переменные 32 бита, есть 16, 8.
Как мне универсально преобразовать к нужному типу?
...
Рейтинг: 0 / 0
12.05.2019, 12:55
    #39812198
alex55555
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
jenya7Но теперь если я хочу выполнить операцию
Код: plaintext
1.
result = *(expr.l_var) – *( expr.r_var);



я получаю исключение
Error[Pe041]: expression must have arithmetic or pointer type
Напиши подробно, зачем ты использовал каждый знак в данной операции.
...
Рейтинг: 0 / 0
12.05.2019, 12:58
    #39812199
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
jenya7,

union с разными типами заюзать не судьба или не нравится?

(круглый)
...
Рейтинг: 0 / 0
12.05.2019, 13:06
    #39812200
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
alex55555jenya7Но теперь если я хочу выполнить операцию
Код: plaintext
1.
result = *(expr.l_var) – *( expr.r_var);



я получаю исключение
Error[Pe041]: expression must have arithmetic or pointer type
Напиши подробно, зачем ты использовал каждый знак в данной операции.
Допустим есть генерик
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
void SCRIPT_Process(void *l_var, void *r_var, uint32_t oper)
{
    int32_t res;
     
    switch (oper)
    {
        case OP_PLUS: 
            res = *((int32_t *) l_var) + *((int32_t *)r_var);
        break;
        case OP_MINUS: 
            res = *((int32_t *) l_var) - *((int32_t *)r_var);
        break; 
    }
}


Как мне заране знать в какой тип преобразовать?
...
Рейтинг: 0 / 0
12.05.2019, 13:09
    #39812201
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
kolobok0jenya7,

union с разными типами заюзать не судьба или не нравится?

(круглый)
юнион не будет работать.
...
Рейтинг: 0 / 0
12.05.2019, 13:11
    #39812202
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
jenya7kolobok0jenya7,

union с разными типами заюзать не судьба или не нравится?

(круглый)
юнион не будет работать.
опять таки - где я решаю в какого типа сохранить указатель?
...
Рейтинг: 0 / 0
12.05.2019, 13:54
    #39812214
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
jenya7Как мне заране знать в какой тип преобразовать?
Никак, обломись.
...
Рейтинг: 0 / 0
12.05.2019, 14:00
    #39812216
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
Только в С++ можно такое сделать.


Либо шаблонами, либо пользовательскими операторами.
...
Рейтинг: 0 / 0
12.05.2019, 19:09
    #39812275
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
jenya7Как мне заране знать в какой тип преобразовать?
Никак. Указатель это просто адрес в памяти, а тип указателя - как трактовать память по этому адресу (сколько байт и т.д.)
Т.е. из void * никак не восстановить исходный тип. Убирай void * или добавляй данные об исходном типе.
...
Рейтинг: 0 / 0
12.05.2019, 22:10
    #39812298
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
jenya7...юнион не будет работать.

т.е. приводить указатель к нужному типу через юнион - не получиться? кхм...
ну что я могу сказать - это из разряда = а мужики и не знали...



удачи вам, она вам потребуется
(круглый)
...
Рейтинг: 0 / 0
13.05.2019, 09:04
    #39812340
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
Dima Tjenya7Как мне заране знать в какой тип преобразовать?
Никак. Указатель это просто адрес в памяти, а тип указателя - как трактовать память по этому адресу (сколько байт и т.д.)
Т.е. из void * никак не восстановить исходный тип. Убирай void * или добавляй данные об исходном типе.
тогда такой вопрос
Код: c#
1.
2.
int a, b, c;
c = a + b;


это компилируется в машинный код. как конвейер формирующий команду знает с каким типом оперировать? есть отдельная команда сложения для каждого типа?
...
Рейтинг: 0 / 0
13.05.2019, 09:12
    #39812346
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
jenya7есть отдельная команда сложения для каждого типа?
Есть. Во время компиляции выбирается соответствующая команда.
...
Рейтинг: 0 / 0
14.05.2019, 12:52
    #39812949
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
Есть структура

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
typedef struct 
{  
    void *l_var;      
    void *r_var;    
}EXPR;

EXPR expr;



Инициализирую
Код: sql
1.
2.
expr.l_var = &motor_rt_params[0].position;
expr.r_var = &motor_rt_params[1].position;



Но теперь если я хочу выполнить операцию
Код: plaintext
1.
result = *(expr.l_var) – *( expr.r_var);



я получаю исключение
Error[Pe041]: expression must have arithmetic or pointer type

Это не исключение. Это ошибка компиляции.

Нужно явно привести к типу
Код: plaintext
1.
result = *((int32_t *) expr.l_var) - *((int32_t *)expr.r_var);



Нужно.


Но не все переменные 32 бита, есть 16, 8.
Как мне универсально преобразовать к нужному типу?

Хранить десигнатор хранимого типа, делать по нему switch/if и делать в каждой ветке нужное приведение типа.

Ещё совет -- сначала учить язык программирования, потом пытаться на нём что-то писать.
...
Рейтинг: 0 / 0
14.05.2019, 12:52
    #39812952
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
kolobok0jenya7,

union с разными типами заюзать не судьба или не нравится?

(круглый)

С union проблема будет такая же.
...
Рейтинг: 0 / 0
14.05.2019, 12:55
    #39812953
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
jenya7Dima Tпропущено...

Никак. Указатель это просто адрес в памяти, а тип указателя - как трактовать память по этому адресу (сколько байт и т.д.)
Т.е. из void * никак не восстановить исходный тип. Убирай void * или добавляй данные об исходном типе.
тогда такой вопрос
Код: c#
1.
2.
int a, b, c;
c = a + b;


это компилируется в машинный код. как конвейер формирующий команду знает с каким типом оперировать? есть отдельная команда сложения для каждого типа?


Да, есть.

Конвеер не знает, и не должен. Компилятор знает типы переменных, обрабатывает их, и должным образом генерирует машинный код, где для реализации операций над разными типами используются соответствующие операции и типу операндов машинные комманды.
...
Рейтинг: 0 / 0
14.05.2019, 13:08
    #39812966
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
MasterZiv...С union проблема будет такая же.

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

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

это собственно очевидные вещи.


(круглый)
...
Рейтинг: 0 / 0
14.05.2019, 20:32
    #39813209
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
kolobok0MasterZiv...С union проблема будет такая же.

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



Так десигнатор всё равно надо делать, и ветвление по него.
...
Рейтинг: 0 / 0
14.05.2019, 23:12
    #39813260
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
А чего эта тема переехала в "программирование" ???

Я может ВБА учил всю жизь, мне ваши укаказатели не в дугу!
...
Рейтинг: 0 / 0
15.05.2019, 10:40
    #39813400
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
MasterZiv...Так десигнатор всё равно надо делать, и ветвление по него.

и хде тут десигнатор+ветвление?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
typedef union _uPoint
{
	void* vv;
	uint32_t* u32v;
	uint16_t* u16v;
	uint8_t* u8v;
} uPoint;
//
typedef struct 
{
	uPoint l;
	uPoint r;
} EXPR;

void subbFoo(uPoint lv, uPoint rv, uint32_t& rData)
{
	rData = *lv.u32v - *rv.u32v;
}

void subbFoo(uPoint lv, uPoint rv, uint16_t& rData)
{
	rData = *lv.u16v - *rv.u16v;
}

void subbFoo(uPoint lv, uPoint rv, uint8_t& rData)
{
	rData = *lv.u8v - *rv.u8v;
}



юзанье типо

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
	expr.l.vv = &motor_rt_params[0].position;
	expr.r.vv = &motor_rt_params[1].position;

	uint32_t u32Data = 0;
	uint16_t u16Data = 0;
	uint8_t u8Data = 0;

	subbFoo(expr.l, expr.r, u32Data);
	subbFoo(expr.l, expr.r, u16Data);
	subbFoo(expr.l, expr.r, u8Data);



ик?
...
Рейтинг: 0 / 0
15.05.2019, 12:39
    #39813476
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
kolobok0MasterZiv...Так десигнатор всё равно надо делать, и ветвление по него.

юзанье типо

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
	expr.l.vv = &motor_rt_params[0].position;
	expr.r.vv = &motor_rt_params[1].position;

	uint32_t u32Data = 0;
	uint16_t u16Data = 0;
	uint8_t u8Data = 0;

	subbFoo(expr.l, expr.r, u32Data);
	subbFoo(expr.l, expr.r, u16Data);
	subbFoo(expr.l, expr.r, u8Data);



ик?
во первых третий аргумент rData где то надо хранить. во вторых - *lv.u32v - *rv.u16v; не судьба? значит rData нужно хранить для lv и rv.
а если выражение усложниться var1-var2 > var3 - rData нужно хранить и для var3. отжирается куча места.
...
Рейтинг: 0 / 0
15.05.2019, 15:05
    #39813606
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с void указателями в С
jenya7...во первых третий аргумент rData где то надо хранить. во вторых ...

третий аргумент надо хранить там, где Вы и храните Ваш result

Код: sql
1.
result = *(expr.l_var) – *( expr.r_var);




во вторых....дальше полёт мысли я простите потерял....

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

удачи вам, она вам потребуется
(круглый)
...
Рейтинг: 0 / 0
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Работа с void указателями в С / 21 сообщений из 21, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]