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

 
 
> Функция, выполняющая действия с аргументами разных типов, Как сделать перегрузку функции
alux
сообщение Jun 14 2007, 20:18
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Т.е. чтобы в функцию передавался аргумент, который может быть как unsigned char , так и signed char.
Сейчас у меня работает так::
//Глобальные переменные
unsigned char* ptr;
unsigned char val;
signed char offset;
void valcodr(void);

//Определение
void valcoder(void)
{
выполняет действия с ptr;
}

//Вызов функции, которая изменяет переменную val
ptr=&val;
valcoder();

Вопрос. Как теперь заставить функцию работать с знаковой переменной offset? Возможна ли такая перегрузка функции?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 13)
KRS
сообщение Jun 14 2007, 20:50
Сообщение #2


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Так у вас сейчас вообще у функции аргументов нет!
Все через глобальные переменные.
Причем ptr - указатель на беззнаковый тип. и адрес переменной offset ему будет присваивать не корректно.
Go to the top of the page
 
+Quote Post
DRUID3
сообщение Jun 14 2007, 21:02
Сообщение #3


山伏
*****

Группа: Свой
Сообщений: 1 827
Регистрация: 3-08-06
Из: Kyyiv
Пользователь №: 19 294



Цитата(alux @ Jun 14 2007, 23:18) *
Т.е. чтобы в функцию передавался аргумент, который может быть как unsigned char , так и signed char.
Сейчас у меня работает так::
//Глобальные переменные
unsigned char* ptr;
unsigned char val;
signed char offset;
void valcodr(void);

//Определение
void valcoder(void)
{
выполняет действия с ptr;
}

//Вызов функции, которая изменяет переменную val
ptr=&val;
valcoder();

Вопрос. Как теперь заставить функцию работать с знаковой переменной offset? Возможна ли такая перегрузка функции?

Хоть убейте, я вообще не понимаю, что Вы спрашиваете 07.gif , но может быть это спасет отца русской демократии smile.gif ?
Цитата
//Глобальные переменные
unsigned char* ptr1;
signed char* ptr2;

unsigned char val;
signed char offset;

void valcodr(void);

//Определение
void valcoder(void)
{
//безобразничает с ptr1 и ptr2;
}

//Вызов функции, которая изменяет переменные val и offset вместе взятые smile.gif

ptr1 = &val;
ptr1 = &offset;

valcoder();


У Вас же функция работает c глобальными указателями на глобальные переменные. Ничего ей не передаеЦЦо и ничего она не возвращает. Хоть три ( biggrin.gif ) переменных сразу обрабатуйте. Не очень элегантно, но когда человек покупает стиральную машину ему главное чтобы она долго и упорно работала, а не стиль зашитого в нее кода... smile.gif

А чо функция так называеЦЦо? Валкодер крутите?


--------------------
Нас помнят пока мы мешаем другим...
//--------------------------------------------------------
Хороший блатной - мертвый...
//--------------------------------------------------------
Нет старик, это те дроиды которых я ищу...
Go to the top of the page
 
+Quote Post
alux
сообщение Jun 15 2007, 06:50
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(KRS @ Jun 14 2007, 23:50) *
Так у вас сейчас вообще у функции аргументов нет!
Все через глобальные переменные.
Причем ptr - указатель на беззнаковый тип. и адрес переменной offset ему будет присваивать не корректно.

Очень ценное замечание... Я и не говорил, что сейчас в моей функции что-либо передавалось. Я спрашивал КАК сделать, чтобы функция могла работать с переменными разных типов. Возможно, это можно сделать через перегрузку функции. Как вы могли заметить, функция действительно называется valcoder. И по идее она должна изменять значение переменных, на которые указывает глобальный указатель. По крайней мере сейчас у меня так работает, только для переменных беззнакового типа.

В общем я подумал, проще будет написать отдельную функцию для работы с знаковыми переменными. И соответственно создать указатель знакового типа. Или будут другие предложения?

Сообщение отредактировал alux - Jun 15 2007, 07:16
Go to the top of the page
 
+Quote Post
vet
сообщение Jun 15 2007, 07:13
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



