реклама на сайте
подробности

 
 
> Работа со struct
Jenya7
сообщение Jul 14 2014, 10:13
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Есть struct:
Код
typedef struct command
{
    char *name;  //command name
    char mode;   //0-read, 1- read/write
    int minval;  
    int maxval;  
    void (*fp) (int com_num);  //pointer to function
    void *vp;   //pointer to variable
}command;

command commands[] = {
    {"imax1", 1, 0, 10000, GetSetImax, &max_current1},
    {"imax2", 1, 0, 10000, GetSetImax, &max_current2},
};

Я могу считать переменную
Код
UsartSendInt( (int)commands[com_num].vp );

Но записать не получается
Код
(int *)(commands[com_num].vp) = mux_cur;

Что я делаю не так?
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 14)
andrewlekar
сообщение Jul 14 2014, 10:29
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Как вам такой вариант:
Код
commands[com_num].vp = (void *)&mux_cur;
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 14 2014, 10:39
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(andrewlekar @ Jul 14 2014, 16:29) *
Как вам такой вариант:
Код
commands[com_num].vp = (void *)&mux_cur;

компайлер не ругается но я что то не понимаю - мы приводим к войд?
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 14 2014, 10:43
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



попробуйте *(int *)... = val
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Jul 14 2014, 10:48
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Цитата
но я что то не понимаю - мы приводим к войд?

Да, раз у вас в структуре хранится void *, то и приводите к void *. Потом обратно можно получить указатель на что угодно.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 14 2014, 10:57
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(adnega @ Jul 14 2014, 16:43) *
попробуйте *(int *)... = val

вроде работет. спасибо.

Цитата(andrewlekar @ Jul 14 2014, 16:48) *
Да, раз у вас в структуре хранится void *, то и приводите к void *. Потом обратно можно получить указатель на что угодно.

все рвно не понимаю - как он запишет инеджер в войд?
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Jul 14 2014, 11:11
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Цитата
все рвно не понимаю - как он запишет инеджер в войд?

Во-первых, он запишет указатель на интеджер в указатель на войд. Так делают, чтобы использовать одну структуру для разных данных (полиморфизм).
Во-вторых, это вам надо выяснить, зачем вы в своей же структуре храните переменную как указатель на войд. Храните саму переменную как инт и всё будет проще.
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Jul 14 2014, 11:13
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(Jenya7 @ Jul 14 2014, 13:57) *
все рвно не понимаю - как он запишет инеджер в войд?


int*, char*, short*, void* и вообще любой указатель - это просто число. Адрес переменной. int или char определяют сколько байт нужно считать при обращении к переменной. А void* получается пустой указатель. т.е. указатель на переменную без привязки к её типу (разрядности). Чтоб корректно считать данные при чтении вы должны привести его к одному из существующих типов - int*, char* и т.д.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 14 2014, 11:19
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(andrewlekar @ Jul 14 2014, 17:11) *
Во-первых, он запишет указатель на интеджер в указатель на войд. Так делают, чтобы использовать одну структуру для разных данных (полиморфизм).
Во-вторых, это вам надо выяснить, зачем вы в своей же структуре храните переменную как указатель на войд. Храните саму переменную как инт и всё будет проще.

у меня переменная может быть разной размерности - поэтому указатель на войд, чтоб потом привести к нужному типу.
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Jul 14 2014, 11:21
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Цитата
у меня переменная может быть разной размерности

В таком случае, если будете писать
Код
*(int *)... = val

рискуете получить падающую программу.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 14 2014, 11:31
Сообщение #11


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(andrewlekar @ Jul 14 2014, 17:21) *
В таком случае, если будете писать
Код
*(int *)... = val

рискуете получить падающую программу.

ну если переменная скажем чар то я привожу к *(char *). по моему вполне безопасно.

Сообщение отредактировал Jenya7 - Jul 14 2014, 11:32
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 14 2014, 11:40
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(andrewlekar @ Jul 14 2014, 15:21) *
В таком случае, если будете писать
Код
*(int *)... = val

рискуете получить падающую программу.

Поэтому нужно писать *(мой_сегодняшний_тип *)... = val
А выше #typedef мой_сегодняшний_тип int.
Компилятору не дается шанса найти ошибку и предупредить.
Упасть может и в случае, если хранить указатель на int, но забыть его проинициализировать.
И если ТС не подтянет знания по указателям, то и в многих других местах (заканчивая изощренными, типа, невыровненные данные).

С другой стороны, указатель как правило 32-битный.
Храните int и забудте о char, short.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 14 2014, 11:44
Сообщение #13


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(adnega @ Jul 14 2014, 17:40) *
Поэтому нужно писать *(мой_сегодняшний_тип *)... = val
А выше #typedef мой_сегодняшний_тип int.
Компилятору не дается шанса найти ошибку и предупредить.
Упасть может и в случае, если хранить указатель на int, но забыть его проинициализировать.
И если ТС не подтянет знания по указателям, то и в многих других местах (заканчивая изощренными, типа, невыровненные данные).

С другой стороны, указатель как правило 32-битный.
Храните int и забудте о char, short.


то есть лучше писать * (uint32_t *) ?
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Jul 14 2014, 11:45
Сообщение #14


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



uint32_t vp;
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 14 2014, 11:45
Сообщение #15


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(adnega @ Jul 14 2014, 17:40) *
С другой стороны, указатель как правило 32-битный.
Храните int и забудте о char, short.

по моему это лучший способ избежать головной боли. sm.gif
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th July 2025 - 05:58
Рейтинг@Mail.ru


Страница сгенерированна за 0.01482 секунд с 7
ELECTRONIX ©2004-2016