2008-10-02 10 views
92

Domanda veloce:const int vs int const come parametro di funzione in C++ e C

int testfunc1 (const int a) 
{ 
    return a; 
} 

int testfunc2 (int const a) 
{ 
    return a; 
} 

sono questi due funzioni lo stesso in ogni aspetto o c'è una differenza? Sono interessato a una risposta per il linguaggio C, ma se c'è qualcosa di interessante nel caso C++ mi piacerebbe saperlo.

+0

C'è una parola chiave const in C ora? Non c'era, ma non sono così familiare con lo standard C 99. –

+6

Non è necessario esserlo. C90 è sufficiente. Sebbene non fosse nel K & R C originale. –

+2

È una parola chiave in C89 e ANSI. Non so se fosse una parola chiave nei giorni di Kerningham e Richie. –

risposta

146

const T e T const sono identici. Prestare attenzione alla precedenza del puntatore, tuttavia:

char const* è un puntatore a un carattere costante (matrice), mentre char* const è un puntatore costante a un carattere mutabile (matrice).

+1

C ha const, dato: static const char foo [] = "foo"; è meglio non modificare foo. –

+1

K & R C non ha avuto const; C90 (e C99) fa. È un po 'limitato rispetto al C++, ma è utile. –

+0

Ho già rimosso quell'assurdità dal mio testo. ;-) –

3

Sì, sono uguali per appena int

e diverso per int*

+5

(const int *) e (int const *) sono gli stessi, sono solo diversi da (int * const). –

3

Credo che in questo caso sono gli stessi, ma qui è un esempio in cui le questioni di ordine:

const int* cantChangeTheData; 
int* const cantChangeTheAddress; 
+1

Infatti, ma int const * è uguale al primo, quindi l'ordine di int e const non ha importanza, è solo l'ordine del * e del const che lo fa. –

7

Prakash è corretto che le dichiarazioni sono le stesse, anche se un po 'più spiegazione del caso puntatore potrebbe essere in ordine

"const int * p" è un puntatore a un int che non consente di modificare l'int tramite quel puntatore. "int * const p" è un puntatore a un int che non può essere modificato per puntare a un altro int.

Vedere http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.5.

12

Non c'è differenza. Entrambi dichiarano "un" un numero intero che non può essere modificato.

Il punto in cui le differenze iniziano ad apparire è quando si usano i puntatori.

Entrambi questi:

const int *a 
int const *a 

dichiarare "a" per essere un puntatore a un intero che non cambia. "a" può essere assegnato a, ma "* a" non può.

int * const a 

dichiara "a" di essere un puntatore costante a un numero intero. "* a" può essere assegnato a, ma "a" non può.

const int * const a 

dichiara "a" come puntatore costante a un numero intero costante. Né "a" né "* a" possono essere assegnati a.

static int one = 1; 

int testfunc3 (const int *a) 
{ 
    *a = 1; /* Error */ 
    a = &one; 
    return *a; 
} 

int testfunc4 (int * const a) 
{ 
    *a = 1; 
    a = &one; /* Error */ 
    return *a; 
} 

int testfunc5 (const int * const a) 
{ 
    *a = 1; /* Error */ 
    a = &one; /* Error */ 
    return *a; 
} 
291

Il trucco è quello di leggere la dichiarazione all'indietro (da destra a sinistra):

const int a = 1; // read as "a is an integer which is constant" 
int const a = 1; // read as "a is a constant integer" 

Entrambi sono la stessa cosa.Pertanto:

a = 2; // Can't do because a is constant 

La lettura all'indietro trucco viene particolarmente utile quando hai a che fare con le dichiarazioni più complesse, come:

const char *s;  // read as "s is a pointer to a char that is constant" 
char c; 
char *const t = &c; // read as "t is a constant pointer to a char" 

*s = 'A'; // Can't do because the char is constant 
s++;  // Can do because the pointer isn't constant 
*t = 'A'; // Can do because the char isn't constant 
t++;  // Can't do because the pointer is constant 
+71

Mi piace il trucco di lettura all'indietro. :-) –

+20

questo è un suggerimento di insegnamento molto forte - ben fatto – bph

+1

che dire di "char const * u"? Questo legge "Un puntatore a un carattere costante" o "un puntatore che è costante per un carattere"? Sembra ambiguo. Lo standard dice il primo, ma per scoprirlo, devi prendere in considerazione le regole di precedenza e di associatività. –

4

Questa non è una risposta diretta, ma un suggerimento relativo. Per mantenere le cose dritte, uso sempre la convezione "metti const all'esterno", dove con "fuori" intendo l'estrema sinistra o l'estrema destra. In questo modo non c'è confusione - il const si applica alla cosa più vicina (o il tipo o lo *). Ad esempio,



int * const foo = ...; // Pointer cannot change, pointed to value can change 
const int * bar = ...; // Pointer can change, pointed to value cannot change 
int * baz = ...; // Pointer can change, pointed to value can change 
const int * const qux = ...; // Pointer cannot change, pointed to value cannot change 
+5

Forse stai meglio usare la regola "const rende const tutto ciò che resta di esso". Per esempio. "int * const foo" rende il puntatore "const", perché il puntatore è lasciato ad esso. Tuttavia, dovresti scrivere la seconda riga "int const * bar", rende int const, perché è lasciato ad esso. "int const * const * qux", rende entrambi, int e il puntatore const, perché a uno dei due viene lasciata una sola volta. – Mecki

5

const int è identico a int const, come è vero con tutti i tipi scalari in C. In generale, dichiarare un parametro di funzione scalare come const non è necessaria, poiché semantica call-by-value di C significa che qualsiasi le modifiche alla variabile sono locali alla sua funzione di chiusura.

-2

Sono uguali, ma in C++ c'è una buona ragione per usare sempre const sulla destra. Sarete coerente in tutto il mondo, perché le funzioni membro const devono essere dichiarati in questo modo:

int getInt() const; 

cambia il puntatore this nella funzione Foo * const-Foo const * const. See here.

+2

Questo è un tipo completamente diverso di const. –

+0

Perché è completamente diverso? Abbastanza diverso da guadagnare un downvote. –

+0

Sì, la domanda riguarda la differenza tra "const int" e "int const" la tua risposta non ha nulla a che fare con esso. –

Problemi correlati