Термин "перегруженная функция" означает две или больше функций, которые работают с разным числом и типом аргументов, но носят одно и то же имя. Такое допустимо в С++; соответственно, модуль, в котором они описаны, должен быть написан на С++ и объявлен в проекте, как С++ модуль.
А так ли оно нужно в данном случае? может, достаточно простого приведения типа переменной?


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
alux
сообщение Jun 15 2007, 07:21
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(DRUID3 @ Jun 15 2007, 00:02) *
Хоть три ( biggrin.gif ) переменных сразу обрабатуйте. Не очень элегантно, но ... smile.gif
А чо функция так называеЦЦо? Валкодер крутите?

Нет, не спасет. Функция в один момент времени должна работать только с одной переменной.
Go to the top of the page
 
+Quote Post
dxp
сообщение Jun 15 2007, 07:22
Сообщение #7


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(alux @ Jun 15 2007, 13:50) *
Очень ценное замечание... Я и не говорил, что сейчас в моей функции что-либо передавалось. Я спрашивал КАК сделать, чтобы функция могла работать с переменными разных типов. Возможно, это можно сделать через перегрузку функции.

Все-таки не понятно, что именно Вы хотите. Перегрузка имени функции - это использование одного имени для разных фукнций. Т.е. это не одна функция, которая работает с разныими данными, а это разные функции, которые работают с разными данными. Например:

Код
void f(int x) { ... }
void f(float x) { ... }

...

f(1); // вызывается void f(int x)
f(1.0) // вызывается void f(float x)


Вообще, написать функцию, которая бы работала с разными типами данных на С++, нельзя - как компилятор будет знать, какой код ему родить, если он не знает их типов (ни размеров, ни форматов).

Существует случай, когда хотя данные и разные, но работа с ними делается единообразно, и писать аналогичный, почти повторяющийся код в разных функциях не есть достойное занятие. Для этого случая в С++ имеются шаблоны, которые позволяют описать действия функции без привязки к конкретному типу, а при использовании - инстанцировать функцию по шаблону с заданным параметром. Например:

Код
template<typename T>
T square(T x)
{
    return x*x;
}

...

    int x = square(5);

    printf("Result: %d\n", x);

    float y = square(5.0);

    printf("Result: %f\n", y);

результат:

Result: 25
Result: 25.000000


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


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
alux
сообщение Jun 15 2007, 08:33
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(dxp @ Jun 15 2007, 10:22) *
Существует случай, когда хотя данные и разные, но работа с ними делается единообразно, и писать аналогичный, почти повторяющийся код в разных функциях не есть достойное занятие. Для этого случая в С++ имеются шаблоны, которые позволяют описать действия функции без привязки к конкретному типу, а при использовании - инстанцировать функцию по шаблону с заданным параметром.

Вот это уже ближе к делу. А есть ли такая возможность (создание шаблонов) в Си?


Цитата(DRUID3 @ Jun 15 2007, 00:02) *
Не очень элегантно, но когда человек покупает стиральную машину ему главное чтобы она долго и упорно работала, а не стиль зашитого в нее кода... smile.gif

Согласен. Некрасиво работать через указатель на глобальные переменные. Сделал так:

unsigned char value1;
signed char value2;
unsigned char valcoder(unsigned char);

unsigned char valcoder(unsigned char x)
{
if(++x>250) x=0;
................
}

//Вызов функции:
value1=valcoder(value1);

Для переменной signed char value2 функция valcoder должна сделать то же самое, отличие состоит только в проверке на другой диапазон.
Если создать шаблонную функцию, как говорил dxp, можно ли создать специализированную версию функции? Например вот так:

template <typename T>
signed char valcoder(T x)
{
if(++x>120) x=0;
..............
}

//Вызов функции:
value2=valcoder(value2);

Сообщение отредактировал alux - Jun 15 2007, 08:47
Go to the top of the page
 
+Quote Post
dxp
сообщение Jun 15 2007, 09:13
Сообщение #9


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(alux @ Jun 15 2007, 15:33) *
Вот это уже ближе к делу. А есть ли такая возможность (создание шаблонов) в Си?

Нет, шаблоны - это С++ная фишка. А в чем проблема-то? Кроссплатформенный компилятор IAR вполне поддерживает шаблоны. Не только шаблоны функций, но и классов. Если компилятор умеет - пользуйтесь. Только надо режим ++ включить у компилятора.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
alux
сообщение Jun 15 2007, 09:31
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(dxp @ Jun 15 2007, 12:13) *
Нет, шаблоны - это С++ная фишка. А в чем проблема-то? Кроссплатформенный компилятор IAR вполне поддерживает шаблоны. Не только шаблоны функций, но и классов. Если компилятор умеет - пользуйтесь. Только надо режим ++ включить у компилятора.

