Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Шаблоны функций с указателями


Автор: TarasProger 13.8.2015, 09:05
1. Максимум линейного массива:
Код
template <typename Type> Type *Max(Type *Data, size_t Count)
{
 Type *End;
 Type *Result;
 for (End=Data+Count-1, Result=Data, ++Data; Data<=End; ++Data)
 {
  if ((*Data)>(*Result))
  {
   Result=Data;
  }
 }
 return Result;
}
.
Не проверяет валидность указателя на массив и фактическое количество элементов, полностью полагаясь на вызывающий код. Находит указатель на максимальный элемент массива. Если требуется значение элемента, указать надо разыменовать: 
Код
double m;
double a[200];
...
m=*Max(a, 200);
. Если нужен индекс элемента, то из указателя на максимальный элемент надо вычесть указатель на сам массив: 
Код
double m;
double a[200];
...
m=Max(a, 200)-a;
.
2. Минимум линейного массива:
template <typename Type> Type *Min(Type *Data, size_t Count)
{
 Type *End;
 Type *Result;
 for (End=Data+Count-1, Result=Data, ++Data; Data<=End; ++Data)
 {
  if ((*Data)<(*Result))
  {
   Result=Data;
  }
 }
 return Result;
}.
Не проверяет валидность указателя на массив и фактическое количество элементов, полностью полагаясь на вызывающий код. Находит указатель на минимальный элемент массива. Если требуется значение элемента, указать надо разыменовать: 
Код
double m;
double a[200];
...
m=*Min(a, 200);
. Если нужен индекс элемента, то из указателя на минимальный элемент надо вычесть указатель на сам массив: 
Код
double m;
double a[200];
...
m=Min(a, 200)-a;
.
3. Средее арифметическое линейного массива:
Код
template <typename Type> Type Ave(Type *Data, size_t Count)
{
 Type *End;
 Type  Result;
 for (End=Data+Count-1, Result=(Type)0.0; Data<=End; ++Data)
 {
  Result+=*Data;  
 }
 return Result/((Type)Count);
}
.
Не проверяет валидность указателя на массив и фактическое количество элементов, полностью полагаясь на вызывающий код. Не безопасна относительно переполнения типа. Округляет до результа до точности базового типа массива, причём, по правилам, действующим для оператора деления операндов этого типа.

Автор: TarasProger 13.8.2015, 09:25
4. Пузырьковая сортировка линейного массива по возрастанию:
Код
template <typename Type> void Increase(Type *Data, size_t Count)
{
 Type *End;
 Type *i;
 Type *j;
 Type  Tempory;
 for (End=Data+Count-1, i=Data; i<End; ++i)
 {
  for (j=i+1; j<=End; ++j)
  {
   if ((*i)>(*j))
   {
    Tempory=*i;
    *i=*j;
    *j=Tempory;
   }
  }
 }
}
.
Не проверяет валидность указателя на массив и фактическое количество элементов, полностью полагаясь на вызывающий код. Время работы функции с ростом количества элементов растёт квадратично..
5. Пузырьковая сортировка линейного массива по убыванию:
Код
template <typename Type> void Decrease(Type *Data, size_t Count)
{
 Type *End;
 Type *i;
 Type *j;
 Type  Tempory;
 for (End=Data+Count-1, i=Data; i<End; ++i)
 {
  for (j=i+1; j<=End; ++j)
  {
   if ((*i)<(*j))
   {
    Tempory=*i;
    *i=*j;
    *j=Tempory;
   }
  }
 }
}
.
Не проверяет валидность указателя на массив и фактическое количество элементов, полностью полагаясь на вызывающий код. Время работы функции с ростом количества элементов растёт квадратично..

Автор: volatile 13.8.2015, 11:32
Тему нужно переименовать в "как не нужно писать программы"

Автор: TarasProger 13.8.2015, 11:36
Энто с какого?

Автор: volatile 13.8.2015, 11:40
Цитата(TarasProger @  13.8.2015,  11:36 Найти цитируемый пост)
Энто с какого? 

Хотя бы потому что ни одна из них не обрабатывает банального случая с нулевой длиной массива.

Не изобретайте велосипедов.
Смотрите как писать в STL


Автор: TarasProger 13.8.2015, 13:43
Цитата(volatile @  13.8.2015,  11:40 Найти цитируемый пост)
Хотя бы потому что ни одна из них не обрабатывает банального случая с нулевой длиной массива.
А должна? Кстати, при нулевой длине End сразу меньше Data, цикл не запустится, но Result будет присвоен. В случае Ave он получит нулевое значение, что адекватно задаче. Сортирующие функции просто ничего не сделают, Result в них просто нет. А что они должны делать при нулевой длине массива? И даже при единичной? А Max и Min отработают при нулевой длине адекватно в том лишь случае, если и указатель на массив равен nullptr (его и вернут). Но все эти функции должны получать только валидные данные, а значит только существующие массивы. Провреки просто вынесены в вызывающий код.

Автор: volatile 13.8.2015, 15:00
да фиг с ним с нулевым размером (хотя это первый признак вшивости.)
но оно и с обычными то не работает
среднее значение 10 и 12, оказывается рано 6
http://codepad.org/WiZgbfqG

TarasProger, мне честно говоря не хочется тратить время на полное обсуждение ваших поделок.
просто предупредил новичков чтобы не думали что в этой теме следует чему-то учиться
удачи

Автор: TarasProger 13.8.2015, 15:12
Исправил.

Добавлено через 13 минут и 21 секунду
Цитата(volatile @  13.8.2015,  15:00 Найти цитируемый пост)
да фиг с ним с нулевым размером (хотя это первый признак вшивости.)
Первый признак вшивости - это когда одна и та же проверка одного и того же массива расползается по всему коду. Вот смотри: создаёшь ты массив. Он что, может быть пустым? Нет конечно. Но система может вернуть nullptr, значит это надо проверить сразу же, а не откладывать до функции. Ладно оставил ты это функции, но тебе надо и отсортировать, и найти ома экстремальных элемента, и ещё посчитать среднее. Ты будешь тратить время эти проверки в каждой функции? Дальше, деларируешь ты не динамический массив, а обычный. Он пустым быть не может чисто синтаксически. Будешь его проверять? Таких проверок по всему коду могут быть тысячи, при этом нужна будет в лучшем случае одна и если её не пройдёшь, то до этих функций в принципе не должен дойти. Дальше, хорошо, пусть у тебя свои функции все занимаются проверками. Эйси. В плане производительности не много потеряешь. Это повод не делать проверку в момет создания?
1. Когда нибудь додумаешься передать какой нибудь массив какой нибудь мелкомягкой функциии, а их глючность всем известна.
2. Даже если и нет, эйси, проверяет массив функция, которая массив должна обработать. И что она должна сделать? Причём, вызвана она может быть из тысяч мест, в каждом из которых ты будешь вынужден проверять уже её результат. При этом не очень то понятно, как на него реагировать.
Это вместо того, чтоб до функии просто не дойти.

Автор: TarasProger 13.8.2015, 15:46
Причём, если на nullptr функция ещё может обработать, то проверить валидность указателя и фактическое количество элементов она не может в приципе, при создании же массива известно, какого размера он задуман и он или создаётся имеено такого размера, или не создаётся вовсе, при этом повзращается не мусорный указатель, а nullptr. Так зачем раскидывать по функциям проверки, которые всё равно не будут работать?

Автор: TarasProger 13.8.2015, 17:27
Да, в Ave при нулевой длине фигня получится дальге. При деление на 0. А в сортирках не получится.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)