gratiszona

arrays y punteros en el lenguaje C

Arrays.
Un array es una coleccion ordenada de objetos, llamados elementos del array, todos del mismo tipo. Un array de 10 elementos se declara de la siguiente forma:
float a[100];
El primer elemento de este array es a[0] y el ultimo a[9].
Un array se puede inicializar asi:
float a[3] = {10.1,10.2,10.3};
Si no se indica el tamaño del array, este sera igual al numero de elementos que se indiquen:
float x[] = {1.3, 2.4};
crea un vector x de tamaño 2.
Arrays multidimensionales
Los arrays multidimensionales se declaran:
int a[3][3], b[2][3];
En este ejemplo, a es una matriz 3x3 y b una matriz 2x3. Los elementos se almacenan por filas, al contrario de lo que sucedia en FORTRAN. Asi, podemos inicializar b de la siguiente forma:
int b[2][3] = { {1,2,3}, {4,5,6} };
Punteros.
El concepto de puntero esta unido a la forma en que los tipos de datos son almacenados en la memoria de un ordenador, ya que denotan la direccion de una variable determinada. El nombre de la variable determina el tipo (char, int, float o double) y su direccion determina donde esta almacenada. Conocer la direccion de una variable es importante porque:
Permite que las funciones cambien el valor de sus argumentos, como veremos en el capitulo siguiente.
Permite pasar vectores de forma eficiente entre funciones: en lugar de copiar cada elemento del vector, se copia la direccion del primer elemento.
Permite reservar memoria en tiempo de ejecucion en lugar deben tiempo de compilacion, lo que significa que el tamaño de un vector puede ser determinado por el usuario en lugar de por el programador.
El nombre de un array es un puntero al array. Por tanto, los punteros y los arrays estan intimamente ligados EN EL LENGUAJE C y EN EL LENGUAJE C++.

Terminologia basica.
Para entender los punteros y los vectores, es necesario conocer primero como se almacenan los numeros en la memoria del ordenador. El valor de cada variable en un programa de ordenador se guarda en una seccion de memoria cuyo tamaño esta determinado por el tipo de dato de la variable. La localizacion de esta seccion de memoria es almacenada en la direccion de la variable. Por tanto, es como si cada variable estuviera compuesta de dos partes: su valor y su direccion. Cada celda de memoria se puede considerar compuesta de una parte con el contenido, y otra en la que se almacena la direccion. Esto es analogo a una fila de casas: cada casa tiene diferentes contenidos y para mirarla necesitamos conocer su direccion.
Las direcciones se representan normalmente por un numero hexadecimal, pudiendo contener un caracter, un entero o un real (aunque en realidad todos son almacenados como numeros binarios).
Para obtener la direccion de una variable se utiliza el operador direccion &:
#include <iostream.h>
main() {
double d = 2.7183;
cout << 'numero = ' << d << '\tdireccion = ' << &d << '\n';
}
El valor de d es 2.7183. El valor de &d es una direccion (donde 2.7183 esta almacenado). La direccion es imprimida en formato hexadecimal.
Direcciones y punteros
Un puntero guarda la direccion de un objeto en memoria y como tal un puntero es tambien una variable. Puede parecer algo confuso, es como decir que el contenido de una casa es la direccion de otra vivienda. Las direcciones se guardan como numeros hexadecimales, por lo que no hay ninguna razon por la que no podamos definir otro tipo de dato, similar a un entero, pero a traves del cual se puede modificar el valor almacenado en esa direccion. Es importante entender la relacion entre punteros y direcciones:
Cada variable tiene su direccion, que puede ser obtenida mediante el operador unario &.
La direccion de una variable puede ser almacenada en un tipo de dato llamado puntero.
Un puntero EN EL LENGUAJE C o EN EL LENGUAJE C++ se declara anteponiendo un * al nombre de la variable, que es el operador inverso a &. El puntero apunta entonces a una variable del tipo especificado y no debe ser usado con variables de otros tipos. Un experto EN EL LENGUAJE C podria forzar la utilizacion de un puntero con un tipo distinto del que se ha declarado, pero no es recomendable, ya que podria conducir a un uso erroneo.
Ejemplos de declaracion de punteros:
int *puntero1;
int *puntero2, *puntero3;
char variable, *punteroCaracter;
float *punteroReal, real;
En la primera linea, declaramos un puntero a un entero. En la segunda, dos punteros a entero. En la tercera, un caracter (variable) y un puntero a caracter (punteroCaracter). Por ultimo, punteroReal es un puntero a un real y real es declarado como un numero real.
Ejemplo de uso del operador * y del operador de direccion (&):
#include <iostream.h>
main() {
double d, *dp;
d = 2.7183;
dp = &d;
cout << 'numero = ' << d << '\tdireccion = ' << &d << '\n';
}
Operaciones con punteros.
Un puntero es un tipo de dato similar a un entero y hay un conjunto de operaciones definidas para punteros:
La suma o resta de un entero produce una nueva localizacion de memoria.
Se puedEN EL LENGUAJE Comparar punteros, utilizando expresiones logicas, para ver si estan apuntando o no a la misma direccion de memoria.
La resta de dos punteros da como resultado el numero de variables entre las dos direcciones.
Siempre que se realiza una operacion aritmetica sobre un puntero, sumando o restando un entero, el puntero se incrementa o decrementa un numero apropiado de sitios tal que el nuevo valor apunta a la variable que esta n elementos (no n bytes) antes o despues que el dado. De la misma forma, al restar dos punteros se obtiene el numero de objetos entre las dos localizaciones. Finalmente, dos punteros son iguales si y solo si apuntan a la misma variable (el valor de las direcciones es el mismo). No son necesariamente iguales si sus valores indirectos son los mismos, ya que estas variables podrian estar en diferentes localizaciones de memoria.
La siguiente tabla resume los operadores que manipulan punteros:
Anterior: estructuras de control
Siguiente: reserva dinamica de memoria