Zeiger auf Funktionen





ein Funktionszeiger, с++, Programmieren für Anfänger, c++c ++

Es wurde beobachtet,, daß die Zeiger können auf eine Vielzahl von Arten von Objekten in der Programmsprache C ++ Punkt. genauer, für alle und auf allen Arten von Objekten, Daten in dem Programm.

Jedoch die gleichen Objekte, wie konventionelle Datenobjekte, sind Funktionen im Programm. Daher entsteht der Wunsch, zu versuchen einen Funktionszeiger zu definieren und verwenden. Erstellen Sie dieses einfache Programm (ex1.cc):

Hier mit der Funktion Bereich() alles klar: es berechnet die Fläche eines Kreises mit dem Radius, wer zu ihr gewidmet, als Parameter. Aber später erklären wir einen variablen Zeiger auf eine Funktion:

Zum Zeitpunkt dieser Mitteilung, der Zeiger pFunc Es ist nichts mehr, als eine bestimmte Adresse in dem internen Computerdarstellung (4 Byte 32-Bit-Betriebssystem,, 8 Byte 64-Bit-Betriebssystem,). Dies ist genau die gleiche Art von internen, was hat, lassen Sie uns sagen, ein Zeiger auf eine ganzzahlige Variable int *. Jedoch hat dieser Index einen streng definierten Typ: ein Funktionszeiger, nimmt einen Parameter des Typs doppelt, und gibt einen Wert vom Typ doppelt. Aber auf welchen spezifischen Funktionszeiger Punkte, bei seiner Definition - ganz gleich,: der Indexwert ist nicht definiert.

Aber die nächste Zuweisungsoperator binden wir einen Funktionszeiger auf eine bestimmte Funktion Bereich(). Absolut richtig wäre es, die Zuordnung der Funktionszeiger Adressen aufnehmen: pFunc = &Bereich. Aber die C ++ Compiler ist intelligent genug,, dass verweist der Name der Funktion in der Zuweisungsanweisung interpretiert als seine Adresse. So Eintrag pFunc = Fläche auch absolut richtig. Von diesem Punkt können wir den Zeiger pFunc eine Funktion aufzurufen, auf die sie verweist. Dazu schreiben wir den Wert der Zeiger auf dem *pFunc (Betrieb * in diesem Zusammenhang wird sie aufgerufen Dereference Zeiger). Die Klammern um den dereferenzierte Wert pFunc Aufnahme (*pFunc)( r ) notwendig aus Gründen der Priorität der Maßnahmen hinsichtlich der Offenlegung. Die Ausführung dieses Beispiel:

ein Funktionszeiger, с++, Programmieren für Anfänger, c++c ++

Während die Verwendung von Funktionszeiger nichts grundlegend Neues in diesem Beispiel bringen,, abgesehen von einigen Syntax Feinheiten. Aber in diesem Beispiel wissen wir nur noch, wie zu definieren und Funktionszeiger verwenden. Und jetzt können wir auf die Frage bewegen, warum es notwendig ist, und wie wir es verwenden.

angenommen, für ein großes Projekt, bereiten wir eine Reihe von Tests, in den Prozess der Entwicklung und das Wachstum des Testprojekts durchgeführt (die so genannte Test-Entwicklungstechnologie, und sehr produktiv). Die Anzahl der rundenbasierten Test in dieser Situation wird weiter wachsen, da wir die Bereitschaft des Basis Projekt bewegen.

In dieser Situation können wir tun, so (ex2.cc):

Und das ist, was wir auf die Leistung haben,:

ein Funktionszeiger, с++, Programmieren für Anfänger, c++c ++

In dieser Auflistung Tests[ ] – Das Feld Funktionszeiger ohne Parameter und ohne Rückgabewert. Schöne Lösung, Oder? Wir können nicht zögern, neue Funktionen von festen Test verursacht hinzufügen, und alle von ihnen werden in der Reihenfolge aufgerufen werden, wenn die Durchführung.

Wir können sogar noch weiter gehen: Wenn die Funktion einen Zeiger auf eine Funktion, in einem Expressions, Sie können einen Funktionszeiger als Parameter an eine andere übergeben, umarmen Funktion, und dieser wird in Ihrem Körper Funktion ausführen Parameter übergeben, nicht zu wissen, welche Maßnahmen zur gleichen Zeit durchgeführt wird,.

