2017-01-17 3 views
1

Я хочу передать функцию в другую функцию, но я так сильно смутил синтаксис и то, что на самом деле происходит. Это код, который я бегу:Передача функции в другую функцию в C

#include <stdio.h> 

int func(int a){ 
    printf("%d\n", a); 
} 

void another_func(int p_func(int)){ 
int (*funcptr)(int) = p_func; 
funcptr(7); 
} 

int main(void){ 

    another_func(func); 

    return 0; 
} 

Однако, я обнаружил, что я могу поставить сколько Звездочка я хочу, прежде чем FUNC при вызове его в основном, к примеру:

another_func(*******************func); 

Я сделать то же самое при назначении функции указателя функции, например:

int (*funcptr)(int) = ***********p_func; 

Я хотя запрещено ставить амперсанд перед p_func при назначении его к указателю функции. Кроме того, кажется, не имеет значения, если я пишу:

void another_func(int (*p_func)(int)){ 

Может ли мой просить о помощи после некоторых легендарных богов C от спячки, которые могут сделать подробное объяснение? Я действительно не понимаю, как это работает, что передается и т. Д.

ответ

2

Согласно стандарту C (6.3.2.1 Lvalues, массивы и функции десигнаторами)

4 Функция целеуказатель является выражением, имеет тип функции. За исключением случаев, когда это операнд SIZEOF operator65) или унарным & оператор, функция целеуказатель с типом «» функции возвращающегося типа «» преобразуется в выражение, которое имеет тип «» указатель на функцию возвращающегося типа» '

с другой стороны (6.5.3.2 Адрес и операторы) косвенного предоставления

4 унарный * оператор обозначает косвенность. Если операнд указывает на функцию, результатом будет обозначение функции;

Таким образом, вы можете поместить столько звёздочки перед функцией целеуказателем как компилятор позволит в соответствии со своими собственными пределами. :)

И вы можете использовать оператор & с функцией целеуказателем. Например,

#include <stdio.h> 

int f(int x) 
{ 
    return x; 
} 

int main(void) 
{ 
    int (*fp)(int) = &f; 

    printf("%d\n", fp(10)); 

    return 0; 
} 

Учтите, что параметр функции, объявленный как функция, настраивается на указатель на тип функции.

Таким образом, эти две декларации функции объявить ту же одну функцию и могут быть оба присутствуют в модуле компиляции (хотя функция должна быть определена один раз, если он не встраивать)

void another_func(int p_func(int)); 
void another_func(int (*p_func)(int)); 
+0

Итак, по сути функциональные выражения всегда преобразуются в обозначения функций, независимо от того, что? –

+0

@NoobDoob Обозначение функции всегда преобразуется в указатель функций с редкими исключениями, перечисленными в представленной цитате из стандарта C. –

+0

Итак, когда я передаю функцию another_func, она автоматически становится указателем, тем самым помещая амперсанд раньше, как я сказал, незаконным? –

0

«Я узнал, что могу указать, сколько астерикс я хочу, прежде чем func при вызове в главном». Я не хочу вас обидеть, но я предлагаю вам прочитать что-нибудь о указателях. Пример о том, что вы ищете может быть:

int foo(int (*foo2)(void)) 
{ 
    foo2(); 
} 

int foo2(void) 
{ 
    return rand(); 
} 

int main(void) 
{ 
    foo(foo2); 
} 
+0

Есть тонны вещей, написанных о указатели. Разработайте то, что вы имеете в виду, что я не понимаю о указателях. –

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