2010-02-25 6 views
7

stavo leggendo the following text from Stanford's Programming Paradigms class, e ho notato che quando l'autore utilizza la classe string, il costruttore fa una chiamata di funzione che assomiglia a questo:elementare C++ Tipo Confusione

string::string(const char* str) { 
    initializeFrom(str, str + strlen(str)); 
} 

Se la funzione initializeFrom prende due char * argomenti, come mai il secondo argomento può passare un (char * + int) a un char * e farlo funzionare correttamente? In che modo il sistema di tipi interpreta questa affermazione?

Grazie in anticipo.

+0

'strlen()' restituisce effettivamente un 'size_t', non un' int'. Una delle differenze importanti è che 'size_t' è un tipo senza segno, cioè può contenere solo numeri positivi. Questo ha senso - le lunghezze delle stringhe possono essere 0, 1 o 30000 caratteri, ma mai -7. – MSalters

risposta

11

Questo è chiamato aritmetica del puntatore. Un char * + int risulta in un char * che ha caratteri int più alti in memoria.

+1

+1 per nominarlo correttamente. :) –

+0

Se 'int' è -ve potrebbe anche essere inferiore nella memoria; quindi dovrebbe essere un 'unsigned int' perché il risultato sia * sempre * più alto nella memoria. [Scusa se si tratta di nitpicking;] – legends2k

+0

@ legends2k Questo è vero, sebbene strlen() non debba mai restituire un valore negativo, quindi il particolare codice in analisi qui risulterà nel secondo argomento sempre maggiore o uguale al primo. – ChrisH

0

Il primo argomento punta all'inizio dell'array char e il secondo punta il carattere NULL alla fine dell'array char.

const char *str = "abc"; 
char *start = str; // start now points to the first char. 
char *end = str + strlen(str); // end now points to the null char at the end. 

È possibile confermare questa stampa:

printf("%c %d",*start,*end); // will output: a 0 
0

come mai il secondo argomento può passare un (char * + int)

E 'ancora passando un puntamento char * a strlen(str) oltre la posizione inizialmente indicata.

2

Ricordare che un puntatore è solo una variabile che contiene un indirizzo di memoria. Quindi puoi aggiungere valori a un indirizzo di memoria. Un indirizzo di memoria è un numero.

Quando si aggiunge 1 a un puntatore di un determinato tipo, verrà effettivamente aggiunto 1 * sizeof (tipo). Quando aggiungi qualsiasi valore N, in realtà aggiungerà N * sizeof (tipo).

consideri il seguente esempio:

int x[5] = {0,1,2,3,4}; 
int *p = &(x[0]);//point to the first element 
p = p + 1;//p now points to the second element. 
4

operatori additivi binari + e - possono essere utilizzati quando un argomento è un puntatore a qualsiasi tipo completa (ad esempio, T* p) e l'altro argomento è un intero (ad esempio, i). Implementano il cosiddetto aritmetico del puntatore .

Il compilatore presuppone che il puntatore punta a un elemento di un array (ad esempio, T array[N]). L'operazione produce un puntatore a un altro elemento dell'array, che è i elementi lontano dall'elemento originale. È possibile "spostare" il puntatore in entrambe le direzioni, cioè verso l'inizio dell'array o verso la fine dell'array. Ad esempio, se p punta a array[3], quindi p + 4 punta a array[7].

L'operazione è valida solo quando i punti di risultato a un elemento esistente della matrice o uno dopo l'ultimo elemento della matrice, ossia data la matrice T array[N], è possibile creare puntatori a elementi dal array[0] all'elemento immaginario array[N]. Qualsiasi tentativo di superare questi limiti utilizzando il risultato aritmetico del puntatore nel comportamento non definito.

Il tipo T deve essere completa, nel senso che l'aritmetica dei puntatori non può essere utilizzata con void * puntatori, per un esempio, anche se alcuni compilatori permettono questo come un prolungamento (trattamento void * puntatori come equivalente a char * puntatori).

Oltre agli operatori additivi binari, puntatori include anche prefisso e suffisso unari ++ e -- operatori (applicato puntatori) così come operatori di assegnamento composto += e -= (con puntatori nella sua sinistra e interi su il lato destro).

Nel tuo caso, str + strlen(str) espressione produrrà un puntatore di char * tipo che punta alla terminazione \0 carattere della stringa str.

0

Penso che questo potrebbe essere eccessiva risposta.

In:

initializeFrom(str, str + strlen(str)); 

str è un puntatore all'inizio della stringa.

(str + strlen(str)) è un puntatore alla fine della stringa.

tenga presente che str (un puntatore a carattere) è solo un numero intero ((int), (long), (long long) seconda dell'architettura) che identifica una locazione di memoria.

+0

Un puntatore non è (sempre) un numero intero. Ad esempio, per x86-16 è una coppia di numeri interi. – MSalters