Zur Veranschaulichung, was gesagt wurde das Programm erstellt die primitivste Rechner, Ausführen arithmetische Operationen mit Integer-Operanden (ex3.cc):

Es führt die eigentliche Berechnungsfunktion berechnen(). Aber sie "wissen" nichts über die durchgeführten Aktionen und alle arithmetischen Operationen: Sie gilt für die zweite die erste seiner Parameter 6 Funktionen, die sie reichte bis zum 3. Parameter überführen.

Wer kennt sie nicht über typedef lesen Sie hier.

Dieser Code-Funktion strtod() – ein Standard-Feature von der C-Bibliothek (ANSI C, Standard POSIX), die extrahiert eine Dezimalzahl aus einem String, aus dem Standardeingabestrom erhalten. Im Rahmen unserer Diskussion ist interessant, weil, dass:

  • ein C ++ Programm kann den gesamten Satz der C-Bibliothek Anrufe verwenden;
  • C ++ Programm mit Runtime Shared-C-Bibliothek (.damit oder .dll), und in Abwesenheit eines Standard-C-Bibliothek, C ++ Programme sind unwirksam.

Aber zurück zum Rechner gezeigt (seine extrem aufgrund der Tatsache vereinfacht, dass wir mit den Problemen der Eingabe nicht umgehen, Format und verarbeiten nicht die Benutzereingabefehler – in realen Anwendungen, so können Sie nicht tun):

ein Funktionszeiger, с++, Programmieren für Anfänger, c++c ++

Aufmerksame Leser haben vielleicht bemerkt,, daß die Funktion berechnen() trotz aller Lust und konnte nicht der erforderlichen Rechenoperationen ausführen, Neben diesen Aktionen Funktion ausführen Summe(), dif(), mir() und div() beschrieben später Funktionen berechnen() im Funktionscode nicht sichtbar berechnen().

Auf diese Weise, Wir sahen uns an mehreren verschiedenen Gelegenheiten, wenn Funktionen in C ++ verwendet, als Datenelemente,. Sie können in Arrays kombiniert werden,, integriert als Felder Strukturen, oder als Argumente für andere Funktionen über. All diese Details und Möglichkeiten werden auf Kosten realisiert von Funktionszeiger (Obwohl sie aussehen können nicht als Zeiger Syntax Datensätze, Durch die intelligente C ++ Compiler, wer versteht den Kontext, das sollte Funktionen Adressen verwendet werden).

Wenn Sie etwas nicht verstehen auf dem Material oder den Code-Programme – Fragen in den Kommentaren.

Wir laden Sie ein, diese Lektion zu bewerten und Lehre Zeiger auf Objekte:

Newsletter neue Lektionen über die Programmierung:


Ich bin damit einverstanden, Nachrichten zu empfangen von purecodecpp.com auf meine E-Mail

Datum
Seite
Funktionszeiger in C ++
Wertung
5
Öl

Etwa Öl

praktische Erfahrungen über die Softwareentwicklung 40 Jahre. Lehrer Globale Logik internationales Softwareunternehmen. IBM Developer Works Permanent Autor von Publikationen. Wissenschaftliche Herausgeber der Computerliteratur-Verlag "Symbol-Plus", Sankt Petersburg.

