Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: помогите с контрукциями С
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Dubov
Волей судьбы пришлось разбираться с чужим кодом.
Никак не пойму что означает такая конструкция:
CODE
typedef void ( * DSP_Proc ) ( win_inst * win, mod_msg * pMsg );


а потом вижу такое
CODE
DSP_Proc Сom_fProc[CMD_NUMBER];

где элементы массива - имена, ранее объявленых функций.

Зачем так сильно всё усложнать? где такие выкрутасы оправданы и полезны?
_Артём_
Цитата(Dubov @ Jul 11 2012, 18:26) *
Никак не пойму что означает такая конструкция:
Код
typedef void ( * DSP_Proc ) ( win_inst * win, mod_msg * pMsg );

Есть такая штука - указатель на функцию. DSP_Proc - имя типа указателя на фунцкию принимающую два параметра (win_inst * и mod_msg *) и не возвращающая ничего(void).


Цитата(Dubov @ Jul 11 2012, 18:26) *
Код
DSP_Proc Сom_fProc[CMD_NUMBER];

где элементы массива - имена, ранее объявленых функций.

Сom_fProc - массив указателей на функцию.


Цитата(Dubov @ Jul 11 2012, 18:26) *
Зачем так сильно всё усложнать? где такие выкрутасы оправданы и полезны?

Иногда такое нужно и удобно - во многих языках такое есть. Почитайте у того же K&R или ещё где.
ViKo
Цитата(Dubov @ Jul 11 2012, 18:26) *
где такие выкрутасы оправданы и полезны?

Вы хотите выполнить команду из некого набора. Каждая команда соответствует индексу (номеру) в массиве указателей на функцию. Указатели на функцию собраны в один массив. Команде 0 соответствует указатель 0-й, 1 - 1-й, и т.д. И вы просто вызываете нужную функцию DSP_Proc Сom_fProc[CMD_NUMBER] по указателю.
Dubov
Не хочу засорять форум однотипными вопросами. Но очень нужна помощь в понимании некоторых конструкции, а посему опять вопрос)
Вижу контсрукцию:
CODE
typedef struct tagX {

int16 * p; //!< pointer to samples buffer

} X;
X x1;


а затем вижу такое

CODE
memcpy( &RawVal[0],
&x1.p[0],
NUMB*sizeof(int16) );
memcpy( &RawVal[NUMB],
&ad7324.pSamp[NUMB*FRAME_SZ],
NUMB*sizeof(int16) );


Получается сначала объявили структуру, где поле является указателем, а потом копируется по адресу указателя целый массив. Это нормально?
Tiro
Цитата(Dubov @ Jul 12 2012, 23:48) *
Не хочу засорять форум однотипными вопросами. Но очень нужна помощь в понимании некоторых конструкции, а посему опять вопрос)

Керниган Ритчи Язык С второе издание
_Артём_
Цитата(Dubov @ Jul 12 2012, 23:48) *
Получается сначала объявили структуру, где поле является указателем, а потом копируется по адресу указателя целый массив. Это нормально?

Конечно нормально - указатели для того и придумали, чтобы читать-писать по адресу.
Сергей Борщ
QUOTE (Dubov @ Jul 12 2012, 23:48) *
а потом копируется по адресу указателя целый массив.
по адресу, на который указывает этот указатель.
p - адрес, на который указывает указатель. p[0] - значение, на которое указывает указатель. &p[0] - адрес значнения, на которое указывает указатель, т.е. то же самое, что и p. Эту конструкцию можно записать гораздо проще и понятнее:
CODE
memcpy( RawVal, x1.p, NUMB * sizeof(int16));
Почему автор выбрал такую запутанную форму выражения своей мысли - загадка. Возможно он считал, что именно так будет понятнее.
mdmitry
Цитата(Сергей Борщ @ Jul 13 2012, 01:32) *
Почему автор выбрал такую запутанную форму выражения своей мысли - загадка. Возможно он считал, что именно так будет понятнее.

Однажды нарвался с IAR под ARM.
Не компилировалось именно это
Код
memcpy( RawVal, x1.p, NUMB * sizeof(int16));

А это проходило:
Код
memcpy( &RawVal[0], &x1.p[0], NUMB*sizeof(int16) );

Была выборочно включена MISRA, которая на вид написания кода накладывает заметные ограничения. Возможно у автора кода такая же ситуация.

С включенной MISRA
Код
switch(a)
{
case 1:
case 2:
break;
case 3:
break;
default:
break;
}

не соберётся. Будет ругаться на отсутствие
Код
break
в
Код
case 1:
.
Сергей Борщ
QUOTE (mdmitry @ Jul 13 2012, 00:48) *
Не компилировалось именно это
CODE
memcpy( RawVal, x1.p, NUMB * sizeof(int16));
Странно это. Второй параметр memcpy - void const *. Так зачем разыменовывать уже готовый указатель, чтобы взятием адреса вернуться к нему же? Могу допустить, что MISRA не резрешает использовать имя массива как указатель на его начало, но такое черз одно место использование указателя во втором параметре - нет уж, нафиг такую миСРУ. Она была задумана для уменьшения ошибок/описок, но в этом случае она их явно провоцирует.
mdmitry
Цитата(Сергей Борщ @ Jul 13 2012, 02:18) *
Странно это. Второй параметр memcpy - void const *. Так зачем разыменовывать уже готовый указатель, чтобы взятием адреса вернуться к нему же? Могу допустить, что MISRA не резрешает использовать имя массива как указатель на его начало, но такое черз одно место использование указателя во втором параметре - нет уж, нафиг такую миСРУ. Она была задумана для уменьшения ошибок/описок, но в этом случае она их явно провоцирует.

У меня своя функция принимала указатель на массив и работало только с указанной выше конструкцией.

Код
static unsigned char SendCommand(... ,    unsigned char *pcmd,  unsigned char cmdSize, unsigned char *pData,     unsigned int dataSize );

error = SendCommand(..., myBuffer, mysize, &myrxbuf[0], 0);

Буфер myrxbuf был глобальный для единицы трансляции.
Там и с const какие-то сложности были, сейчас уже не помню.
ReAl
Ну это странно, так как по стандарту языка С RawVal везде, кроме sizeof(RawVal) и &RawVal автоматически приводится к &RawVal[0].

Т.е. требование мисры писать только &RawVal[0] сродни требованию писать
Код
    unsigned char foo;

    foo = (unsigned char)0;
так как 0 таки ж имеет тип int и к unsigned char он в этом выражении приводится автоматически.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.