USO DE PUNTEROS Y ARRAYS EN C51
Los punteros constituyen paradójicamente uno de los puntos fuertes y a la vez puntos débiles del lenguaje C. El uso, o más apropiadamente el abuso de los punteros es la razón por la que algunos consideran peligroso al lenguaje C.
Para un programador en ensamblador, los punteros de C equivalen al direccionamiento indirecto que realizan las siguientes instrucciones del 8051:
MOV R0,#40 MOV A,@RO ; Lectura de RAM interna MOV R0,#40 MOVX A,@RO ; Lectura de RAM externa paginada MOVX A,@DPTR ; Lectura de RAM externa CLR A MOV DPTR,#0040 MOVC A,@A+DPTR ; Lectura de memoria de código
En todos los casos anteriores el dato se encuentra en una posición de memoria cuya dirección se encuentra en los registros situados a la derecha de '@'.
El puntero es el equivalente en C al acceso indirecto del ensamblador. Puede definirse el puntero como una variable que contiene la dirección de otra variable o constante.
Se define un puntero a unsigned char así:
unsigned char *puc;
Notar que el prefijo *, indica que el dato residente en puc es una dirección y no un valor.
En todos los ejemplos anteriores en ensamblador se utilizan dos operaciones:
En C se utiliza el mismo procedimiento, aunque se debe definir el puntero, mientras que en ensamblador se utilizan los registros del 8051.
/* 1 - Definir un puntero para almacenar la dirección de otra variable */ unsigned char *puc ; /* 2 - Poner en el puntero la dirección de la variable a la que se */ /* desea acceder indirectamente */ puc = &variable_c ; /* 3 - Poner el dato '0xff' indirectamente en variable_c */ *puc = 0xff ;
Los pasos anteriores hacen:
La posibilidad de asignar valores de forma directa, x = valor, o de forma indirecta, x = *y_ptr, es extremadamente útil. Veamos un ejemplo en C:
/* Demostración del uso de Punteros */ char c1; // 1 - Define la variable c1, de tipo char char *pc; // 2 - Define un puntero a variable de tipo char que todavía no apunta a ningún lugar main() { c1 = 0xff; // 3 - Asigna (directamente) el valor 0xff a c1 pc = &c1; // 4 - Asigna a pc la dirección de c1 *pc = 0xff; // 5 - Asigna (indirectamente) el valor 0xff a c1 }
Nota: La línea 4 hace que pc apunte a la variable c1. Una forma alternativa de hacer esto es:
/* Demostración del uso de Punteros */ char c1; // 1 - Define la variable c1, de tipo char char *pc = &c1; // 2 - Define un puntero a variable de tipo char que apunta a la variable c1 main() { c1 = 0xff; // 3 - Asigna (directamente) el valor 0xff a c1 *pc = 0xff; // 5 - Asigna (indirectamente) el valor 0xff a c1 } |
Los punteros con el prefijo *, pueden utilizarse igual que las variables normales. La sentencia:
x = y + 3 ;
puede realizarse igualmente con punteros:
char x, y ; char *x_ptr = &x ; char *y_ptr = &y ; *x_ptr = *y_ptr + 3 ;o:
x = y * 25 ; *x_ptr = *y_ptr * 25 ;
La cosa más importante a recordar con punteros es que
*ptr = var ;
significa "asignar el valor var a la variable apuntada por ptr", mientras que
ptr = &var ;
significa "asignar a ptr la dirección de la variable var".