In realta' il programma inizia la sua esecuzione prima che il
controllo venga ceduto alla funzione main() e termina
successivamente alla restituzione del controllo da parte della funzione
main() od alla chiamata della funzione exit().
Che cosa avvenga negli istanti che precedono
la chiamata di main() e negli istanti successivi al suo termine,
dipende fortemente dall'implementazione del compilatore e dalla
interazione con il sistema operativo.
Per esempio, all'inizio, potrebbero venire invocate delle routine di
inizializzazione che provvedono all'apertura dei file standard (stdio,
stdout e stderr), alla copia della command line in apposiata area di
memoria, al salvataggio dei puntatori del vettore di interrupt (HW e/o SW) ed
aggancio di nuove e specifiche routine (es: gestione I/O per porte seriali,
gestione dell'orologio di sistema, ecc.), ecc., poi, al termine
dell'inizializzazione, il controllo passa alla funzione main chiamandola con i
parametri da passare.
Analogamente, al termine della funzione main() (od in seguito alla chiamata
della funzione exit() ), potrebbero venire eseguite delle routine di
terminazione che provvedono ad effetuare la flush dei files (scrittura
dei dati ancora presenti nei buffer di memoria) e chiusura dei files ancora
aperti qualora il programmatore non abbia provveduto direttamente, a
ripristinare il vettore di interrupt con i puntatori salvati in fase di
inizializzazione, ecc..
Non e' necessario che le funzioni richiamate dal main() o, piu' in
generale, richiamate da altre funzioni, siano definite nello stesso file
sorgente assieme alle funzioni chiamanti; come caso limite, ogni funzione
potrebbe venire scritta in un file differente e
compilata separatamente.
int main(void) {...} int main(int argc, char *argv[]) {...} int main(int argc, char *argv[], char *envp[]) {...}Tradizionalmente gli argomenti della funzione main() vengono battezzati argc, argv e envp da tutta la letteratura informatica e dalla comunita' di programmatori.
In particolare argc, dichiarato come int, e argv,
dichiarato come array di puntatori a char servono per passare
al programma i paramentri inseriti nella linea di comando
(command tail) al momento in cui si richiede al sistema operativo di
mandare in esecuzione il programma stesso.
Infine envp dichiarato come array di puntatori a char,
se presente, e' impiegato per trasmettere al programma copia dell'ambiente
(cioe' tramite envp vengono passate le variabili di ambiente al
programma).
Nel dettaglio:
argc contiene il numero dei paramentri sulla riga di comando, incluso il nome del programma. Pertanto argc e' sempre >= 1. | |||||||||
argv e' un array di puntatori a char. Ogni puntatore
referenzia un singolo parametro della linea di comando sottoforma
sempre di stringa. In altri termini, i parametri inseriti nella linea di comando vengono sempre acquisiti dal programma come stringhe, anche nel caso che questi rappresentino dei valori numerici. Il significato dell'array di puntatori e' il seguente:
| |||||||||
envp e' un array di puntatori a char. Ogni puntatore referenzia
una singola variabile di ambiente, definita come stringa ed avente la
forma:variabile=valoreA differenza di argv, per envp non e' dato di conoscere a priori il numero di puntatori presenti nell'array. Analogamente ad argv, anche per envp l'ultimo puntatore valido e' seguito da un puntatore nullo; pertanto il termine dell'array e' testabile con la condizione: envp[i] == '\0'In alternativa all'uso di envp per la rilevazione delle variabili di ambiente, e' preferibile fare impiego della funzione getenv() della libreria standard. |