Cum transmiteți o funcție ca parametru în C?

Vreau să creez o funcție care să efectueze o funcție transmisă de parametru pe un set de date. Cum transmiteți o funcție ca parametru în C?

0
fr hi bn
@MooingDuck Nu sunt de acord cu sugestia dvs., iar sugestia dvs. nu are raționament pentru a susține concluzia. Eu personal prefer niciodată folosind typedef pe indicatorii funcției, și cred că face codul mai clar și mai ușor de citit.
adăugat autor andrewrk, sursa
adăugat autor AminM, sursa
Dacă utilizați funcții/matrice ca variabile, ÎNTOTDEAUNA folosiți typedef .
adăugat autor Mooing Duck, sursa
@andrewrk: Preferați void funcA (void (* funcB) (int)) și void (* funcA() ; void funcA (funcB) și funcB funcA() ? Nu văd partea superioară.
adăugat autor Mooing Duck, sursa
Oh, tocmai am observat că comentariul spune "matricele ca variabile". Da, asta e cuvinte greșite. Am vrut să spun că variabilele arătător array.
adăugat autor Mooing Duck, sursa
Numele funcției ar trebui să fie un ponton al funcției. Cei mai mulți oameni care învață C acoperă qsort mai devreme sau mai târziu, care face exact asta?
adăugat autor mckenzm, sursa

5 răspunsuri

Trebuie să introduceți un pointer de funcții . Sintaxa este puțin greoaie, dar este foarte puternică odată ce te familiarizează cu ea.

0
adăugat

Această întrebare are deja răspunsul pentru definirea indicatoarelor de funcții, cu toate acestea ele pot deveni foarte dezordonate, mai ales dacă le veți transmite în jurul cererii dvs. Pentru a evita această neplăcere aș recomanda să introduceți pointerul funcției în ceva mai ușor de citit. De exemplu.

typedef void (*functiontype)();

Declară o funcție care revine nule și nu ia argumente. Pentru a crea un pointer de funcții la acest tip puteți face acum:

void dosomething() { }

functiontype func = &dosomething;
func();

Pentru o funcție care returnează un int și ia un caracter ar face

typedef int (*functiontype2)(char);

și să o folosească

int dosomethingwithchar(char a) { return 1; }

functiontype2 func2 = &dosomethingwithchar
int result = func2('a');

Există biblioteci care vă pot ajuta să rotiți indicatorii funcției în tipuri ușor de citit. Biblioteca funcția de îmbunătățire este minunată și merită bine efort!

boost::function functiontype2;

este mult mai plăcut decât cele de mai sus.

0
adăugat
Dacă doriți să "transformați un pointer al funcției într-un tip", nu aveți nevoie de biblioteca de stimulare. Doar utilizați typedef ; este mai simplu și nu necesită biblioteci suplimentare.
adăugat autor wizzwizz4, sursa

Treceți adresa unei funcții ca parametru la o altă funcție după cum se arată mai jos

#include 

void print();
void execute(void());

int main()
{
    execute(print);//sends address of print
    return 0;
}

void print()
{
    printf("Hello!");
}

void execute(void f())//receive address of print
{
    f();
}

Also we can pass function as parameter using function pointer

#include 

void print();
void execute(void (*f)());

int main()
{
    execute(&print);//sends address of print
    return 0;
}

void print()
{
    printf("Hello!");
}

void execute(void (*f)())//receive address of print
{
    f();
}
0
adăugat

De la C ++ 11 puteți folosi biblioteca funcțională pentru a face acest lucru într-o succint și generic. Sintaxa este, de exemplu,

std::function

unde bool este tipul de retur al unei funcții cu un argument, al cărui prim argument este de tip int .

Am inclus un exemplu de program de mai jos:

// g++ test.cpp --std=c++11
#include 

double Combiner(double a, double b, std::function func){
  return func(a,b);
}

double Add(double a, double b){
  return a+b;
}

double Mult(double a, double b){
  return a*b;
}

int main(){
  Combiner(12,13,Add);
  Combiner(12,13,Mult);
}

Uneori, totuși, este mai convenabil să folosiți o funcție de șablon:

// g++ test.cpp --std=c++11

template
double Combiner(double a, double b, T func){
  return func(a,b);
}

double Add(double a, double b){
  return a+b;
}

double Mult(double a, double b){
  return a*b;
}

int main(){
  Combiner(12,13,Add);
  Combiner(12,13,Mult);
}
0
adăugat
Întrebarea este despre C; C ++ nu se aplică aici.
adăugat autor Super Cat, sursa
Poate că întrebarea pentru C ++ nu ar trebui să fie menționată aici pentru că această întrebare este pentru C.
adăugat autor Michael Fulton, sursa
Întrebarea pentru C ++ ( stackoverflow.com/questions/6339970/ & hellip; ) este menționată aici, deci cred că acest răspuns este în vigoare.
adăugat autor mr_T, sursa

Declarație

Un prototip pentru o funcție care are un parametru de funcție arată după cum urmează:

void func ( void (*f)(int) );

Aceasta indică faptul că parametrul f va fi un indicator al unei funcții care are un tip de returnare void și care are un singur parametru int . Următoarea funcție ( print ) este un exemplu de funcție care poate fi trecută ca parametru func , deoarece este tipul potrivit:

void print ( int x ) {
  printf("%d\n", x);
}

Funcție de apel

Când se apelează o funcție cu un parametru de funcție, valoarea trecută trebuie să fie un indicator al unei funcții. Utilizați numele funcției (fără paranteze) pentru aceasta:

func(print);

ar apela func , trecând funcția de imprimare la ea.

Funcția corpului

Ca și în cazul oricărui parametru, func poate utiliza acum numele parametrului în corpul funcției pentru a accesa valoarea parametrului. Să presupunem că func va aplica funcția pe care o transmite numerele 0-4. Luați în considerare, în primul rând, ceea ce ar arăta buclă de a apela imprimare direct:

for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
  print(ctr);
}

