2013-10-03 2 views
0

Интересно, когда мы создаем функциюQSort и функция bsearch ... «указатель»

int compar(const void *, const void *) 

, и мы просто передать его имя в один из параметров qsort и bsearch, как эти функции распознают сказал по существу случайное слово (поскольку мы никогда не указывали явно, что это указатель на функцию, а скорее фактическая функция) и использовать его как параметр? Есть ли явное выражение в объявлениях функций qsort и bsearch или что-то в этом роде?

ответ

3

Это не имеет ничего общего с 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(), мир был бы в другом месте :-)

+0

хорошо ... Что точка указателей функций? Разве это не делает их устаревшими? (поскольку void также считается возвращаемым типом) – x86ris

+1

Точка указателя функции заключается в том, что один указатель может указывать на любую функцию. Классическим примером является массив указателей функций, индексированных по состоянию для конечного автомата, который позволяет вам называть одно из множества функций с чем-то простым, например '(fnarr [state]) (payloadpointer);' В вашем конкретном случае вы хотите иметь возможность вызывать 'qsort' с произвольной функцией сравнения (числами, строками, строками без учета регистра и т. д.). Указатель функции позволяет это сделать. – paxdiablo

+0

+1 для цитирования стандартной ссылки – fayyazkl

Смежные вопросы