Комментарий к этой странице в документации MySQL имеет следующее предложение:
-- (mostly) High Performance scaling MEDIAN function per group
-- Median defined in http://en.wikipedia.org/wiki/Median
--
-- by Peter Hlavac
-- 06.11.2008
--
-- Example Table:
DROP table if exists table_median;
CREATE TABLE table_median (id INTEGER(11),val INTEGER(11));
COMMIT;
INSERT INTO table_median (id, val) VALUES
(1, 7), (1, 4), (1, 5), (1, 1), (1, 8), (1, 3), (1, 6),
(2, 4),
(3, 5), (3, 2),
(4, 5), (4, 12), (4, 1), (4, 7);
-- Calculating the MEDIAN
SELECT @a := 0;
SELECT
id,
AVG(val) AS MEDIAN
FROM (
SELECT
id,
val
FROM (
SELECT
-- Create an index n for every id
@a := (@a + 1) mod o.c AS shifted_n,
IF(@a mod o.c=0, o.c, @a) AS n,
o.id,
o.val,
-- the number of elements for every id
o.c
FROM (
SELECT
t_o.id,
val,
c
FROM
table_median t_o INNER JOIN
(SELECT
id,
COUNT(1) AS c
FROM
table_median
GROUP BY
id
) t2
ON (t2.id = t_o.id)
ORDER BY
t_o.id,val
) o
) a
WHERE
IF(
-- if there is an even number of elements
-- take the lower and the upper median
-- and use AVG(lower,upper)
c MOD 2 = 0,
n = c DIV 2 OR n = (c DIV 2)+1,
-- if its an odd number of elements
-- take the first if its only one element
-- or take the one in the middle
IF(
c = 1,
n = 1,
n = c DIV 2 + 1
)
)
) a
GROUP BY
id;
-- Explanation:
-- The Statement creates a helper table like
--
-- n id val count
-- ----------------
-- 1, 1, 1, 7
-- 2, 1, 3, 7
-- 3, 1, 4, 7
-- 4, 1, 5, 7
-- 5, 1, 6, 7
-- 6, 1, 7, 7
-- 7, 1, 8, 7
--
-- 1, 2, 4, 1
-- 1, 3, 2, 2
-- 2, 3, 5, 2
--
-- 1, 4, 1, 4
-- 2, 4, 5, 4
-- 3, 4, 7, 4
-- 4, 4, 12, 4
-- from there we can select the n-th element on the position: count div 2 + 1
void
имеет более одного использования; это все. void
и void*
очень разные звери. Обратите внимание, что void*
- это не ключевое слово, а void
-
Не думайте о void*
как о вашей структуре. Это просто указатель, который был преобразован из другого типа путем приведения. malloc
возвращает void*
, который может быть преобразован в другой тип указателя с помощью механизма, который несколько парадоксально делает невозможным запись malloc
в переносимый C.
Использование ключевого слова void
может действительно иметь различную семантику в зависимости от контекста:
void myfunction(...) { ... }
или в [ 112] void *p = ...;
В C указатель void - это указатель, который может указывать на что угодно. В C ++ также следует избегать использования, насколько это возможно, и std::any
следует отдавать предпочтение.
Важное замечание о вашей воображаемой реализации: указатель void сам по себе ничего не знает о размере объекта, на который он указывает.
void
- это тип, который ( C11 6.2.5p19 )
содержит пустой набор значений; это неполный тип объекта, который не может быть завершен.
blockquote>И
void *
- это тип указателя, который указывает на объект указанного типа.Любой тип указателя объекта может быть преобразован в другой тип указателя объекта с явным приведением , учитывая, что указатель соответствующим образом выровнен; единственное преобразование между типами указателей, которое может произойти без преобразования в C, - это преобразования в
void *
и обратно; отсюда статусvoid *
как тип общего указателя.Тип
void
сам по себе может использоваться для других задач - например, выражение может быть приведено кvoid
, чтобы сигнализировать, что значение намеренно игнорируется, или использоваться как тип возвращаемого значения, чтобы сигнализировать, что функция не возвращает значение. Единственная семантическая перегрузка - использованиеvoid
в прототипе:int func(void)
, чтобы сигнализировать, что функция не принимает никаких аргументов.