678 Stimmen

Was ist eine "statische" Funktion in C?

Die Frage bezog sich auf einfache c Funktionen, nicht c++ static Methoden, wie in den Kommentaren präzisiert.

Ich verstehe, was ein static Variable ist, aber was ist eine static Funktion?

Und warum ist es so, dass, wenn ich eine Funktion deklariere, sagen wir void print_matrix in, sagen wir mal a.c (OHNE a.h ) und umfassen "a.c" - Ich bekomme "print_matrix@@....) already defined in a.obj" , ABER wenn ich es deklariere als static void print_matrix dann kompiliert er?

UPDATE Nur um das klarzustellen - ich weiß, dass auch .c ist schlecht, wie viele von Ihnen betont haben. Ich tue es nur, um vorübergehend Platz zu schaffen in main.c bis ich eine bessere Vorstellung davon habe, wie ich all diese Funktionen zu richtigen .h y .c Dateien. Nur eine vorübergehende, schnelle Lösung.

16voto

Douglas Leeder Punkte 50423

Erstens: Es ist generell eine schlechte Idee, eine .cpp Datei in einer anderen Datei - das führt zu Problemen wie diesem :-) Der normale Weg ist, separate Kompiliereinheiten zu erstellen und eine Header-Datei für die eingeschlossene Datei hinzuzufügen.

Zweitens:

C++ hat hier eine verwirrende Terminologie - ich wusste es nicht, bis ich in den Kommentaren darauf hingewiesen wurde.

a) static functions - von C geerbt, und worüber Sie hier sprechen. Außerhalb jeder Klasse. Eine statische Funktion bedeutet, dass es außerhalb der aktuellen Kompiliereinheit nicht sichtbar ist - in Ihrem Fall hat a.obj also eine Kopie und Ihr anderer Code eine unabhängige Kopie. (Aufblasen der endgültigen ausführbaren Datei mit mehreren Kopien des Codes).

b) static member function - was in der Objektorientierung als statische Methode . Befindet sich innerhalb einer Klasse. Der Aufruf erfolgt über die Klasse und nicht über eine Objektinstanz.

Diese beiden unterschiedlichen statischen Funktionsdefinitionen sind völlig verschieden. Seien Sie vorsichtig - hier gibt es Drachen.

0 Stimmen

Nun, ich tue es nur, um vorübergehend etwas Platz in main.cpp freizumachen, bis ich mich entscheide, wie ich die Datei in Bibliotheken zusammen mit richtigen .hpp's organisieren kann. Gibt es eine bessere Idee, wie man dies tun?

2 Stimmen

Die korrekte Terminologie in C++ ist member function, nicht method. Es gibt keine "Methoden" in der C++-Juristensprache. Methode ist ein allgemeiner OO-Begriff. C++ implementiert sie über Mitgliedsfunktionen.

16voto

" Was ist ein " static "Funktion in C? "

Fangen wir ganz am Anfang an.

Das Ganze basiert auf einer sogenannten "Verknüpfung":

" Ein Bezeichner, der in verschiedenen Bereichen oder mehr als einmal im selben Bereich deklariert ist, kann durch einen Prozess, der als Verknüpfung bezeichnet wird, dazu gebracht werden, auf dasselbe Objekt oder dieselbe Funktion zu verweisen. 29) Es gibt drei Arten von Verknüpfungen: externe, interne und keine. "

Quelle: C18, 6.2.2/1


"In der Menge der Übersetzungseinheiten und Bibliotheken, die ein ganzes Programm ausmachen, wird jede Deklaration eines bestimmten Bezeichners mit Außenanbindung bezeichnet das gleiche Objekt oder die gleiche Funktion. Innerhalb einer Übersetzungseinheit wird jede Deklaration eines Bezeichners mit interne Verknüpfung bezeichnet das gleiche Objekt oder die gleiche Funktion. Jede Deklaration eines Identifikators ohne Verknüpfung bezeichnet eine eindeutige Entität".

Quelle: C18, 6.2.2/2


Wird eine Funktion ohne Angabe einer Speicherklasse definiert, hat die Funktion extern al-Verknüpfung standardmäßig:

"Wenn die Deklaration eines Bezeichners für eine Funktion keinen Speicherklassenspezifizierer hat, wird seine Verknüpfung genau so bestimmt, als ob er mit dem Speicherklassenspezifizierer deklariert wäre extern ."

Quelle: C18, 6.2.2/5

Das bedeutet, dass - wenn Ihr Programm aus mehreren Übersetzungseinheiten/Quelldateien besteht ( .c o .cpp ) - die Funktion ist sichtbar in alle Übersetzungseinheiten/Quelldateien, die Ihr Programm hat.

Dies kann in einigen Fällen ein Problem darstellen. Was ist, wenn Sie z.B. zwei verschiedene Funktionen (Definitionen), aber mit demselben Funktionsnamen in zwei verschiedenen Kontexten (eigentlich dem Dateikontext) verwenden wollen.

In C und C++, die static Speicherklassen-Qualifizierer, der auf eine Funktion im Dateisystem angewendet wird (nicht auf eine statische Mitgliedsfunktion einer Klasse in C++ oder einer Funktion innerhalb eines anderen Blocks) kommt nun zu Hilfe und bedeutet, dass die jeweilige Funktion nur innerhalb der Übersetzungseinheit/Quelldatei, in der sie definiert wurde, sichtbar ist und nicht in den anderen TLUs/Dateien.

