Это не имеет ничего общего с qsort
и bsearch
самих функций, а имена функций неявно преобразуются компилятором в указатели на функции в соответствии со стандартом, C11 6.3.2.1 Language/Conversions/Other operands/Lvalues, arrays, and function designators
:
Функция целеуказатель является выражением, которое имеет тип функции. За исключением случаев, когда это операнд оператора sizeof, оператор _Alignof или унарный оператор &, обозначение функции с типом «возвращающий функцию типа» преобразуется в выражение, которое имеет тип «указатель на возвращаемый тип функции».
Это означает, что, когда вы проходите compar
к qsort()
(к примеру), это фактический указатель на функцию, которая будет послана, а не какой-то «по существу случайное слово».
Причины неявным лечения идентификатор функции в качестве своего адреса лежат давно в прошлом, но (и весь этот раздел предположение с моей стороны, на основании того, что я хотел бы рассмотреть интеллектуальные рассуждения, но в никак не окончательный), вероятно, это потому, что значение функции не имеет смысла. С идентификатором int i = 5;
, он имеет a значение (5), и вы также можете использовать &i
, чтобы получить его адрес.
Однако для функций они действительно не имеют значений как таковых. Вы можете называть их генерировать a значение, xyzzy()
, и вы можете получить их адрес, &xyzzy
, для последующего вызова с помощью указателя функции.
Но у них нет реального внутреннего значения значение отдельно от их адреса, как целое число i
. Поэтому ранние компиляторы (pre-ANSI) просто разрешали стенографию xyzzy
в среднем &xyzzy
. И, конечно же, поскольку первоначальный мандат ANSI заключался в кодификации существующей практики, а не в создании нового языка, они сохранили это поведение.
Если K & R ушел в другую сторону и решил xyzzy
должен быть вызов функции не проходит никаких параметров, так же, как xyzzy()
, мир был бы в другом месте :-)
хорошо ... Что точка указателей функций? Разве это не делает их устаревшими? (поскольку void также считается возвращаемым типом) – x86ris
Точка указателя функции заключается в том, что один указатель может указывать на любую функцию. Классическим примером является массив указателей функций, индексированных по состоянию для конечного автомата, который позволяет вам называть одно из множества функций с чем-то простым, например '(fnarr [state]) (payloadpointer);' В вашем конкретном случае вы хотите иметь возможность вызывать 'qsort' с произвольной функцией сравнения (числами, строками, строками без учета регистра и т. д.). Указатель функции позволяет это сделать. – paxdiablo
+1 для цитирования стандартной ссылки – fayyazkl