viernes, 31 de agosto de 2018

Apuntadores, arreglos y aritmetica de apuntadores

Apuntadores, arreglos y aritmetica de apuntadores


Los arreglos y apuntadores estan fuertemente relacionados. El nombre de un arreglo es simplemente un apuntador constante al inicio del arreglo. Se pueden direccionar arreglos como si fueran apuntadores y apuntadores como si fueran arreglos.

Ejemplos:

int lista_arr[5] = {10, 20, 30, 40, 50};
int *lista_ptr;
lista_ptr = lista_arr; // A partir de aqui ambas variables apuntan al mismo sitio
cout << lista_arr[0]; // Imprime 10
cout << lista_ptr[0]; // Instrucción equivalente a la anterior
cout << *lista_arr; // Instrucción equivalente a la anterior
cout << *lista_ptr; // Instrucción equivalente a la anterior
cout << lista_arr[3]; // Imprime 40
cout << lista_ptr[3]; // Instrucción equivalente a la anterior

Es posible sumar y restar valores enteros a un apuntador. El resultado de estas operaciones es el desplazamiento de la direccion de memoria hacia adelante (suma) o hacia atras (resta) por bloques de bytes del tamaño del tipo de dato apuntado por el apuntador.
Esto permite recorrer arreglos utilizando apuntadores.

Ejemplos:

int lista[5] = {10, 20, 30, 40, 50};
int *p;
char cad[15];
char *q;
p = &lista[3]; // ’p’ almacena la dirección de la posición 3 del arreglo
p = lista + 3; // Instrucción equivalente a la anterior
cout << lista[2]; // Imprime 30;
cout << *(lista+2); // Instrucción equivalente a la anterior
// Las siguientes instrucciones imprimen la palabra "Programando"
/* Nota: Recuerdese que una constante de cadena de caracteres es
una secuencia de caracteres en memoria seguidos del caracter nulo */
strcpy(cad, "Programando");
for (q = cad; *q != ’\0’; q++)
cout << q;

También es posible restar dos apuntadores. El resultado de esta operación es el número de bloques de bytes que hay entre las dos direcciones del tamaño del tipo de dato apuntado por los apuntadores.

Ejemplo:

double x[5] = {1.1, 2.1, 3.1, 4.1, 5.1};
double *p = &x[1],
*q = &x[4];
int n;
n = q - p; // a ’n’ se le asigna 3


Asignación dinámica de memoria

Los programas pueden crear variables globales o locales. Las variables declaradas globales en sus programas se almacenan en posiciones fijas de memoria, en la zona conocida como segmento de datos del programa,y todas las funciones pueden utilizar estas variables. Las variables locales se almacenan en la pila (stack) y existen sólo mientras estan activas las funciones donde están declaradas. En ambos casos el espacio de almacenamiento se reserva en el momento de la compilacián del programa.

También es posible reservar y utilizar memoria dinámicamente, tomada de la zona de memoria llamada montículo (heap) o almacén libre. En C están disponibles varias funciones que permiten realizar reservar y librerar memoria, pero C++ además provee un método más fácil y seguro de hacerlo.