У меня проект Си-шный. Так можно пользоваться или нет? Как включить режим ++ ? Компилятор IAR v.4.12A

Сообщение отредактировал alux - Jun 15 2007, 09:34
Go to the top of the page
 
+Quote Post
KRS
сообщение Jun 15 2007, 09:38
Сообщение #11


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(alux @ Jun 15 2007, 13:31) *
У меня проект Си-шный

Если функция маленькая замените ее на #define, но вот если с разными типами вам нужны разные дипазоны, то диапазоны надо тоже как параметры пердавать
Go to the top of the page
 
+Quote Post
alux
сообщение Jun 15 2007, 09:45
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Номер с template не прошел. Проще действительно создать раздельные функции для для разных типов переменных.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 15 2007, 20:13
Сообщение #13


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(alux @ Jun 15 2007, 12:45) *
Номер с template не прошел. Проще действительно создать раздельные функции для для разных типов переменных.
Я конечно не знаю, какие магические действия делает ваша функция с глобальной переменной с помощью глобального указателя. То, что эти глобальные переменные никоим образом не являются аргументами функции вам уже объяснили. Но может вам подойдет такой вариант:
Код
signed char Valcoder()   // не более +-127 пупок за раз
{


}
signed char Offset;
unsigned char Val1;
unsigned int Val2;
signed long Val3;

void Test()
{
   Offset += Valcoder(); if(Offset > 100) Offset = 100; else if(Offset < -100) Offset = -100;
   Val1 += Valcoder(); if(Val1 > 200) Val = 0;
   Val2 += Valcoder();
   Val3 += Valcoder();
}
или такой вариант, используя действительно параметры функции:
Код
signed int Valcoder(signed int init, signed int min, signed int max)
{
   signed int Value = init;
...........
   if(Value < min) Value = min;
   if(Value > max) Value = max;
..........
  return Value;

}
signed char Offset;
unsigned char Val1;
unsigned int Val2;

void Test()
{
   Offset = Valcoder(Offset, -100, 100);
   Val1 = Valcoder(Val1, 0, 200);
   Val2 = Valcoder(Val2, 0, 65535);
}
Цитата(alux @ Jun 15 2007, 12:45) *
Номер с template не прошел.
Если вы пытались использовать их в С, то вас предупреждали - С не знает о template, только С++. Если у вас "номер не прошел" в С++, значит вы просто не смогли правильно объяснить компилятору, чего вы от него хотите.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
alux
сообщение Jun 16 2007, 20:32
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(Сергей Борщ @ Jun 15 2007, 23:13) *
Но может вам подойдет такой вариант:
Код
signed char Valcoder()   // не более +-127 пупок за раз
{
}
signed char Offset;
unsigned char Val1;
unsigned int Val2;
signed long Val3;

void Test()
{
   Offset += Valcoder(); if(Offset > 100) Offset = 100; else if(Offset < -100) Offset = -100;
   Val1 += Valcoder(); if(Val1 > 200) Val = 0;
   Val2 += Valcoder();
   Val3 += Valcoder();
}
или такой вариант, используя действительно параметры функции:
Код
signed int Valcoder(signed int init, signed int min, signed int max)
{
   signed int Value = init;
...........
   if(Value < min) Value = min;
   if(Value > max) Value = max;
..........
  return Value;

}
signed char Offset;
unsigned char Val1;
unsigned int Val2;

void Test()
{
   Offset = Valcoder(Offset, -100, 100);
   Val1 = Valcoder(Val1, 0, 200);
   Val2 = Valcoder(Val2, 0, 65535);
}
Если вы пытались использовать их в С, то вас предупреждали - С не знает о template, только С++. Если у вас "номер не прошел" в С++, значит вы просто не смогли правильно объяснить компилятору, чего вы от него хотите.

"Универсальность" функции - не всегда выгодна. Ваш первый вариант больше на 55 байт, чем вариант з раздельными функциями (для signed и unsigned char). Второй вариант не проверял, но он мне не совсем подходит. Но все-равно спасибо. Странно, что я до Вашего (1-го) варианта сразу не додумался.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 16:16
Рейтинг@Mail.ru


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