2010-02-25 15 views
7

estaba leyendo the following text from Stanford's Programming Paradigms class, y me di cuenta que cuando el autor utiliza la clase string, el constructor hace una llamada a la función que tiene este aspecto:Primaria C++ Tipo Confusión

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

Si la función initializeFrom necesitan dos char * argumentos, ¿cómo es que el segundo argumento puede pasar un (char * + int) a un char * y hacer que funcione correctamente? ¿Cómo interpreta el sistema de tipo esta declaración?

Gracias de antemano.

+0

'strlen()' en realidad devuelve un 'size_t', no un' int'. Una de las diferencias importantes es que 'size_t' es un tipo sin signo, es decir, solo puede contener números positivos. Esto tiene sentido: las longitudes de cadena pueden ser 0, 1 o 30000 caracteres, pero nunca -7. – MSalters

Respuesta

11

Esto se llama aritmética de puntero. Un char * + int da como resultado un char * que tiene int caracteres más arriba en la memoria.

+1

+1 para nombrarlo correctamente. :) –

+0

Si el 'int' es -ve, también podría estar más bajo en la memoria; por lo que debe ser un 'int sin firmar' para que el resultado sea * siempre * más alto en la memoria. [Perdón si esto es quisquilloso;] – legends2k

+0

@ legends2k Eso es cierto, aunque strlen() nunca debe devolver un valor negativo, por lo que el código particular que se analiza aquí dará como resultado que el segundo argumento sea siempre mayor o igual que el primero. – ChrisH

0

El primer argumento apunta al inicio de la matriz de caracteres y el segundo apunta al carácter NULO al final de la matriz de caracteres.

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. 

Puede confirmarlo mediante impresión:

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

¿cómo es que el segundo argumento puede pasar a un (char * + int)

Todavía está pasando un puntero que char * a strlen(str) pasando la ubicación inicialmente apuntada.

2

Recuerde que un puntero es solo una variable que contiene una dirección de memoria. Entonces puede agregar valores a una dirección de memoria. Una dirección de memoria es un número.

Cuando agrega 1 a un puntero de cierto tipo, realmente agregará 1 * sizeof (tipo). Cuando agrega cualquier valor N, realmente agregará N * sizeof (tipo).

Consideremos el siguiente ejemplo:

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

operadores aditivos binarios + y - se pueden utilizar cuando un argumento es un puntero a cualquier tipo completo (por ejemplo, T* p) y el otro argumento es un número entero (por ejemplo, i). Implementan lo que se llama puntero aritmética.

El compilador supone que el puntero apunta a un elemento de una matriz (por ejemplo, T array[N]). La operación produce un puntero a otro elemento de la matriz, que está i elementos lejos del elemento original. Es posible "mover" el puntero en cualquier dirección, es decir, hacia el comienzo de la matriz o hacia el final de la matriz. Por ejemplo, si p apunta a array[3], entonces p + 4 apuntará a array[7].

La operación sólo es válida cuando los puntos de resultados a un elemento existente de la matriz o uno más allá del último elemento de la matriz, es decir, dados la matriz T array[N], es posible crear punteros a elementos de array[0] al elemento imaginario array[N]. Cualquier intento de cruzar estos límites usando la aritmética del puntero produce un comportamiento indefinido.

El tipo T tiene que ser completa, lo que significa que la aritmética de punteros no se puede utilizar con void * punteros, por ejemplo, a pesar de que algunos compiladores permiten esto como una extensión (tratamiento de void * punteros como equivalentes a char * punteros).

Además de los operadores aditivos binarios, la aritmética de punteros también incluye prefijo y posfijo unarios ++ y -- operadores (aplicado a los punteros), así como los operadores de asignación compuesto += y -= (con indicaciones sobre su lado izquierdo y enteros en el lado derecho).

En su caso, str + strlen(str) expresión producirá un puntero de tipo char * que apunta a la \0 carácter de terminación de la cadena str.

0

Creo que esto puede ser una respuesta excesiva.

En:

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

str es un puntero al comienzo de la cadena.

(str + strlen(str)) es un puntero al final de la cadena.

Tenga en cuenta que str (un puntero de caracteres) es sólo un número entero ((int), (long), (long long) dependiendo de la arquitectura) que identifica una ubicación en la memoria.

+0

Un puntero no es (siempre) un número entero. En x86-16, por ejemplo, es un par de números enteros. – MSalters