14 Gedanken zu "Zeiger auf Funktionen

  1. Die zusätzliche Semikolon in der ersten Auflistung nach der Funktion Doppel Bereich(Doppel-R).

    “eine Adresse in dem internen Computerdarstellung”
    nur “eine Adresse”, was über diese Ergänzung “interne Darstellung”? – es fügt etwas auf den Punkt?

    “Neu in dieser primert”
    Typo.

    “Sie können einen Funktionszeiger als Parameter an eine andere übergeben, umarmen Funktion, ”
    Was ist die Funktion der Abdeckung? Was deckt?

    “Wer kennt sie nicht über die typedef - lesen Sie hier.”
    Link ausgezeichnet, aber es ist besser, darüber zu schreiben hier (es ist nicht viel).

    Das letzte Beispiel ist langweilig. IMHO auf Funktionszeiger muss sagen, über sie als Ganzes (wie in dem ersten Beispiel Artikel), Dann geben Sie ein Beispiel für eine Standardfunktion qsort, welches nimmt einen Zeiger auf eine Vergleichsfunktion. Und füllen Sie alle so etwas wie die Suchfunktion der Wurzel von bisection (Dies ist ein sehr einfaches Beispiel, und es genauso bequem passieren Funktion als Parameter an qsort).

    dh. der Benutzer muss sehen, dass es Hinweise auf Funktionen und befassen sich mit der Syntax (Im ersten Beispiel können Sie eine Beschreibung typedef hinzufügen). Dann sah ich,, es wirklich notwendig, (einmal in der Standard-Bibliothek verwendet). Nun, am Ende habe ich gelernt, die die gleichen Funktionen zu schreiben, nehmen andere Funktionszeiger, wie qsort.

    Nun, dies ist IMHO.

    1. > Nur "eine Adresse", auf die sich diese Ergänzung über "interne Repräsentation"? - Es fügt dem Punkt etwas?

      sicherlich fügt. da, in Bezug auf die Typisierung C, insbesondere C ++, syntaktisch “einfach Adressen” oder “einige Adressen” im allgemeinen gibt es keine (außer dass außer void *). Alle typisierte Zeiger (und die radikal unterscheiden sich voneinander). Und nur in der internen Maschinendarstellung eines Zeigers auf eine Funktion, eine Klassenmethode, lassen Sie uns sagen, и char * – bereits nicht unterscheiden, sie sind einfach nicht zu unterscheiden.

      1. > sicherlich fügt. da, in Bezug auf die Typisierung C, insbesondere C ++, syntaktisch "richtet sich einfach" oder "bestimmte Adressen" existiert nicht in allen (außer dass außer void *). Alle typisierte Zeiger … Und nur in der internen Maschinendarstellung eines Zeigers auf eine Funktion, eine Klassenmethode, lassen Sie uns sagen, und char * - schon nicht unterscheiden, sie sind einfach nicht zu unterscheiden.

        Adresse – auch in Afrika Adresse, egal, was Sie schreiben.

        #einschließen

        int main() {
        int val = 12345;
        int * intp = &val; // Geben Sie getippt Zeiger
        char * charp; // Ein weiterer typisierte Zeiger
        Crps = (verkohlen*)intp;

        std::cout << (int) *Crps << " " << *(int *)Crps << std::endl;
        }

        Hier wird gezeigt, dass ein int-Zeiger auf einen Zeiger auf char gegossen werden.
        Nun, dann können Sie an dieser Adresse Daten beziehen sich auf. Im ersten Fall, dereferenced Zeiger char *, so das erste Byte wird durch die Adresse des ausgewählten val. Im zweiten Fall wird char * in einen int * Zeiger gegossen und dereferenced, deshalb bereits alle genommen 4 Byte.

        Abschluss: 57 12345

        In jedem Fall können die Adressen in Cu bestimmungsgemäß funktioniert. Sie können Daten von einer beliebigen Adresse nehmen, lesen sie und schreiben sie etwas.

        Zum Beispiel könnten Sie am Ende dieses Programms anhängen, so etwas wie:
        *Crps = 56;

        std::cout << val << std::endl;

        das heißt, kann die Adresse mit val variable erste Byte ersetzt werden, die Arbeit mit ihm durch einen Zeiger auf char. Und Sie können nicht erste Byte, da in C ist alles gut mit der Adresse Arithmetik.

    2. > Das letzte Beispiel ist langweilig. IMHO auf Zeiger auf Funktionen hatte

      Aber bei dieser Gelegenheit: nicht “ich hatte” – а надо было взять и написать как свой текст, так и свои примеры. А не тоскливо рассказыватькак надо бы было бы”.

      1. Я и пишусвои тексты” :). К критике относись спокойней. Особенно при том, что уроки у тебя не получаются.

        >> Im Rahmen unserer Diskussion ist interessant, weil, dass: … C ++ Programm mit Runtime Shared-C-Bibliothek (.so или .dll), und in Abwesenheit eines Standard-C-Bibliothek, C ++ Programme sind unwirksam.

        Контекст наших обсуждений” – Das “указатели на функциии в нем нам вообще не интересно что там происходит с разделяемыми библиотеками.

        Тем более, что достоверность этой инфы может вызывать сомнения. Ты говоришь, что программы на С++ используютразделяемые библиотекиязыка Си. Терминразделяемая библиотекапредполагает, Bibliothek, die von mehreren Prozessen gleichzeitig verwendet wird,.

        duck, Die Bibliothek enthält in jeder ausführbaren Datei, sie nicht nifiga “gemeinsam genutzt”. Als sie teilten können für die Fehlersuche verwendet werden, aber mit der Möglichkeit, geht Releases –immer statisch. Andernfalls wird Ihr Programm nicht auf Ihrem Computer ausgeführt, если на нем не установлен компилятор той же версии, которую ты использовал при сборке программы и не будут прописаны соответствующие пути в системную переменную PATH. Ну или ты можешь, natürlich, laufen alle Programme, in C ++ von einem Verzeichnis geschrieben, in dem die Wurzel Ort die entsprechende DLL / .so, aber sonst niemand tut

      2. int powr(int op1, int op2)
        {
        int ret = 1;
        während (op2–) rechts * = op1;
        Rückkehr ret;
        }

        Diese Art der Konstruktion im ganzen Ausmaß. nein, что это дико неэффективно и может быть заменено использованием стандартной функции. Так оно еще и упадет при отрицательном значении op2.

        PS. Если писать статью про указатели на функции в С++, IMHO ist es notwendig, über std zu sagen,::funktional. Mit einer Ode an die Parteien angegeben, im Titel von C ++, nicht sein. Auf der anderen Seite – funtional fast jeder Sicht ist besser und bequemer. Zum Beispiel habe ich es kann durch Lambda übertragen (Ja, und andere aufrufbare Objekt), und durch einen Funktionszeiger – Ich kann nicht.

        Stattdessen schrieb der Autor einige falsche Informationen über “разделяемые библиотеки”.

      3. Ich bin vollkommen einverstanden mit dem folgenden Kommentator, уроки у тебя НЕ получаются.

  2. int main()
    {
    //…
    Rückkehr 0; // уже 4 года эта строчка лишняя. Если программа не завершилась аварийно, она *автоматически* вернет нулевой код ошибки. dh. ты тут выполняешь работу, которую и без тебя выполняет компилятор

    >> angenommen, für ein großes Projekt, bereiten wir eine Reihe von Tests, in den Prozess der Entwicklung und das Wachstum des Testprojekts durchgeführt (die so genannte Test-Entwicklungstechnologie, und sehr produktiv). … In dieser Situation können wir tun, so (ex2.cc):

    В этой ситуации ни в коем случае нельзя поступать так, как ты пишешь. Все твои старания дико далеки отразработки через тестирование”. Посмотри на google-Test-Framework или на Boost-Unit-Test-Framework или на 100500 Analoga.

    >>
    für (int i = 0; ich > Durch die intelligente C ++ Compiler, wer versteht den Kontext, das sollte Funktionen Adressen verwendet werden

    Sex Artikel, die Sie sprechen über “Smart-Compiler”. In Wirklichkeit ist es nichts besonders klug ist, nicht – Wenn der Name der Funktion ist keine Klammer, stopudovo es ist kein Funktionsaufruf, und einen Zeiger auf sie. Kein misrepresent Typ &Ich funktioniere überall, aber Ihr Artikel nicht gesehen hat.

  3. Wie schwierig es ist alles was ich mit diesen Zeigern haben:(
    Eine interessante Lektion und macht viel Denken. Ich denke, es ist gut,, aber einige der Höhepunkte für mich haben, blieb unklar. Vor allem mit einer Reihe von Funktionszeiger, und jeder kann mich durch typedef antworten.
    typedef int(*fint_t)(int, int);
    fint_t Das EPA[] =
    {
    summ, diff, viel, DIVD, bals, powr
    };
    Hier ist der Ansicht,, dass die Funktion des Zeigers verwandelt sich in eine Art von Daten?
    erklären Sie bitte…

    1. typedef führt keine eine neue Art von, es definiert nur kurz Synonym für lange Schreib “ein Zeiger auf eine Funktion, hier diese Art”.
      Eine bestimmt Feld diese Funktionszeiger (genannt Das EPA) und er sofort klar initialisiert. Aufgrund der Größe des Arrays Initialisierung erscheint, dann in seiner Beschreibung, können wir es nicht angeben ([]).

  4. verständlicherweise, что sizeof возвращающий длину в байтах, но вот условие:
    ich < Größe von(Tests) / Größe von(Tests[0])
    никак не могу понять. Поясните пжл.

    1. Что может быть проще?
      Так получается число элементов массива.
      Если массив 1-байтных элементов (verkohlen[]) содержит 10 Element, то это 10/1=10.
      Если массив 100-байтных элементов (Strukturen)содержит 10 Element, то это 1000/100=и опять же 10.

Hinterlasse eine Antwort

Platz Code in Tags: <pre class="lang:c ++ dekodieren:true ">DEIN CODE</Vor>