Wat is een statische functie in C?

Beste antwoord

Zoals we weten, kunnen de functies die in een bestand zijn gedefinieerd, in een ander bestand worden benaderd. Als we willen beperken dat functies niet in een ander bestand mogen worden aangeroepen, kunnen we ze statisch maken.

Daarom zijn statische functies die functies die kunnen worden opgeroepen in hetzelfde bestand waarin ze definiëren.

We kunnen een statische functie definiëren door de volgende syntaxis te gebruiken

static return\_type function\_name(arguments)

{

function\_body;

}

Hier is een functie om de vierkantswortel van een bepaald getal te vinden

static long int getSquare(int num){

return (num*num);

}

Programma om voorbeeld van statische functie in C-taal te demonstreren

#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;

}

Uitvoer

Enter an integer number: 36

Square of 36 is 1296.

Waarom zijn de statische functies vereist?

Aangezien functies worden gebruikt om de code opnieuw te gebruiken (d.w.z de code die u heeft geschreven heeft toegang tot een ander bestand door ze in de functies ) te plaatsen, maar wanneer u een aantal functies die niet deelbaar (opvraagbaar) mogen zijn in een ander bestand .

statische functies zijn ook nuttig om aangifteprobleem op te lossen – als er twee functies zijn in twee verschillende bestanden met dezelfde naam, zal de functieverklaring conflicteren. We kunnen ze statisch maken.

Om aan dergelijke vereisten te voldoen, kunnen we ze statisch maken .

Antwoord

Kort antwoord: Het betekent dat de functienaam alleen zichtbaar en opvraagbaar is in het bestand dat momenteel wordt gecompileerd. Andere bestanden die afzonderlijk zijn gecompileerd, zullen de functienaam niet zien of deze kunnen aanroepen. Vervolgens kunnen ze hun eigen statische functies met dezelfde naam hebben. Dit vermijdt naamconflicten bij het opnemen van bestanden en bij het koppelen van objectbestanden en binaire bibliotheken.

Er zijn 4 verschillende opslagklassen voor opslag in C.

  • auto (automatisch) dit is “normaal” (standaard) en gebruikt het trefwoord auto , maar is meestal niet gespecificeerd omdat het de standaard is.
  • register is een “hint” voor de compiler dat het de gemaakte code kan optimaliseren om de waarde in een cpu-register voor snellere verwerking. De compiler zal het proberen als het kan, maar zo niet, dan is het hetzelfde als normaal.
  • extern extern betekent dat er slechts één globale variabele met die naam, en alle bestanden die deze als extern declareren, zullen die opslag gebruiken. Eén bestand zal het globaal declareren als een reguliere variabele, waar het bij compilatie zal worden toegewezen.
  • statisch opslagspecificatie in C-bronbestanden betekent een paar verschillende dingen.

  1. De naam en opslag worden niet geëxporteerd naar andere bestanden die tegelijkertijd worden gecompileerd. Hierdoor kan elk bestand identieke namen hebben die niet botsen.
  2. De opslag die voor de variabele wordt gemaakt, wordt gemaakt in het statische opslaggebied en geïnitialiseerd op 0 bij het starten van het programma, of met een expliciete waarde.
  3. Initialisatie van een statische variabele wordt slechts één keer uitgevoerd . (tijdens het samenstellen). Daarna worden de toegewezen waarden bewaard voor de levensduur van het programma of totdat ze worden gewijzigd door een toewijzing.
  4. Statische opslag gedeclareerd binnen functies heeft een functiebereik, maar statische toewijzing. Dit betekent dat de opslag permanent is voor de levensduur van het programma en niet wordt gemaakt wanneer het functiestapelframe wordt toegewezen voor de functieaanroep. Het behoudt zijn waarde door meerdere functieaanroepen. De opslag blijft bestaan, ook al wordt het codeblok van de stapel hersteld nadat het is teruggekeerd.

int accumulate( unsigned int x)

