Beste Antwort
Da wir wissen, dass auf die in einer Datei definierten Funktionen in einer anderen Datei zugegriffen werden kann. Wenn wir einschränken möchten, dass Funktionen nicht in einer anderen Datei aufgerufen werden dürfen, können wir sie statisch machen.
Daher sind statische Funktionen diejenigen Funktionen, die aufgerufen werden können in derselben Datei, in der sie definieren.
Wir können eine statische Funktion mithilfe der folgenden Syntax definieren:
static return\_type function\_name(arguments)
{
function\_body;
}
Hier ist eine Funktion zum Ermitteln der Quadratwurzel einer bestimmten Zahl
static long int getSquare(int num){
return (num*num);
}
Programm zur Demonstration eines Beispiels für statische Funktionen in C-Sprache
#include
//static function definition
static long int getSquare(int num){
return (num*num);
}
int main()
{
int num;
printf("Enter an integer number: ");
scanf("\%d",&num);
printf("Square of \%d is \%ld.\n",num,getSquare(num));
return 0;
}
Ausgabe
Enter an integer number: 36
Square of 36 is 1296.
Warum sind die statischen Funktionen erforderlich?
Da Funktionen verwendet werden, um den Code wiederzuverwenden (dh Auf den von Ihnen geschriebenen Code kann in einer anderen Datei zugegriffen werden, indem Sie sie in die Funktionen ) einfügen. Wenn Sie jedoch einige Funktionen, die in einer anderen Datei nicht gemeinsam genutzt (aufgerufen) werden dürfen .
statische Funktionen sind auch hilfreich, um das Problem mit dem Deklarationskonflikt zu lösen – Wenn zwei Funktionen in zwei verschiedenen Dateien mit demselben Namen vorhanden sind, ist die Funktionsdeklaration ein Konflikt. Wir können sie statisch machen.
Um diese Art von Anforderung zu erfüllen, können wir sie statisch machen .
Antwort
Kurze Antwort: Dies bedeutet, dass der Funktionsname nur in der aktuell kompilierten Datei sichtbar und aufrufbar ist. Andere Dateien, die separat kompiliert wurden, sehen den Funktionsnamen nicht und können ihn nicht aufrufen. Anschließend können sie ihre eigenen statischen Funktionen mit demselben Namen haben. Dadurch werden Namenskonflikte in Dateieinschlüssen und beim Verknüpfen von Objektdateien und Binärbibliotheken vermieden.
Es gibt 4 verschiedene Speicherklassen für die Speicherung in C.
- auto (automatisch) Dies ist „normal“ (Standard) und verwendet das Schlüsselwort auto , ist es aber Normalerweise nicht angegeben, da dies das Standardregister ist.
- Das Register ist ein „Hinweis“ für den Compiler, dass es den zum Speichern des Codes erstellten Code optimieren kann Wert in einem CPU-Register für eine schnellere Verarbeitung. Der Compiler wird versuchen, dies zu tun, aber wenn nicht, ist es dasselbe wie regulär.
- extern external bedeutet, dass dies der Fall ist Nur eine globale Variable mit diesem Namen und alle Dateien, die sie als extern deklarieren, verwenden diesen Speicher. Eine Datei deklariert sie global als reguläre Variable, wo sie bei der Kompilierung zugewiesen wird.
- statischer Speicherspezifizierer in C-Quelldateien bedeutet ein paar verschiedene Dinge.
- Der Name und der Speicher werden nicht in andere Dateien exportiert, die gleichzeitig kompiliert werden. Auf diese Weise kann jede Datei identische Namen haben, die nicht in Konflikt geraten.
- Der für die Variable erstellte Speicher wird im statischen Speicherbereich erstellt und beim Programmstart auf 0 oder mit einem expliziten Wert initialisiert.
- Die Initialisierung einer statischen Variablen wird nur einmal durchgeführt. (zur Kompilierungszeit). Danach werden die zugewiesenen Werte für die Lebensdauer des Programms oder bis zur Änderung durch eine Zuweisung beibehalten.
- Der in Funktionen deklarierte statische Speicher hat einen Funktionsumfang, aber eine statische Zuordnung. Dies bedeutet, dass der Speicher für die Lebensdauer des Programms permanent ist und nicht erstellt wird, wenn der Funktionsstapelrahmen für den Funktionsaufruf zugewiesen wird. Es behält seinen Wert durch mehrere Funktionsaufrufe. Der Speicher bleibt bestehen, obwohl der Codeblock nach seiner Rückkehr vom Stapel wiederhergestellt wird.
int accumulate( unsigned int x)
{
static unsigned int acc = 0;
acc = acc + x;
return acc;
}
- Das Obige würde zurückkehren eine laufende Abrechnung seiner Eingabe, da die var acc bei jedem Aufruf den Wert behalten würde. acc wird beim Laden des Programms auf 0 initialisiert.
- statische Variablen haben Adressen im RAM, und Sie können sie als Referenz oder Wert in Funktionen senden.
- Variablen mit kleinerem Gültigkeitsbereich (innerhalb von Funktionen definiert), die denselben Namen wie eine statische Variable außerhalb dieses Bereichs haben, beschatten die statische Variable wie alle anderen.
- statische Variablen möglicherweise nicht In externe Dateien exportiert, sodass Werte über Kompilierungsdomänen hinweg verloren gehen können, wenn sie nicht explizit als Parameter nach Wert gesendet werden. (gotcha!)
- Wie 4 können auch andere Dateien nicht wie extern zugreifen automatische (normale) Variablen. Es wird nicht funktionieren, Sie werden fehlerhafte Programme bekommen, die abstürzen, und der Compiler wird möglicherweise getäuscht und verfehlt.
- Statische Variablen können bei ihrer Deklaration initialisiert werden, aber der Initialisierungswert muss ein konstanter Ausdruck sein, der auswertbar ist zur Kompilierungszeit kein Wert, der zur Kompilierungszeit nicht berechenbar ist. Sie können eine statische Variable nicht mit einem unbekannten Wert wie einer Parametervariablen oder dem Ergebnis eines Funktionsaufrufs initialisieren, der zur Kompilierungszeit nicht aufgetreten ist.
int accumulate( unsigned int x)
{
/* ERROR x is not a compile-time constant. */
static unsigned int acc = x;
static unsigned int acc = 0; /* OK */
acc = acc + x;
return acc;
}
Statische Funktionen
- Eine statische Funktion in C hat den Dateibereich . Eine statische Funktion kann nicht sein wird von einer anderen Datei in derselben Übersetzungseinheit aufgerufen. Eine Übersetzungseinheit ist der gesamte Quellcode, der nach der Vorverarbeitung in einen Compiler eingegeben wird, um gleichzeitig kompiliert zu werden. Statische Funktionen können nicht auf statische Variablen zugreifen oder statische Funktionen aus anderen Dateien aufrufen. Wenn Sie also den Zugriff auf eine Funktion auf die aktuelle Datei beschränken möchten, können Sie sie statisch machen. In dieser Datei kann nur eine Funktion mit diesem Namen vorhanden sein (die auch für reguläre Funktionen gilt). Daher werden häufig Dienstprogrammfunktionen in Header-Dateien abgelegt, um in mehreren Kompilierungen enthalten zu sein, und der Header wird mit Vorprozessor-Befehlen geschützt, um dies nicht zu tun mehrmals in einer Zusammenstellungseinheit enthalten sein. Alle Standard-C-Bibliotheksheader sind voll von globalen Funktionen, und diese werden so geschützt, dass sie nur einmal in einer Kompilierung kompiliert werden und globale Funktionen sind. Keine statischen Funktionen. Statische Funktionen sollen „interne Verknüpfung“ haben, was bedeutet, dass sie in anderen kompilierten Modulen nicht angezeigt werden können, selbst wenn sie mit demselben endgültigen Programm oder derselben Bibliothek verknüpft sind. Wenn eine Funktion nicht statisch ist, ist diese Funktion in C eine globale Funktion und wird im gesamten Programm global verfügbar sein. Dies bedeutet, dass Sie im gesamten Programm nur eine Funktion namens print haben können. Um dies zu umgehen, machen Sie Ihre Funktionen und Variablen statisch, und es kommt nicht zu Namenskonflikten.
- Funktionen sind global und standardmäßig extern , außer in der Datei, in der sie definiert sind. Sie sehen also nicht das Wort extern wird in der C-Quelle mit Funktionen verwendet, da es implizit bereits vorhanden ist. Aus diesem Grund können Sie normale Funktionen aus jeder Datei in der Übersetzungseinheit aufrufen. Sie sollen externe Verknüpfung haben, was bedeutet, dass sie nach dem Verknüpfen für jede Datei im Modul oder jedes andere Modul im verknüpften Programm sichtbar und aufrufbar sind.
- Eine Funktionsprototypdeklaration ist eine „vorläufige Definition“, die implizit extern ist. Code nach dem ersten Scannen der Prototypdeklaration kann die Funktion aufrufen, solange die vollständige Definition im endgültigen Code vorhanden ist. Das bedeutet, dass tatsächlich eine „tatsächliche Definition“ vorhanden sein muss, sonst schlägt die -Verbindungsphase fehl. Aus diesem Grund enthalten Header in C normalerweise nicht den Quellcode für die Funktionen, sie werden nicht zum Kompilieren benötigt, sondern befinden sich in der Verknüpfungsphase.
- Eine statische Funktionsprototypdeklaration ist eine „vorläufige Definition“, die explizit nicht extern ist. Die vollständige Definition muss in der aktuellen Übersetzungseinheit vorhanden sein (gleichzeitig kompiliert). Andernfalls schlägt die Kompilierung fehl. Moderne C-Compiler synthetisieren den Prototyp aus der Definition, solange er früher als ein tatsächlicher Funktionsaufruf auftritt. Sogenannte „Forward-Deklarationen“ ermöglichen die Verwendung vorläufiger Definitionen mit der tatsächlichen Definition später und haben verschiedene Verwendungsmöglichkeiten in Datenstrukturen und bei der Organisation von Bibliotheken.
- Die erste Definition einer Dateisignatur wird für das gesamte Programm verwendet, einschließlich statisch oder extern. Sobald eine Funktion zum ersten Mal definiert wurde und zunächst als statisch deklariert wurde, ist sie immer statisch, auch wenn sie später ohne das Schlüsselwort static neu definiert wird. Wenn es ursprünglich als extern deklariert ist (Standard), kann es nicht als statisch neu definiert werden.
static void f(int); /* Function is always static */
...
void f(int x) { ….} /* static , not exported, no error */
void f(int); /* Function is always global */
...
static void f(int x) { ….} /*ERROR NOT STATIC */
clang: "error: static declaration of "f" follows non-static declaration"
- Im Blockbereich definierte Funktionen können nicht als statisch deklariert werden. Außerhalb eines Blocks können nur statische Funktionsdefinitionen für den Dateibereich erstellt werden. Dies ist aus logischer Sicht sinnvoll, da der Dateibereich nicht kleiner als die gesamte Datei sein kann. Definieren Sie daher eine statische Funktion oder zumindest den Prototyp sehr früh in der Datei.
- Statisch bezieht sich auf die Funktion, nicht auf den Rückgabetyp . Sie können das statische Schlüsselwort nach dem Rückgabetyp platzieren, wenn Sie dies wünschen, aber wenn Sie dies tun, sind Sie komisch und Sie werden die Leute verwirren. Der Rückgabewert ist nicht statisch, die Funktion ist.
- Eine statische Funktionsdefinition überschreibt a nicht global definiert davor in derselben Datei oder in einer enthaltenen Datei. Wenn bereits eine Funktion mit diesem Namen definiert ist, können Sie sie möglicherweise nicht mit einer statischen Funktion oder einer Funktion mit demselben Namen neu definieren.
C benennt Funktionen und Variablen nicht intern um, wie dies in C ++ der Fall ist, und unterstützt daher keine Funktionsüberladung. C ++ „entstellt“ die Funktionsnamen mit einem codierten Namen, der mehrere zusätzliche Arten von Daten angibt, z. B. ob sie Teil einer Klasse sind oder welche Parameter sie haben usw. Wenn also in C das statische Schlüsselwort fehlt, haben Sie möglicherweise nur eine Funktion von Jeder eindeutige Name in einem Programm, unabhängig davon, wie viele Dateien oder Bibliotheken er enthält.
Was tun Sie also, wenn Sie Ihre Funktion für eine bereits vorhandene Funktion ändern möchten?
Was Smart C-Codierer tun, ist, sich einen anderen Namen für ihre Funktion auszudenken. Es gibt jedoch eine Möglichkeit, den Compiler zu „täuschen“, indem der Quelltext präventiv mit dem Präprozessor geändert wird.
Beispiel: Ein Idiot hat eine int sort( char** Array)
-Funktion in seine Bibliothek geschrieben und es global gemacht, und es ist fehlerhaft und macht nicht genau das, was Sie wollen, weil es Zahlen nach Buchstaben oder etwas kommen lässt und die T-Wörter aus irgendeinem Grund immer an erster Stelle stehen.
Sie möchten Verwenden Sie die Bibliothek, müssen Sie jedoch die Funktion korrigieren, und Sie haben nur die Header und die kompilierte Bibliothek, nicht den Quellcode.
OK>, sodass ein „spezieller“ Header erstellt wird, der die gesamte Instanz von „ersetzt. sort “mit„ bad\_sort “im Header, importiert dann Ihren Code und ersetzt alle Instanzen von„ sort “durch„ good\_sort “. „Good\_sort“ ist vollständig in good\_sort.h definiert, jedoch als statisch markiert, sodass es nur in der Datei bekannt ist, in der es enthalten ist.
/* good\_sort.h */
#ifndef \_GOOD\_SORT\_H
#define \_GOOD\_SORT\_H
static int good\_sort(char** Array)
{
... //code here
return numsorted;
}
#endif
Eine Definitionsschutzklammer wird hinzugefügt, um sicherzustellen, dass sie nicht zweimal enthalten ist.
/*-----------------------------------*/
/* program.c */
#include "Trumpsort.h" /* The buggy library header */
...
#ifdef sort
#undef sort /* undefine the sort function name as reserved */
#define sort bad\_sort /* replace the name */
#include "good\_sort.h" /* your fixed version */
#endif
#define sort good\_sort /* replace the name in this file */
/* rest of file */
Ein bisschen wie ein Crapfest, aber die Idee ist, Ihre Funktion aufzurufen anstelle des schlechten von Renam Geben Sie es auf „good\_sort“ und nennen Sie es stattdessen. (aber nur in dieser Datei – statisch ).