|
указатель на тип void, попытки создать общую функцию |
|
|
|
Jan 3 2006, 13:06
|
Местный
  
Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064

|
Всех с наступившим!!! Решил написать функцию вывода строки в массив да так чтобы можно было эту строку брать как из SRAM так и из FLASH а поскольку указатели на FLASH и SRAM это разные вещи, то и типы указателей должны быть разные. решил сделать тип void чтобы тип можно было задать при вызове функции с приведением типа. вот код функции Код void LCDString(unsigned char StrNum, unsigned char StrPos, void *pStr) { unsigned char i, c; i = StrPos; c = *((char*)pStr++); while ((i < SYM_STR-2) && (c != 0x00)) { LCDStr[StrNum][i] = c; c = *((char*)pStr++); i++; } } прблема в том что компилятор не может сделать ++ для указателя типа void. если создать отдельную переменную типа char *pS; то все нормально. т.о. вопрос ? как сделать ++ указателю типа void без отдельной переменной, если возможно. И еще вопрос. Если нужен передавать параметр типа bool то можно как-то использовать #if #endif т.е. напрмер Код strcpy(char *pStr, bool S_F) { #if S_F // если передан указатель на FLASH flashcpy() #else Sramcpy() #endif } или может так : Код strcpy(char *pStr) { #ifdef S_F flashcpy() #else Sramcpy() #endif } а вызов функции делать так
#define S_F strcpy(*pStr) #undef S_F Есть еще вариант передавать два указателя, для Flash и SRAM и ненужный передавать 0 Или может еще каким образом поступают при такой задаче, просьба поделиться опытом ...
|
|
|
|
|
 |
Ответов
|
Jan 3 2006, 14:26
|
Местный
  
Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064

|
Цитата(IgorKossak @ Jan 3 2006, 18:15)  Всё, что Вы хотите легко реализуется перегружаемыми функциями в С++, а ещё элегантнее - шаблонной функцией. Давно так делаю и очень доволен. А если делать на С, то надо дополнительно передавать идентификатор типа и внутри универсальной функции делать приведение. Тогда и операция ++ будет работать. Попробовал sprintf() но сгенеренный код получился в 2 раза больше по времени выполнения. это если я Вас правильно понял всмысле перегружаемых. а что такое шаблонная функция ? В С я новичок, поэтому может какие термины еще не знаю  а разве Код (char*)pStr++; Это не приведение типа ? вот на такой вариант компилятор говорит: Error[Pe852]: expression must be a pointer to a complete object type как правильно написать чтобы ++ работал?
|
|
|
|
|
Jan 3 2006, 15:38
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(&-rey @ Jan 3 2006, 21:26)  ...а поскольку указатели на FLASH и SRAM это разные вещи, то и типы указателей должны быть разные Вы сами отвечаете на свой вопрос. В Си вы не сможете объеденить два разных указателя под одним пустым типом VOID. Компилятор просто не знает, как формировать инкремент для данного типа. Указатель на SRAM изменяется линейно, указатель на FLASH имеет немного отличный механизм инкремента. Во-первых это указатель содержит адрес не байта, как в SRAM мо, а слова, где младший бит адреса указывает на тип байта в слове (старший или младший). В Си++ все это можно организовать, но все равно код раздуется до размеров двух процедур с разными типами данных. Так что не убивайте время попусту преобразуйте VOID к переменной конкретного типа и все будет в порядке. Не бойтесь большого количества переменных в теле функции, шелуху компилятор сам откинет. вот франмент варианта кода переделанной функции Код void LCDString(unsigned char StrNum, unsigned char StrPos, char *pSramStr, char __flash *pFlashStr) { if(pSramStr) { ... приводим указатель в теле к char*...}
if(pFlashStr){приводим указатель в теле к char __flash*...}
.......... }
--------------------
|
|
|
|
|
Jan 3 2006, 15:50
|
Местный
  
Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064

|
Цитата(prottoss @ Jan 3 2006, 19:38)  В Си++ все это можно организовать, но все равно код раздуется до размеров двух процедур с разными типами данных.
Так что не убивайте время попусту преобразуйте VOID к переменной конкретного типа и все будет в порядке. Не бойтесь большого количества переменных в теле функции, шелуху компилятор сам откинет. ну в данном конкретном случае думаю код не очень увеличиться я думал это как раз через #if сделать, т.е. передаем указатель и смысл этого указателя S_F типа SRAM или FLASH. Цитата вот франмент варианта кода переделанной функции Идея о двух указателях была рассмотрена, и наверное я на ней остановлюсь  . но для полного понимания проблемы в будущем все таки почему Код (char*)pStr++; дает ошибку при компиляции ???
|
|
|
|
|
Jan 3 2006, 18:04
|
Профессионал
    
Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528