{

static unsigned int acc = 0;

acc = acc + x;

return acc;

}

  1. Het bovenstaande zou terugkeren een lopende telling van zijn invoer, aangezien de var acc de waarde zou behouden tijdens elke aanroep. acc wordt geïnitialiseerd op 0 bij het laden van het programma.
  2. statische variabelen hebben adressen in RAM, en je kunt ze naar functies sturen door middel van referentie of waarde.
  3. Variabelen met een kleiner bereik (gedefinieerd binnen functies) die dezelfde naam hebben als een statische variabele buiten dat bereik, vormen een schaduw van de statische variabele, hetzelfde als alle andere.
  4. statische variabelen mogen dat niet zijn geëxporteerd naar externe bestanden, dus waarden kunnen verloren gaan tussen compilatiedomeinen als ze niet expliciet als parameter op waarde worden verzonden. (gotcha!)
  5. Net als 4 hebben andere bestanden geen toegang tot statische variabelen als extern zoals ze zouden kunnen met automatische (normale) variabelen. Het zal niet werken, je krijgt programmas met fouten die crashen, en de compiler kan voor de gek gehouden worden en het missen.
  6. Statische variabelen kunnen geïnitialiseerd worden bij hun declaratie, maar de initialiseringswaarde moet een constante uitdrukking zijn, evalueerbaar tijdens het compileren, geen waarde die niet kan worden berekend tijdens het compileren. U kunt een statische variabele niet initialiseren met een onbekende waarde, zoals een parametervariabele, of het resultaat van een functieaanroep die niet heeft plaatsgevonden tijdens het compileren.

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 functies

  1. Een statische functie in C heeft een bestandsbereik . Een statische functie kan niet opgeroepen door een ander bestand in dezelfde vertaaleenheid. Een vertaaleenheid is alle broncode die na voorverwerking naar een compiler gaat om in één keer te worden gecompileerd. Statische functies hebben geen toegang tot statische variabelen of roepen geen statische functies op vanuit andere bestanden. Dus als u de toegang tot een functie tot het huidige bestand wilt beperken, kunt u het statisch maken. Er kan slechts één functie met die naam in dat bestand voorkomen (dat geldt ook voor reguliere functies), dus vaak worden hulpprogramma-functies in headerbestanden geplaatst, om in meerdere compilaties te worden opgenomen, en wordt de header bewaakt met pre-processoropdrachten om niet meer dan eens in een compilatie-eenheid worden opgenomen. Alle standaard C-bibliotheekheaders zitten vol met globale functies, en die worden bewaakt zodat ze slechts één keer in een compilatie worden gecompileerd en het zijn globale functies. Geen statische functies. Statische functies zouden ‘interne koppeling’ hebben, wat betekent dat ze niet kunnen worden gezien in andere gecompileerde modules, zelfs niet als ze zijn gekoppeld aan hetzelfde uiteindelijke programma of dezelfde bibliotheek. Als een functie niet statisch is, dan is die functie in C een globale functie en zal deze globaal in het hele programma beschikbaar zijn. Dit betekent dat je in het hele programma maar één functie zou kunnen hebben met de naam print . Om dit te omzeilen, maakt u uw functies en variabelen statisch, zodat u geen botsende namen krijgt.
  2. Functies zijn globaal en standaard extern , behalve in het bestand waarin ze zijn gedefinieerd. U ziet dus niet het woord extern gebruikt in C-bron met functies, omdat het er al impliciet is. Dit is de reden waarom u normale functies kunt oproepen vanuit elk bestand in de vertaaleenheid. Er wordt gezegd dat ze externe link hebben, wat betekent dat als ze eenmaal zijn gekoppeld, ze zichtbaar en opvraagbaar zijn door elk bestand in de module of elke andere module in het gekoppelde programma.
  3. Een functieprototype-declaratie is een “voorlopige definitie”, die impliciet extern is . Code nadat de prototype-declaratie voor de eerste keer is gescand, kan de functie aanroepen zolang de volledige definitie in de definitieve code bestaat. Dat betekent dat er werkelijk een “werkelijke definitie” moet bestaan, anders mislukt de koppelingsfase . Dit is de reden waarom headers in C meestal niet de broncode voor de functies bevatten, ze zijn niet nodig om te compileren, maar bevinden zich in de koppelingsfase.
  4. Een statische functieprototype-declaratie is een “voorlopige definitie”, die expliciet niet extern is . De volledige definitie moet aanwezig zijn in de huidige vertaaleenheid (tegelijkertijd gecompileerd), anders mislukt de compilatie. Moderne C-compilers zullen het prototype van de definitie synthetiseren, zolang het eerder plaatsvindt dan een daadwerkelijke functieaanroep. Zogenaamde “forward declarations” maken het gebruik van voorlopige definities mogelijk met de feitelijke definitie later, en hebben verschillende toepassingen in datastructuren en bij de organisatie van bibliotheken.
  5. De eerste definitie van een bestandshandtekening is degene die wordt gebruikt voor het hele programma, inclusief statisch of extern. Zodra een functie voor het eerst is gedefinieerd en deze aanvankelijk als statisch wordt gedeclareerd, zal deze altijd statisch zijn, zelfs als deze later opnieuw wordt gedefinieerd zonder het statische sleutelwoord. Als in eerste instantie extern is gedeclareerd (standaard), kan het niet opnieuw worden gedefinieerd als statisch.

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"

  1. Functies die zijn gedefinieerd in blokbereik kunnen niet statisch worden verklaard. Alleen statische functiedefinities van bestanden kunnen buiten een blok worden gemaakt. Dit is logisch gezien logisch, aangezien het bereik van het bestand niet kleiner kan worden gemaakt dan het hele bestand. Dus definieer een statische functie, of in ieder geval het prototype, heel vroeg in het bestand.
  2. Statisch verwijst naar de functie, niet naar het retourtype . U kunt het statische trefwoord achter het retourtype plaatsen als u dat wilt, maar als u dat doet, bent u raar en brengt u mensen in verwarring. De geretourneerde waarde is niet statisch, de functie is dat wel.
  3. Een statische functiedefinitie zal een globale een die ervoor is gedefinieerd in hetzelfde bestand of in een opgenomen bestand. Als er al een functie met die naam is gedefinieerd, mag u deze niet herdefiniëren met een statische functie of een functie met dezelfde naam.