Deoarece declarația parametrului func spune că f este numele unui indicator pentru funcția dorită, reamintim mai întâi că dacă f este un pointer atunci * f este un lucru pe care f indică (de exemplu, funcția print în acest caz). Prin urmare, înlocuiți fiecare apariție a tipăririi în buclă de mai sus cu * f :

void func ( void (*f)(int) ) {
  for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
    (*f)(ctr);
  }
}

From http://math.hws.edu/bridgeman/courses/331/f05/handouts/c-c++-notes.html

0
adăugat
@ JonathonReinhart Da, a fost în ANSI C
adăugat autor M.M, sursa
@JonathonReinhart în acest caz, aș tasta tipul de funcție.
adăugat autor M.M, sursa
@ JonathonReinhart bine reperat; trebuie remarcat în mod explicit că pointer typedefs obfuscate codul și, prin urmare, nu ar trebui să fie utilizat.
adăugat autor M.M, sursa
@ JonathonReinhart, care ar fi avantajele cu 'typedef' apprach? Această versiune pare mult mai curată și, totuși, nu are prea multe declarații. destul de mult starter aici.
adăugat autor Abhinav Gauniyal, sursa
@ M.M Este standardul C? Am mai jucat cu el, dar am crezut că a fost o extensie GNU.
adăugat autor Jonathon Reinhart, sursa
Privind la ( stackoverflow.com/questions/4574985/…), singura diferență este includerea codului * când se declară un indicator al funcției, corect? Deoarece nu puteți defini o funcție de la o funcție typedef. Există o mulțime de informații despre indicatorii funcțiilor de tip testarea, dar nu și despre tipurile de funcții.
adăugat autor Jonathon Reinhart, sursa
@ M.M Dezacord. Luați în considerare un API bazat pe callback, în care apelurile de apel sunt înregistrate și stocate într-o structură de context. Dacă utilizați un typedef pentru indicatorii funcției și doriți să vă schimbați prototipul, trebuie doar să schimbați indicatorul de funcții typedef, în loc să îl schimbați peste tot. Acest lucru, provenind de la un tip care nu este de acord cu over-typedefing (și anume pe structuri).
adăugat autor Jonathon Reinhart, sursa
Într-adevăr? Răspunsul evaluat de cel mai înalt nivel nu face o singură referire la utilizarea unui cod typedef pentru indicatorii funcției? Ne pare rău, trebuie să votăm în jos.
adăugat autor Jonathon Reinhart, sursa
Există ceva împotriva trimiterilor la funcții, astfel încât să nu avem o sintaxă oarecum complexă? Ultima dată când am verificat, acestea au funcționat perfect ..
adăugat autor lorro, sursa
În exemplele din primul și ultimul cod, * nu este obligatoriu. Atât definiția parametrului funcției, cât și apelul funcției f pot lua f la fel ca și fără *. S-ar putea să fie o idee bună să o faceți așa cum faceți, pentru a face evident că parametrul f este un indicator al funcției. Dar doare destul de des lenea.
adăugat autor Gauthier, sursa
Consultați [c99, 6.9.1§14] pentru exemple. Ambele sunt corecte, desigur, am vrut doar să menționez alternativa.
adăugat autor Gauthier, sursa
Ce se întâmplă dacă doriți să treceți un pointer de funcție care returnează un pointer ca argument. Am încercat acest lucru:
adăugat autor azmath, sursa