|
Цитата(&-rey @ Jan 3 2006, 21:50)  но для полного понимания проблемы в будущем все таки почему Код (char*)pStr++; дает ошибку при компиляции ??? Выражение var++ эквивалентно var = var+1, НО: Тут есть один тонкий момент - выражения в левой и правой части оператора присваивания вычисляются по-разному. В "С" они называются lvalue и rvalue. В правой части вычисляется значение выражения (rvalue), при этом если в выражении есть имена переменных, т.е. символические имена для некоторых ячеек памяти, то используются значения этих переменных, числа, хранящиеся в соответствующих ячейках памяти. При вычислении выражения в левой части (lvalue) на самом деле вычисляется адрес ячейки памяти куда следует поместить результат вычисления выражения в правой части. Так вот (char*)pStr не может быть lvalue - нет такой ячейки памяти где бы оно хранилось. Ситуация в точности такая-же как и для выражения (2*2)++; P.S. Ну вот, пока объяснял, сам понял :-))
--------------------
Russia est omnis divisa in partes octo.
|
|
|
|
Сообщений в этой теме
&-rey указатель на тип void Jan 3 2006, 13:06    prottoss [quote name='&-rey' date='Jan 3 20... Jan 3 2006, 16:17   defunct Цитата(prottoss @ Jan 3 2006, 17:38) Вы с... Jan 7 2006, 13:30    prottoss Цитата(defunct @ Jan 7 2006, 20:30) Цитат... Jan 7 2006, 21:17     defunct Цитата(prottoss @ Jan 7 2006, 23:17) Цита... Jan 9 2006, 15:36      prottoss Цитата(defunct @ Jan 9 2006, 22:36) ... Jan 9 2006, 19:29       defunct Цитата(prottoss @ Jan 9 2006, 21:29) а Вы... Jan 9 2006, 20:01  IgorKossak Цитата(&-rey @ Jan 3 2006, 16:26... Jan 4 2006, 07:36   &-rey Цитата(IgorKossak @ Jan 4 2006, 11:36) На... Jan 4 2006, 07:51    IgorKossak Цитата(&-rey @ Jan 4 2006, 09:51... Jan 4 2006, 08:28     &-rey Цитата(IgorKossak @ Jan 4 2006, 12:28) ??... Jan 4 2006, 09:36      &-rey ЦитатаВ принципе это можно проверить. так и сделаю... Jan 5 2006, 07:38       Old1 To &-rey.
Я тут для себя тоже провел кое-каки... Jan 7 2006, 20:51 _artem_ sdelay tak :
c = *(((char*)pStr)++);
po moem... Jan 3 2006, 15:58 &-rey Цитата(_artem_ @ Jan 3 2006, 19:58) sdela... Jan 3 2006, 16:09 SSerge Цитата(&-rey @ Jan 3 2006, 19:06... Jan 3 2006, 16:12 &-rey Цитата(SSerge @ Jan 3 2006, 20:12) А комп... Jan 3 2006, 16:27  SSerge Цитата(&-rey @ Jan 3 2006, 22:27... Jan 3 2006, 17:08   &-rey Цитата(SSerge @ Jan 3 2006, 21:08) Код c... Jan 4 2006, 07:38 _artem_ OK, v principe kompayler prav )), on ne mozet preo... Jan 3 2006, 16:27 ObitJr Я думаю неправильно говорить компилятор незнает ил... Jan 10 2006, 19:17 prottoss Цитата(ObitJr @ Jan 11 2006, 02:17) Я дум... Jan 10 2006, 19:57 sensor_ua указатель void, ИМХО, действительно не может знать... Jan 10 2006, 20:27 ObitJr 1. Если что-то кажется, я конечно извеняюсь, есть... Jan 10 2006, 21:33 dxp Цитата(ObitJr @ Jan 11 2006, 03:33) 1. Ес... Jan 11 2006, 07:19  &-rey to Old1:
Спасибо, просмотрел Ваши функции, узнал д... Jan 11 2006, 07:55   ObitJr Ищем книгу "The New C Standard - An economic ... Jan 11 2006, 09:02   Old1 To &-rey.
ЦитатаА вот если в функции с __gener... Jan 12 2006, 09:57    &-rey to Old1:
Спасибо за ссылку, мои подозрения оправда... Jan 12 2006, 11:49    Old1 Цитата(Old1 @ Jan 12 2006, 13:57) ...если... Jan 13 2006, 09:58 _artem_ esli vse taki xotite manipulirovat void v funkcii ... Jan 11 2006, 16:22 &-rey Цитата(_artem_ @ Jan 11 2006, 20:22) esli... Jan 11 2006, 16:38
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|