"Wenn die Deklaration eines Dateibereichskennzeichens für ein Objekt oder eine Funktion den Spezifizierer für die Speicherklasse enthält statisch hat der Identifikator eine interne Verknüpfung. 30)"


  1. Eine Funktionsdeklaration kann den Speicherklassenspezifizierer static nur dann enthalten, wenn sie sich auf Dateiebene befindet; siehe 6.7.1.

Quelle: C18, 6.2.2/3


Daher ist A static Funktion ist nur sinnvoll, wennf:

  1. Ihr Programm besteht aus mehreren Übersetzungseinheiten/Quelldateien ( .c o .cpp ).

und

  1. Sie möchten den Geltungsbereich einer Funktion auf die Datei beschränken, in der die betreffende Funktion definiert ist.

Falls nicht ambos dieser Anforderungen übereinstimmen, brauchen Sie sich nicht den Kopf darüber zu zerbrechen, wie Sie eine Funktion als static .


Randnotizen:

  • Wie bereits erwähnt, ist A static Funktion hat absolut Keinerlei Unterschied zwischen C und C++, da dies ein Merkmal ist, das C++ von C geerbt hat.

Es spielt keine Rolle, dass in der C++-Gemeinschaft eine herzzerreißende Debatte über die Abwertung von Funktionen geführt wird, die als static im Vergleich zur Verwendung von unbenannte Namespaces stattdessen durch einen falsch platzierten Absatz im C++03-Standard initiiert, der die Verwendung statischer Funktionen für veraltet erklärte und bald darauf vom Ausschuss selbst überarbeitet und in C++11 entfernt wurde.

Dies war Gegenstand verschiedener SO-Fragen:

Unbenannte/anonyme Namensräume vs. statische Funktionen

Überlegenheit des unbenannten Namensraums gegenüber dem statischen?

Warum ist ein unbenannter Namespace eine "bessere" Alternative zu statisch?

Ausmusterung des Schlüsselworts static... nicht mehr?

In der Tat ist sie laut C++-Standard noch nicht veraltet. Daher ist die Verwendung von static Funktionen ist immer noch legal. Auch wenn unbenannte Namespaces Vorteile haben, ist die Diskussion über die Verwendung oder Nichtverwendung statischer Funktionen in C++ der eigenen Meinung unterworfen und damit für diese Website nicht geeignet.

8voto

Parrots Punkte 25928

Eine statische Funktion ist eine Funktion, die mit der Klasse selbst aufgerufen werden kann, im Gegensatz zu einer Instanz der Klasse.

Eine nicht-statische Variante wäre zum Beispiel:

Person* tom = new Person();
tom->setName("Tom");

Diese Methode wirkt auf eine Instanz der Klasse, nicht auf die Klasse selbst. Sie können jedoch eine statische Methode haben, die auch ohne eine Instanz funktioniert. Dies wird manchmal im Factory-Muster verwendet:

Person* tom = Person::createNewPerson();

3 Stimmen

Ich habe den Eindruck, dass Sie von einer statischen "Methode" und nicht von einer "Funktion" sprechen.

0 Stimmen

Ich nahm an, dass Sie sich auf statische Funktionen innerhalb einer Klasse beziehen.

0 Stimmen

Wenn ich gewusst hätte, dass "Methoden" in C++ "Methodenfunktionen" genannt werden, wäre mir das klarer gewesen. Nun, jetzt weiß ich es :) Trotzdem vielen Dank

7voto

dirkgently Punkte 104289

Kleines Manko: statische Funktionen sind für eine Übersetzungseinheit sichtbar, was in den meisten praktischen Fällen die Datei ist, in der die Funktion definiert ist. Der Fehler, den Sie erhalten, wird gemeinhin als Verletzung der One Definition Rule bezeichnet.

In der Norm steht wahrscheinlich so etwas wie:

"Jedes Programm muss genau eine Definition jeder Nicht-Inline-Funktion oder jedes Objekts enthalten Funktion oder eines Objekts enthalten, das in diesem Programm verwendet wird; keine Diagnose erforderlich."

Das ist die C-Art, statische Funktionen zu betrachten. In C++ ist dies jedoch veraltet.

In C++ können Sie außerdem Mitgliedsfunktionen als statisch deklarieren. Dabei handelt es sich meist um Metafunktionen, d.h. sie beschreiben/verändern nicht das Verhalten/den Zustand eines bestimmten Objekts, sondern wirken auf die gesamte Klasse selbst. Das bedeutet auch, dass Sie kein Objekt erstellen müssen, um eine statische Mitgliedsfunktion aufzurufen. Das bedeutet auch, dass Sie nur innerhalb einer solchen Funktion Zugriff auf statische Mitgliedsvariablen erhalten.

Ich würde dem Beispiel von Parrot das Singleton-Muster hinzufügen, das auf dieser Art von statischer Mitgliedsfunktion basiert, um ein einzelnes Objekt während der gesamten Lebensdauer eines Programms zu erhalten/zu verwenden.

7voto

user2410022 Punkte 101

Die Antwort auf die Frage nach der statischen Funktion hängt von der jeweiligen Sprache ab:

1) In Sprachen ohne OOPS wie C bedeutet es, dass die Funktion nur innerhalb der Datei zugänglich ist, in der sie definiert ist.

2) In OOPS-Sprachen wie C++ bedeutet dies, dass die Funktion direkt in der Klasse aufgerufen werden kann, ohne dass eine Instanz der Klasse erstellt wird.

0 Stimmen

Das ist nicht wahr. Die Erklärung in Ihrem zweiten Absatz bezieht sich auf " statische Mitgliedsfunktionen " einer Klasse, nicht " statische Funktionen ". In C++ ist eine Funktion, die mit static hat auch file-scope, wie es in C ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X