2015-01-30 18 views
7

Se una funzione è dichiarata comeC: come dichiarare una funzione statica che restituisce una stringa non statica?

static char *function(...) { ... } 

Vuol dire che si tratta di una funzione non statico che restituisce un static char *, o una funzione statica che restituisce un non statico char *?

Confrontare le seguenti due funzioni. Qual è l'uso corretto?

static char *fn1(void) 
{ 
    static char s[] = "hello"; 
    return s; 
} 


static char *fn2(void) 
{ 
    char *s = malloc(6); 
    strcpy(s, "world"); 
    return s; 
} 
+0

'char statico *' non è un tipo –

+0

In realtà, il 'void' è ridondante e rende alcuni compilatori interrotti. –

+0

@ Prof.Falken, penso che 'fn1 (void)', almeno in C89, significa che sto dichiarando una funzione che non accetta alcun parametro, mentre 'fn1()' significa che i parametri non sono specificati (cioè, nel vecchio tempi in cui l'idea del prototipo non è stata inventata). Ho sbagliato? – hbp

risposta

8

static si applica alla funzione, non al tipo di ritorno. Entrambe queste funzioni sono corrette: la differenza è che s verrà inizializzato una volta alla prima chiamata a fn1 e tutte le chiamate a fn1 condivideranno s; mentre in fn2, un nuovo s verrà assegnato ad ogni chiamata. E poiché sia ​​fn1 e fn2 hanno il collegamento static, saranno privati ​​dell'unità di traduzione (file di origine, approssimativamente) in cui sono definiti.

+0

Grazie per la chiara spiegazione. – hbp

3

Entrambe le definizioni delle funzioni sono corrette.

Point to note, static qui viene utilizzato per limitare la funzione all'ambito del file, non per specificare il tipo di ritorno, cioè, questa funzione può essere utilizzata [chiamata] dalle altre funzioni presenti nello stesso file, ma non da le funzioni che sono presenti in altri file, anche se potrebbero essere stati compilati e collegati insieme per formare il binario.

+0

Grazie per la spiegazione. – hbp

3

static prima della funzione applica alla funzione, non il tipo (o parte di esso, come il ritorno-type):
significa che la funzione ha il collegamento statico, alias è Traduzione unità/File locale (e quindi molto probabile che sia in linea).

Entrambe le funzioni sono corrette, anche se hanno diverse semantica:

  • Il primo restituisce un puntatore a una matrice statica, il cui contenuto può essere modificato. Attenzione però alla concorrenza e ai problemi di riacquisizione se lo fai.
  • Il secondo alloca un po 'di memoria heap, lo inizializza con una stringa e lo restituisce. Ricordati di free it.
+0

Grazie per la risposta! – hbp

1

La parola chiave static quando utilizzata con una definizione di funzione indica che la funzione ha un ambito a livello di file. Questo significa che il nome della funzione è visibile solo all'interno del file stesso. La parola chiave static utilizzata in una definizione di funzione modifica la visibilità del nome della funzione e non modifica il tipo di ritorno della funzione.

Quindi una funzione dichiarata statica può restituire qualsiasi tipo di un tipo.

L'uso di static su una variabile definita in un corpo di una funzione viene utilizzato per indicare che la variabile deve essere creata nel momento in cui l'applicazione viene caricata e avviata. Pertanto, se si utilizza il modificatore static su una variabile all'interno di una funzione, tale variabile non viene creata nello stack quando viene chiamata la funzione. Esiste indipendentemente da quando viene chiamata la funzione. Tuttavia la visibilità della variabile è solo all'interno della funzione.

Nell'esempio si ha una funzione che restituisce l'indirizzo di una variabile static. Puoi farlo, ma devi capire che questo uso non è sicuro.In altre parole, tutti i thread che chiamano la funzione otterranno la stessa variabile nella stessa posizione di memoria e non nella propria versione della variabile.

È inoltre necessario comprendere che se si restituisce l'indirizzo di una variabile static si possono anche causare problemi con la rientranza e la ricorsività. La ragione è che le variabili nello stack forniscono la ricorrenza e la ricorsività dal momento che ogni volta che viene chiamata la funzione, viene aggiunto un nuovo frame allo stack in modo che ogni chiamata di funzione abbia il proprio frame di stack quindi il proprio insieme di variabili.

Questo è un problema noto con il vecchio strtok() funzione nella libreria standard C che utilizza una variabile all'interno della funzione strtok() per mantenere uno stato tra chiamate utilizzando NULL come indirizzo stringa di dove l'ultima chiamata al strtok() sinistra quando parsing una stringa. Ho visto un problema in cui una funzione chiamata strtok() iniziava l'analisi di una stringa e quindi chiamava un'altra funzione che a sua volta chiama strtok() per iniziare l'analisi di una stringa diversa. Il risultato sono stati alcuni errori e comportamenti davvero strani fino a quando la causa non è stata individuata.

L'utilizzo del modificatore static su una variabile globale all'interno di un file creerà una variabile globale che può essere condivisa da più funzioni all'interno del file. Tuttavia, ad esempio usando il modificatore statico su un nome di funzione, una variabile static avrà solo visibilità dell'ambito del file.

// .. top of a file of C source code 

static int aStaticInt = 0; // a static int that can be shared by all functions in the file but is visible only in the file 
int aNonStaticInt = 0; // a non static int that is visible outside of the file 

static int myStaticFunc (void) 
{ 
    // a function that is visible only within the file 
} 

int myNonStaticFunc (void) 
{ 
    // a function that is visible outside the file as well as inside the file 
} 
+0

Grazie signore per la spiegazione approfondita! – hbp

Problemi correlati