2015-05-08 13 views
13

Ho letto la prima edizione di C++. Nel terzo paragrafo dell'elenco dei parametri delle funzioni del capitolo 6.1. Scrive "Inoltre, le variabili locali nell'ambito più esterno della funzione potrebbero non utilizzare lo stesso nome di qualsiasi parametro". Che cosa significa?Che cosa significa "le variabili locali nella parte più esterna della funzione potrebbero non utilizzare lo stesso nome di qualsiasi parametro" significa?

Non sono madrelingua inglese. Non capisco i significati attuali di "ambito più esterno" della funzione.

risposta

24

L'ambito più esterno della funzione è il blocco che definisce il corpo della funzione. Puoi inserire altri blocchi (interni) al suo interno e dichiarare le variabili in quelle che sono locali a quel blocco. Le variabili nei blocchi interni possono avere lo stesso nome di quelle in un blocco esterno, o i parametri di funzione; nascondono i nomi nello scope esterno. Le variabili nel blocco esterno non possono avere lo stesso nome di un parametro di funzione.

Per dimostrare:

void f(int a)   // function has a parameter 
{      // beginning of function scope 
    int b;    // OK: local variable 
    {     // beginning of inner block 
     int a;   // OK: hides parameter 
     int b;   // OK: hides outer variable 
    }     // end of inner block 
    int a;    // Error: can't have same name as parameter 
} 
+6

Vorrei semplicemente suggerire di evitare l'uso di blocchi e scope in modo intercambiabile. Il commento "inizio del blocco interno", pur corretto, omette il dettaglio della succinta che questo blocco introduce un nuovo _scope_ interno. Che "L'ambito più esterno della funzione è il blocco che definisce il corpo della funzione" non è realmente vero, piuttosto, il blocco che definisce il corpo delle funzioni definisce anche il suo ambito più esterno. Un ambito non è un blocco, è definito da uno. – davmac

+2

@davmac: Grazie per la critica grammaticale. Penso che la formulazione sia abbastanza chiara così com'è. –

+4

@MikeSeymour la critica è più tecnica che grammaticale, ma hey, è la tua risposta. – davmac

16

significa che non si possono fare cose come questa:

void foo (int x) 
{ 
    int x = 4; //in the outermost scope, invalid 
} 

È possibile, tuttavia, fare questo:

void foo (int x) 
{ 
    { //this introduces a new scope 
     int x = 4; //not in the outermost scope, valid 
    } 
} 
+2

è il caso valida mai davvero una buona idea? – dwcanillas

+4

@dwcanillas non in un esempio semplificato, ma in un esempio più complesso in cui gli ambiti sono introdotti da cicli o istruzioni 'if', sono sicuro che potresti trovare un caso ragionevole. Generalmente è una buona idea evitare di "sovraccaricare" i nomi. – TartanLlama

+2

Se ritieni che questa sia una buona idea, probabilmente la tua funzione è troppo lunga o troppo complessa. –

7

Vuol dire che questo non è valido:

void f(int p) 
{ 
    int p = 3; 
} 

dove questo è

void f(int p) 
{ 
    { 
    int p = 3; 
    } 
} 

è consentito.

2

Immaginate di avere una funzione 'foo' che prende un parametro intero 'bar'.

int foo (int bar) 
{ 
    int bar = 0; // < illegal, this is the 'outermost' scope 
    if (bar == 10) { 
     int bar = 5; // legal (though unadvisable) this 'shadows' the passed-in 'bar' 
     return bar; 
    } 
    return bar; 
} 

La prima dichiarazione interna del 'bar' è illegale, dal momento che il passato nel parametro è anche dichiarato nello stesso contesto (anche se la sintassi non necessariamente rende chiaro.)

Proprio come sarebbe errato scrivere:

int bar; 
char bar[10]; 

Poiché queste due variabili condividono lo stesso ambito.

La seconda dichiarazione di bar (nella funzione sopra) è legale (anche se di solito è una cattiva idea) poiché è dichiarata nell'ambito interiore del gioco "se" e quindi equo.

Spero che questo aiuti.

4

Questa regola è valida non solo per i parametri di funzione di definizioni di funzioni, ma anche per l'iterazione e istruzioni condizionali e per le eccezioni gestori

3.3.3 portata Block

2 Il potenziale ambito di un parametro di funzione nome (incluso uno visualizzato in un lambda-dichiaratore) o una variabile predefinita locale di funzione in una definizione di funzione (8.4) inizia al punto della dichiarazione . Se la funzione ha un blocco funzione try il potenziale di un parametro o di una variabile predefinita locale funzione termina alla fine dell'ultimo gestore associato, altrimenti termina sul blocco più esterno della funzione . definizione. Un nome parametro non deve essere ripreso nel blocco più esterno della definizione della funzione né nel blocco più esterno di qualsiasi gestore associato a un blocco di prova .

3 Il nome dichiarato in una dichiarazione di eccezione è locale per il gestore e non deve essere ripreso nel blocco più esterno del gestore .

4 nomi dichiarati nel for-init-statement, il per-gamma-dichiarazione, e nella condizione di se, mentre, per, e passare dichiarazioni sono locale al caso, mentre, per, o switch dichiarazione (compresa la dichiarazione controllata ), e non deve essere dichiarata in una successiva condizione di quella dichiarazione né nel blocco più esterno (o, per la dichiarazione se , uno dei blocchi più esterni) dell'istruzione controllata; vedere 6.4.

Per esempio, questo frammento di codice è valido

if(int x = SomeFunction()) 
{ 
    int x; // invalid declaration 
    //... 
} 
Problemi correlati