De scope van identifiers is een fundamenteel concept dat bepaalt waar in het programma variabelen, functies of andere entiteiten beschikbaar zijn. De vraag van zichtbaarheid heeft een rijke geschiedenis — vanaf de eerste implementaties van C leidde verkeerd gebruik van scopes tot moeilijk te achterhalen fouten, gerelateerd aan overschrijvingen, onverwacht gedrag en koppeling fouten.
C is oorspronkelijk ontworpen voor kleine projecten, waar het hele programma in één bestand werd geplaatst. Met de evolutie van de taal ontstond de noodzaak om variabelen/functies duidelijk te scheiden voor verschillende delen van het programma, wat leidde tot de formalisering van scopes: block, file, en globaal.
Zonder goed georganiseerde scopes kan men per ongeluk de waarden van variabelen wijzigen die in verschillende delen van het programma worden gebruikt, naamconflicten krijgen of de controle over de programmastructuur verliezen. Fouten met "schaduw" variabelen en het overschrijven van globale definities door lokale variabelen zijn een veelvoorkomende oorzaak van bugs.
In C zijn de scopes:
{ ... } (bijvoorbeeld, in een functie of loop). Buiten het blok wordt de variabele "vergeten".Voorbeeldcode:
#include <stdio.h> int global = 10; // globale scope void foo() { int block_var = 5; // block scope static int static_file_var = 0; // file scope, als static buiten functies printf("%d\n", block_var); } int main() { printf("%d\n", global); // zichtbare globale foo(); // printf("%d\n", block_var); // fout: block_var niet zichtbaar return 0; }
Belangrijke kenmerken:
1. Als een globale variabele en een functieparameter dezelfde naam hebben, wat zal dan binnen de functie worden gebruikt?
De functie "verduistert" de globale variabele met de parameter, dus binnen de functie wordt de waarde van de parameter gebruikt. De globale variabele is alleen toegankelijk onder een andere naam (tenzij deze is overschreven).
2. Is de scope van static binnen de functie en static buiten de functie hetzelfde?
Nee! static binnen een functie (static local) — de variabele behoudt de waarde tussen aanroepen, maar is alleen zichtbaar in deze functie. static buiten functies — beperkt de zichtbaarheid van de variabele/functie tot het huidige bestand.
Voorbeeldcode:
static int a = 0; // static file scope void foo() { static int b = 0; // static local scope }
3. Mag de naam van een lokale variabele gelijk zijn aan die van een globale variabele?
Ja, maar dit zal leiden tot "verduistering" van de globale binnen het huidige blok. Dit leidt tot fouten door onjuiste toegang tot de verkeerde waarde.
Voorbeeldcode:
int var = 10; void f() { int var = 20; printf("%d", var); // geeft 20, globale is niet zichtbaar }
Project is verdeeld over 2 bestanden. Gelijkaardige globale variabelen zijn in beide bestanden gedeclareerd zonder static/extern. De linker geeft een foutmelding of het programma werkt met onverwachte waarden.
Voordelen:
Nadelen:
Er wordt expliciet gebruik gemaakt van static en extern, de variabelen zijn in een aparte header geplaatst en de benoemregels zijn beschreven.
Voordelen:
Nadelen: