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

 
 
> указатель на тип void, попытки создать общую функцию
andrvisht
сообщение Jan 3 2006, 13:06
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 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
Или может еще каким образом поступают при такой задаче, просьба поделиться опытом ...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
IgorKossak
сообщение Jan 3 2006, 14:15
Сообщение #2


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Всё, что Вы хотите легко реализуется перегружаемыми функциями в С++, а ещё элегантнее - шаблонной функцией.
Давно так делаю и очень доволен.
А если делать на С, то надо дополнительно передавать идентификатор типа и внутри универсальной функции делать приведение. Тогда и операция ++ будет работать.
Go to the top of the page
 
+Quote Post
andrvisht
сообщение Jan 3 2006, 14:26
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064



Цитата(IgorKossak @ Jan 3 2006, 18:15) *
Всё, что Вы хотите легко реализуется перегружаемыми функциями в С++, а ещё элегантнее - шаблонной функцией.
Давно так делаю и очень доволен.
А если делать на С, то надо дополнительно передавать идентификатор типа и внутри универсальной функции делать приведение. Тогда и операция ++ будет работать.

Попробовал sprintf() но сгенеренный код получился в 2 раза больше по времени выполнения.
это если я Вас правильно понял всмысле перегружаемых.
а что такое шаблонная функция ?
В С я новичок, поэтому может какие термины еще не знаю sad.gif
а разве
Код
(char*)pStr++;

Это не приведение типа ? вот на такой вариант компилятор говорит:
Error[Pe852]: expression must be a pointer to a complete object type

как правильно написать чтобы ++ работал?
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 3 2006, 15:38
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 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*...}

..........
}


--------------------
Go to the top of the page
 
+Quote Post
defunct
сообщение Jan 7 2006, 13:30
Сообщение #5


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(prottoss @ Jan 3 2006, 17:38) *
Вы сами отвечаете на свой вопрос. В Си вы не сможете объеденить два разных указателя под одним пустым типом VOID. Компилятор просто не знает, как формировать инкремент для данного типа. Указатель на SRAM изменяется линейно, указатель на FLASH имеет немного отличный механизм инкремента. Во-первых это указатель содержит адрес не байта, как в SRAM мо, а слова, где младший бит адреса указывает на тип байта в слове (старший или младший).


Вот это хит! ;>

Дело в том, что если взять адрес слова, и сдвинуть его на 1 влево, а освободившийся младший бит использовать для адресации байта (старшего и младшего), то получится линейный указатель, точно такой же как тот, что адресует (по вашим словам) SRAM. И действительно физически это одна и та же регистровая пара Z.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 7 2006, 21:17
Сообщение #6


Гуру
******

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



Цитата(defunct @ Jan 7 2006, 20:30) *
Цитата(prottoss @ Jan 3 2006, 17:38) *

Вы сами отвечаете на свой вопрос. В Си вы не сможете объеденить два разных указателя под одним пустым типом VOID. Компилятор просто не знает, как формировать инкремент для данного типа. Указатель на SRAM изменяется линейно, указатель на FLASH имеет немного отличный механизм инкремента. Во-первых это указатель содержит адрес не байта, как в SRAM мо, а слова, где младший бит адреса указывает на тип байта в слове (старший или младший).


Вот это хит! ;>

Дело в том, что если взять адрес слова, и сдвинуть его на 1 влево, а освободившийся младший бит использовать для адресации байта (старшего и младшего), то получится линейный указатель, точно такой же как тот, что адресует (по вашим словам) SRAM. И действительно физически это одна и та же регистровая пара Z.


Хит это или нет, но я и имел ввиду, что компилятор не знает, сдвигать указатель на бит или нет. Читайте внимательнее топики (или купите монитор многодюймовый)


--------------------
Go to the top of the page
 
+Quote Post
defunct
сообщение Jan 9 2006, 15:36
Сообщение #7


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(prottoss @ Jan 7 2006, 23:17) *
Цитата(defunct @ Jan 7 2006, 20:30) *
Цитата(prottoss @ Jan 3 2006, 17:38) *

Вы сами отвечаете на свой вопрос. В Си вы не сможете объеденить два разных указателя под одним пустым типом VOID. Компилятор просто не знает, как формировать инкремент для данного типа. Указатель на SRAM изменяется линейно, указатель на FLASH имеет немного отличный механизм инкремента. Во-первых это указатель содержит адрес не байта, как в SRAM мо, а слова, где младший бит адреса указывает на тип байта в слове (старший или младший).


Вот это хит! ;>

Дело в том, что если взять адрес слова, и сдвинуть его на 1 влево, а освободившийся младший бит использовать для адресации байта (старшего и младшего), то получится линейный указатель, точно такой же как тот, что адресует (по вашим словам) SRAM. И действительно физически это одна и та же регистровая пара Z.


Хит это или нет, но я и имел ввиду, что компилятор не знает, сдвигать указатель на бит или нет. Читайте внимательнее топики (или купите монитор многодюймовый)


"Не говорите мне что делать, и я не скажу Вам куда идти" © begin...end. smile.gif

В Вашей цитате не было написано того, о чем Вы сейчас говорите. Чтобы сказанное Вами было понятно не только Вам, а всем, я бы добавил, что указатели на Flash могут быть двух типов:
1. указатель на функцию - тогда флеш указатель указывает на СЛОВО (сдвинут на 1 вправо);
2. указатель на данные - тогда флеш указатель указывает на БАЙТ (линейный указатель как и при адресации SRAM).

Согласитесь, что "указатель содержит адрес не байта, как в SRAM мо, а слова, где младший бит адреса указывает на тип байта в слове (старший или младший)" - фраза не совсем понятная и не раскрывает сути вопроса.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- &-rey   указатель на тип void   Jan 3 2006, 13:06
||- - &-rey   Цитата(prottoss @ Jan 3 2006, 19:38) В Си...   Jan 3 2006, 15:50
|||- - prottoss   [quote name='&-rey' date='Jan 3 20...   Jan 3 2006, 16:17
|||- - SSerge   Цитата(&-rey @ Jan 3 2006, 21:50...   Jan 3 2006, 18:04
||- - 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


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

 


RSS Текстовая версия Сейчас: 18th June 2025 - 01:35
Рейтинг@Mail.ru


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