Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Функция, выполняющая действия с аргументами разных типов
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
alux
Т.е. чтобы в функцию передавался аргумент, который может быть как 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? Возможна ли такая перегрузка функции?
KRS
Так у вас сейчас вообще у функции аргументов нет!
Все через глобальные переменные.
Причем ptr - указатель на беззнаковый тип. и адрес переменной offset ему будет присваивать не корректно.
DRUID3
Цитата(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

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

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

В общем я подумал, проще будет написать отдельную функцию для работы с знаковыми переменными. И соответственно создать указатель знакового типа. Или будут другие предложения?
vet
Термин "перегруженная функция" означает две или больше функций, которые работают с разным числом и типом аргументов, но носят одно и то же имя. Такое допустимо в С++; соответственно, модуль, в котором они описаны, должен быть написан на С++ и объявлен в проекте, как С++ модуль.
А так ли оно нужно в данном случае? может, достаточно простого приведения типа переменной?
alux
Цитата(DRUID3 @ Jun 15 2007, 00:02) *
Хоть три ( biggrin.gif ) переменных сразу обрабатуйте. Не очень элегантно, но ... smile.gif
А чо функция так называеЦЦо? Валкодер крутите?

Нет, не спасет. Функция в один момент времени должна работать только с одной переменной.
dxp
Цитата(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


В общем, Вам бы надо поконкретнее определиться, что именно Вам нужно, и уже на основе этого выбирать средство для реализации.
alux
Цитата(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);
dxp
Цитата(alux @ Jun 15 2007, 15:33) *
Вот это уже ближе к делу. А есть ли такая возможность (создание шаблонов) в Си?

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

У меня проект Си-шный. Так можно пользоваться или нет? Как включить режим ++ ? Компилятор IAR v.4.12A
KRS
Цитата(alux @ Jun 15 2007, 13:31) *
У меня проект Си-шный

Если функция маленькая замените ее на #define, но вот если с разными типами вам нужны разные дипазоны, то диапазоны надо тоже как параметры пердавать
alux
Номер с template не прошел. Проще действительно создать раздельные функции для для разных типов переменных.
Сергей Борщ
Цитата(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, только С++. Если у вас "номер не прошел" в С++, значит вы просто не смогли правильно объяснить компилятору, чего вы от него хотите.
alux
Цитата(Сергей Борщ @ 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-го) варианта сразу не додумался.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.