1123 Да, есть альтернатива. В стандартной библиотеке C уже есть функция под названием qsort
(которая, вероятно, является сокращением быстрой сортировки, но это может быть и любой другой алгоритм сортировки). Чтобы использовать эту функцию, вы передаете ей массив, количество элементов в массиве, размер каждого элемента и функцию сравнения.
Вам просто нужно написать функцию сравнения для каждого типа данных, как показано в примере на этой странице.
Если вы хотите объединить 4 функции сравнения в одну функцию, вам нужно передать некоторую контекстную информацию в функцию сравнения. В этом случае вы больше не можете использовать qsort
, но должны использовать qsort_s
. Тогда ваша функция сравнения может выглядеть следующим образом:
#define compare(a, b) (((a) > (b)) - ((b) > (a)))
#define compare_ptr(type) (compare(*(type *)(p1), *(type *)(p2)))
static int compare_by_type(const void *p1, const void *p2, void *ctx) {
int type = *(int *) ctx;
switch (type) {
case 1: return compare_ptr(short);
case 2: return compare_ptr(int);
case 3: return compare_ptr(float);
case 4: return compare_ptr(double);
default: return 0;
}
}
#undef compare
#undef compare_ptr
int main(void) {
int iarray[] = {1, 6, 4, 9, 55, 999, -33333};
int sort_type = 1;
qsort_s(iarray, 7, sizeof(int), compare_by_type, &type);
}
Это довольно продвинутый материал:
Но, в конце концов, добавить дополнительные типы в список тривиально До тех пор, пока они поддерживают оператор <
.
Обратите внимание, что float
и double
даже не принадлежат к этой категории, поскольку их оператор <
возвращает false
, как только одно из чисел равно NaN
, что означает «Не число», и приводит к из выражений, таких как 0.0 / 0.0
. Как только у вас есть такое значение в массиве, поведение становится неопределенным. Функция сортировки может даже застрять в бесконечном цикле. Чтобы исправить это, измените определение макроса compare
:
#define compare(a, b) (((a) > (b)) - !((b) <= (a)))
Теперь это выглядит еще сложнее, но работает для NaN
. Например:
compare(NaN, 5)
= (NaN > 5) - !(5 <= NaN)
= false - !(5 <= NaN)
= false - !(false)
= false - true
= 0 - 1
= -1
Это означает, что NaN будет отсортирован в начало массива.
compare(NaN, NaN)
= (NaN > NaN) - !(NaN <= NaN)
= false - true
= -1
Черт возьми. Сравнение двух NaN должно было привести к 0, что означает, что они равны. Таким образом, в этом особом случае необходимо внести поправку:
#define compare(a, b) (((a) > (b)) - ((b) > (a)) - ((a) != (a) || (b) != (b)))
Поскольку NaN
является единственным значением, которое сравнивает неравномерно с самим собой, этот дополнительный код не влияет на целочисленную арифметику и должен быть оптимизирован путем компилятор.
Определите ваши свойства с их значениями по умолчанию, например:
private bool _ShowBox = false;
public bool ShowBox
{
set { _ShowBox = value; }
}
или в конструкторе элемента управления, установите значения по умолчанию:
public MyControl()
{
_ShowBox = false;
}
или сгенерируйте исключение, если оно не назначено:
private bool _ShowBox = false;
public bool ShowBox
{
set { _ShowBox = value; }
get { return _ShowBox; }
}
Просто установите желаемое значение по умолчанию при объявлении переменной:
class myControl
{
private bool _showBox = true;
[PersistenceMode(PersistenceMode.Attribute), DefaultValue(false)]
public bool showBox
{
get { return _showBox; }
set { _showBox = value; }
}
}
Необязательно, вы можете добавить DefaultValueAttribute для конструктора.