ARRAYS Y PUNTEROS - ¿DOS CARAS DE LA MISMA MONEDA?
Las variables declaradas vía:
unsigned char x ; unsigned char y ;
son posiciones de memoria de 8 bits. Las declaraciones:
unsigned int a ; unsigned int b ;
reservan cuatro posiciones de memoria dos para 'a', y dos para 'b'. En varios lenguajes de programación es posible agrupar variables del mismo tipo en arrays. En BASIC se crea un array con DIM a(10).
De igual forma en 'C' se declara un array, así:
unsigned char a[10] ;
Su efecto es reservar diez posiciones de memoria consecutivas, comenzando en la dirección de 'a'. Como no hay nada al lado derecho de la definición, no se asignan valores iniciales a los elementos del array.
Una situación más usual con arrays es:
unsigned char test_array [] = { 0x00,0x40,0x80,0xC0,0xFF } ;
en la que los valores iniciales se asignan antes de que el control del programa llegue a "main()". Notar que no es necesario poner entre corchetes el tamaño del array, ya que el compilador lo ajusta automáticamente.
Otro ejemplo corriente en BASIC es el de una cadena, o array de caracteres como:
A$ = "HELLO!"
En C se escribe así:
char test_array[] = "HELLO!";
En C no hay distinción entre cadenas y arrays, ya que en C un array es un conjunto secuencial de bytes ocupados por caracteres o números. De echo, el campo de los apuntadores y los arrays se solapan con las cadenas en virtud de:
char test_array[] = "HELLO!"; char *string_ptr = "HELLO!";
El caso 1 crea una secuencia de bytes con el equivalente ASCII de "HELLO!". De igual forma, el segundo caso ubica la misma secuencia de bytes, pero además crea un puntero llamado string_ptr que apunta a la misma secuencia de caracteres.
El caso 2 equivale realmente a:
char test_array[] = "HELLO!";
Y en tiempo de ejecución:
char string_ptr = test_array; // Nombre de array tratado como puntero
o; char string_ptr = &test_array[0]; // Pone la dirección del primer // elemento del array en el puntero
Esto muestra nuevamente la equivalencia entre punteros y arrays. La primera sentencia significa "poner la dirección de test_array en string_ptr". En este contexto el nombre del array se trata como un apuntador a su primer elemento, haciendo innecesario el empleo del operador de dirección (&).
La segunda sentencia significa "obtener la dirección del primer elemento del array y ponerla en string_ptr". No hay ninguna conversión implícita a puntero, sólo la obtención de la dirección base del array.
|
La variable array_index contiene el desplazamiento, medido desde el comienzo del array, del carácter a mover, y del carácter a guardar.
Como ha sido indicado, los punteros y arrays se encuentran íntimamente relacionados. El programa anterior puede re-escribirse así:
/* Copiar la cadena HELLO! en un array vacío */ char *string_ptr = "HELLO!" ; unsigned char dest_array[7] ; unsigned char array_index ; array_index = 0 ; while(array_index < 7) { // Comprobar el final del array dest_array[array_index] = string_ptr[array_index] ; //Mover carácter-a-carácter al array destino array_index++ ; } |
Notar que quitando el '*' a string_ptr y añadiendo el par '[ ]', el puntero se convierte en un array! Sin embargo en este caso se puede copiar la cadena HELLO!, utilizando la forma *ptr++:
array_index = 0 ; while(array_index < 7) { // Comprobar el final del array dest_array[array_index] = *string_ptr++ ; //Mover carácter-a-carácter al array destino }
La sentencia "c2 = *ptr++", no significa "incrementar el valor apuntado por ptr, y asignarlo a c2", sino "asignar a c2 el valor apuntado por ptr, e incrementar ptr para que apunte al siguiente char".
Para resumir
Crear un puntero a char que todavía no apunta a ningún lugar:
char *x_ptr ;
Crear un puntero a una variable C:
char x ; char *x_ptr = &x ;
Crear un array no inicializado:
unsigned char x_arr[10] ;
Crear e inicializar un array:
unsigned char x_arr[] = { 0,1,2,3 } ;
Crear un array de caracteres o cadena:
char x_arr[] = "HELLO" ;
Crear un puntero a cadena:
char *string_ptr = "HELLO" };
Crear un puntero a un array:
char x_arr[] = "HELLO" ; char *x_ptr = x_arr ;