C hernoemt functies en variabelen niet intern zoals C ++ doet, dus het ondersteunt geen functie-overbelasting. C ++ “verminkt” de functienamen met een gecodeerde naam die verschillende extra soorten gegevens aangeeft, zoals of het deel uitmaakt van een klasse of wat de parameters zijn, enz. Dus in C afwezig het statische sleutelwoord, mag je maar één functie hebben van elke unieke naam in een programma, ongeacht hoeveel bestanden of bibliotheken het bevat.

Dus wat doe je als je je functie wilt vervangen door een functie die al bestaat?

Wat slimme C-codeerders doen, is een andere naam bedenken voor hun functie. Maar er is een manier om de compiler voor de gek te houden door preventief de brontekst te wijzigen met de preprocessor.

Voorbeeld: een idioot schreef een int sort( char** Array) -functie in zijn bibliotheek en maakte het globaal, en het is buggy en doet niet precies wat je wilt, omdat het ervoor zorgt dat cijfers na letters of zoiets komen, en de T-woorden om de een of andere reden altijd de eerste zijn.

Je wilt gebruik de bibliotheek maar moet de functie repareren, en je hebt alleen de headers en de gecompileerde bibliotheek, niet de broncode.

OK> dus er wordt een “speciale” header gemaakt die alle instanties van ” sort ”met“ bad\_sort ”in de header, importeert vervolgens uw code en vervangt alle gevallen van“ sort ”door“ good\_sort ”. “Good\_sort” is volledig gedefinieerd in good\_sort.h, maar is gemarkeerd als statisch, dus het is alleen bekend in het bestand waarin het is opgenomen.

/* good\_sort.h */

#ifndef \_GOOD\_SORT\_H

#define \_GOOD\_SORT\_H

static int good\_sort(char** Array)

{

... //code here

return numsorted;

}

#endif

Er is een definitiebeugel toegevoegd om er zeker van te zijn dat deze niet tweemaal wordt opgenomen.

/*-----------------------------------*/

/* 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 */

Een beetje een onzin, maar het idee is om je functie aan te roepen in plaats van de slechte door renam door het op “good\_sort” te zetten en dat in plaats daarvan te bellen. (maar alleen in dit bestand – statisch ).

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *