Эта тема создана мною на основе вопроса
Smallest odd number in given array, заданного на сайте
Stackoverflow.
Автор вопроса подошел к решению задания следующим образом: он объявляет в функции дополнительный массив, куда копирует нечетные элементы, а затем пытается найти наименьший элемент среди нечетных элементов, записанных в новый массив.
Очевидно, что такой подход неэффективный.
В представленном коде в вопросе имеются многочисленные недостатки.
Во-первых, используется некое магическое число
5 для размерности массива.
Во-вторых, автор вопроса ошибочно предполагает, что незаполненные элементы в новом массиве, куда копируются нечетные элементы, по умолчанию инициализируются
0, что, естественно, неверно.
К тому же цикл
while, где происходит выбор минимального элемента, является бесконечным.
К сожалению, ответы на вопрос на сайте также не выдерживают критики. Например, в ответе, который признан автором вопроса лучшим, предполагается, что функция будет иметь неопределенное поведение в случае, если в исходном массиве нет нечетных элементов. Такое ограничение на функцию совершенно неоправданное.
Авторы ответов, почему-то, в объявлении параметра массива не используют квалификатор
const. К тому же либо не указывают размер массива, либо для его задания используют тип
int вместо типа
size_t.
То есть качество ответов очень низкое и не допустимо для профессиональных программистов. Увы, например, один из отвечающих, как следует из его анкеты является даже системным архитектором/разработчиком по
Java аж с 1984, и на протяжении этих лет также имел дело с
C++.
Так как может выглядеть соответствующая функция?
Сначала следует определиться с соглашениями об интерфейсе функции. Имеется два подхода.
Первый заключается в том, чтобы возвращать индекс минимального нечетного элемента. Если такой элемент не найден, то возвращаемое значение индекса, равного размеру массива. Поэтому по этому значению пользователь функции легко может определить: найден искомый минимальный элемент, удовлетворяющий заданному условию, или нет.
Второй подход может использовать соглашение, согласно которому функция будет возвращать null-указатель, если искомый минимальный элемент не найден.
Чтобы функция была более обобщенная, желательно, чтобы само условие, по которому ищется минимальный элемент, также задавалось пользователем функции в качестве параметра, то есть в виде объявления предиката.
Ниже представлена демонстрационная программа поиска минимального элемента массива согласно заданному условию. В реализации функции используется первый описанный выше подход, когда функция возвращает индекс искомого минимального элемента или размер исходного массива, если искомый элемент не найден.
Также помимо поиска минимального элемента в демонстрационной программе представлена и функция поиска максимального элемента.
// https://stackoverflow.com/questions/54180226/smallest-odd-number-in-given-array
#include <stdio.h>
size_t min_element_if( const int a[], size_t n, int pred( int ) )
{
size_t min_i = 0;
while ( min_i < n && !pred( a[min_i] ) ) min_i++;
if ( min_i != n )
{
for ( size_t i = min_i + 1; i < n; i++ )
{
if ( pred( a ) && a < a[min_i] ) min_i = i;
}
}
return min_i;
}
size_t max_element_if( const int a[], size_t n, int pred( int ) )
{
size_t max_i = 0;
while ( max_i < n && !pred( a[max_i] ) ) max_i++;
if ( max_i != n )
{
for ( size_t i = max_i + 1; i < n; i++ )
{
if ( pred( a ) && a[max_i] < a ) max_i = i;
}
}
return max_i;
}
int odd( int x )
{
return x % 2;
}
int main(void)
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t min_i = min_element_if( a, N, odd );
if ( min_i != N ) printf( "Minimum odd element is %d\n", a[min_i] );
size_t max_i = max_element_if( a, N, odd );
if ( max_i != N ) printf( "Maximum odd element is %d\n", a[max_i] );
return 0;
}
Вывод программы на консоль:
Minimum odd element is 1
Maximum odd element is 9