2013-02-20 1 views
4

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

int func1(char *ptr) 
{ 
    printf("%s",ptr); 
    return 0; 
} 

и другие функции, в которой я хочу назвать FUNC1

int func2(void *i) 
{ 
    //call i 
    //here i point to function func1 
    //and do something with return value of i 
} 

Итак, как я могу назвать это в main()?

int main() 
{ 
    void *d; 
    //SOMETHING wrong in next four line 
    d=&func1("abcd"); 
    func2(d); 
    d=&func1("xyz"); 
    func2(d); 
    return 0; 
} 
+3

Для этого вам нужно использовать указатель на функцию. Также 'main' не принимает параметр' void * '. –

+0

Извините, я не использовал void * i в main, поэтому удалил его – Gaurav

+0

@gauravmeena d = & func1 ("abcd"); может не работать, потому что func1 («abcd») предоставит данные, возвращаемые func1 (что совсем не так), а не адрес func1 .. –

ответ

3

Вы можете просто создать function (func2), который принимает указатель на нужную функцию, которую вы хотите вызвать, и другой параметр, который принимает указатель на вашу строку. Затем в func2 вызовите переданный в функцию указатель функции с аргументом str.

#include <stdio.h> 

void func1(const char *str) 
{ 
    puts(str); 
} 

void func2(void (*fp)(const char *), const char *str) 
{ 
    fp(str); 
} 

int main(void) 
{ 
    const char *str = "Hello world."; 

    func2(func1, str); 

    return 0; 
} 
+0

Спасибо за ответ. – Gaurav

+0

@kludas да, это самый подходящий способ. но я увидел один из комментариев gauravmeena, что func2 - это функция lib и что разрешен только указатель void. вы также можете передать структуру с указателем функции и строкой (как char *) в качестве членов и вернуть ее обратно в структуру func2? –

+0

@ Koushik да это было ограничение для меня, но в вашем ответе вы поместили строку в func2 .... Kludas также может сделать это и сделать func2 с одним параметром в качестве входа. Единственный способ передать строку из main - использовать struct, как вы предложили – Gaurav

1

см это Function pointers и читать на Wiki - Function Pointers, и вы будете знать, как исправить код.

+1

Хороший ответ в духе SO содержит хотя бы минимальный ответ на вопрос. Затем ссылки могут помочь в детализации деталей или содержать примеры. – alk

2

Вы должны в первую очередь использовать указатели функций для выполнения желаемой вами работы. Использование указателя void - это метод, в котором вы должны знать, что именно вы будете использовать для разыменования. Поскольку вы передаете адрес функции, вы должны в любой момент отнести ее к указателю на функцию. Поэтому избегайте всего этого и объявляйте указатель func в любом случае. Используйте void * только, если вы знаете, что можете обрабатывать все возможности. например. memcpy использует void * это приемлемо, поскольку вы просто хотите, чтобы куча данных в местонахождении soure была скопирована в место назначения.

#include <stdio.h> 
void func1(char * str) 
{ 
    printf("%s",str); 
} 
void func2(void * g) 
{ 
    void (*p) (char *); //function pointer 
    p = (void (*)(char *))g;//casting void * to pi.e func pointer reqiuired eitherways. 
    p("Func pointer caller"); 
} 
void main() 
{ 
    void * d = func1; // name of the function is itselt its address 
    //printf("func1 = %d\nd = %d",func1,d); 
    func2(d); 
} 

все это можно избежать простым указателем на функцию.

+0

Несмотря на то, что он оставил одну проблему (отправка * str из основного) ... Это функциональность, которую я хотел. Спасибо – Gaurav

+0

@ gauravmeena0708 да, это не дает этой функции, так как нет прямого способа сделать это. Могут быть обходные пути для этого, но они будут только обходными решениями для этой конкретной ситуации, но не общим обходным решением. –

+0

В стандарте C не указывается указатель на указатель данных и наоборот. http://stackoverflow.com/a/5579907/1005312 – Kludas

0

Jatin уже разместил общую ссылку на указатели функций, очень хорошо объясняя указатели на функции.

Как вы, швы хотите передать не классический указатель функции, а указатель функции С его аргументом как один «указатель на функцию» к другой функции, я не думаю, что это сработает.

Но зачем передавать функцию с аргументом в качестве одного параметра? Это означало бы, что функция, которую вы передаете с параметрами, вернет только один результат, который уже известен за пределами func2 (поскольку func2 вызовет func1 с этим уже вне определенного набора параметров). Итак, почему бы просто не передать результат func1-вызова func2?

+0

func2 является библиотечной функцией и может принимать только значения void *. поэтому я могу либо передать адрес функции, либо структуру ... Я просто хотел попробовать это. – Gaurav

+0

В этом случае (поскольку вы не можете передавать функциональные параметры для func1 в func2), я бы либо вызвал func1 со своими параметрами вне func2, и просто передал результат. Если вы не можете получить результат в проходимом формате, вы можете сделать func3, вызвав func1 с его параметрами и передать указатель функции func3 на func2. Таким образом, у вас есть указатель на функцию без параметров. – JokoFacile

+0

да понял, что так или я пропускаю два вара или структуру ... как @Kludas сделал в своем решении – Gaurav

2

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

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

int func1(char * pc) 
{ 
    int i; 
    /* assigne somehting to "i" and use "pc" */ 
    return i; 
} 

int func1_abcd(void) 
{ 
    return func1("abcd") 
} 

int func1_xyz(void) 
{ 
    return func1("xyz") 
} 

typedef int (*pfunc1_wrapper_t)(void); 

int func2(pfunc1_wrapper_t pfunc1_wrapper) 
{ 
    return pfunc1_wrapper(); 
} 

int main(int argc, char ** argv) 
{ 
    pfunc1_wrapper_t pfunc1_wrapper = NULL; 
    int i = 0; 

    pfunc1_wrapper = func1_abcd; 
    i = func2(pfunc1_wrapper); 

    pfunc1_wrapper = func1_xyz; 
    i = func2(pfunc1_wrapper); 

    ... 

    return 0; 
} 
Смежные вопросы