Académique Documents
Professionnel Documents
Culture Documents
Un dato primitivo (o simplemente primitivo) es cualquier dato que puede ser le�do o
escrito en la memoria del ordenador usando un acceso de memoria (por ejemplo, tanto
un byte como una palabra son primitivas).
A un byte offset, tal como el valor ASCII hexadecimal de un car�cter (por ejemplo,
X'29') se puede utilizar para apuntar a un valor alternativo entero (o �ndice) en
una matriz (por ejemplo, X'01'). De esta manera, los caracteres pueden ser
traducidos de manera muy eficiente partiendo de datos brutos, a un �ndice
secuencial utilizable y luego a una direcci�n absoluta sin utilizar una tabla de
b�squeda.
Uso en tablas de control
Por lo general, las tablas de control, que se utilizan para controlar el flujo del
programa hacen un amplio uso de punteros. Los punteros, normalmente integrados en
una entrada de la tabla, pueden, por ejemplo, ser usados para sostener los puntos
de entrada a subrutinas a ser ejecutados, basado en ciertas condiciones definidas
en la misma entrada de la tabla. Sin embargo, los indicadores pueden ser simples
�ndices de otros cuadros distintos, pero relacionados, que comprenden un conjunto
de las direcciones reales o direcciones propias (dependiendo de las construcciones
disponibles del lenguaje de programaci�n). Tambi�n pueden utilizarse para se�alar
(retrocediendo) a entradas de la tabla anterior (como en el procesamiento de bucle)
o avanzar para pasar algunas entradas de la tabla (como en un switch o salida
"prematura" de un bucle). A este �ltimo efecto, el "puntero" simplemente puede ser
el n�mero de entrada de la tabla en s� y puede pasar a ser una direcci�n actual
usando aritm�tica simple.
Or�genes en la arquitectura de ordenador
Los punteros son una abstracci�n muy delgada en la parte superior de las
capacidades de direccionamiento ofrecidas por la mayor�a de las arquitecturas
modernas. En el esquema m�s simple, una direcci�n, o un �ndice num�rico, se asigna
a cada unidad de memoria en el sistema, donde la unidad es t�picamente un byte o
una palabra - dependiendo de si la arquitectura es direccionable por byte o
direccionable por palabra - transformando eficazmente toda la memoria en una matriz
muy grande. Entonces, si tenemos una direcci�n, el sistema provee una operaci�n
para recuperar el valor almacenado en la unidad de memoria en esa direcci�n (por lo
general la utilizaci�n de registros de prop�sito general de la m�quina).
Por otra parte, algunos sistemas tienen m�s unidades de memoria que no son
direcciones. En este caso, se emplea un esquema m�s complejo, tal como la
segmentaci�n de memoria o de paginaci�n a utilizar diferentes partes de la memoria
en diferentes momentos. Las �ltimas encarnaciones de la arquitectura x86 soportan
hasta 36 bits de direcciones de memoria f�sica, que fueron asignadas al espacio de
direcciones lineal de 32 bits usando un mecanismo PAE de paginaci�n. As�, solo el
1/16 de la posible memoria total puede ser accedida a la vez. Otro ejemplo de la
misma familia de ordenadores estaba el modo protegido de 16 bits del procesador
80286, que, sin embargo, soportaba solamente 16 MiB de memoria f�sica, pudiendo
acceso a un m�ximo de 1 GiB de memoria virtual, pero la combinaci�n de direcci�n de
16 bits y el segmento de registros hizo acceder a m�s de 64 KiB en una estructura
de datos engorroso. Algunas restricciones de la aritm�tica del puntero ANSI
pudieron haberse debido a los modelos de memoria segmentadas de esta familia de
procesadores. [cita requerida]
Los punteros son compatibles directamente sin restricciones en lenguajes como PL/1,
C, C++, Pascal, y la mayor�a de los lenguajes ensambladores. Se utilizan
principalmente para la construcci�n de referencias, que a su vez son fundamentales
para la construcci�n de casi todas las estructuras de datos, as� como para pasar
datos entre las diversas partes de un programa.
Los punteros se utilizan para pasar par�metros por referencia. Esto es �til si el
programador quiere modificaciones de una funci�n a un par�metro sea visible para
llamador de la funci�n de la funci�n. Esto tambi�n es �til para devolver varios
valores de una funci�n.
int * ptr;
Esto declara ptr como el identificador de un objeto, de la siguiente forma:
Esto usualmente se manifiesta de forma m�s sucinta como 'ptr es un puntero a int.'
En cualquier caso, una vez que un puntero ha sido declarado, el siguiente paso
l�gico es que se apunte a algo:
int a = 5;
int *ptr = NULL;
ptr = &a;
*ptr = 8;
int a = 5;
int *ptr = NULL;
Direcci�n Contenido
0x8130 0x00000005
0x8134 0x00000000
ptr = &a;
produce los siguientes valores de memoria:
Direcci�n Contenido
0x8130 0x00000005
0x8134 0x00008130
*ptr = 8;
Direcci�n Contenido
0x8130 0x00000008
0x8134 0x00008130
Esto asigna un bloque de cinco enteros y nombres de la matriz de bloques, que act�a
como un puntero al bloque. Otro uso com�n de los punteros es para que apunte a la
memoria asignada din�micamente desde malloc que devuelve un bloque consecutivo de
memoria de no menos que el tama�o solicitado que se puede utilizar como una matriz.
0 1 2 3
1000 2 0 0 0
1004 4 0 0 0
1008 3 0 0 0
100C 1 0 0 0
1010 5 0 0 0
struct link {
void *datos; /* datos de este v�nculo */
struct link *proximo; /* siguiente enlace; EMPTY_LIST si no hay ninguno */
};
Nil es la lista vac�a y Cons a (Link a) es una cons cell de un tipo a con otro
enlace tambi�n de tipo a.
Los punteros se pueden usar para pasar variables por su direcci�n, lo que permite
cambiar su valor. A modo de ejemplo, se considera el siguiente c�digo en C:
#include <stdio.h>
/* se puede cambiar una copia de int n dentro de la funci�n sin afectar el c�digo
de llamada */
void passbyvalue(int n) {
n = 12;
}
int main(void) {
int x = 3;
return 0;
}
A mediados de los a�os 80, usar la BIOS para acceder a las capacidades de video de
PC era lento. Las aplicaciones que se encontraban en pantalla intensiva normalmente
se utiliza para acceder a la memoria de v�deo CGA directamente mediante colada las
constantes hexadecimales 0xb8000 a un puntero a un array de 80 valores int de 16
bits sin signo. Cada valor consist�a en un c�digo ASCII en el byte bajo y un color
en el byte alto. Por lo tanto, para poner la letra 'A' en la l�nea 5, columna 2
blanco sobre azul luminoso, uno podr�a escribir c�digo como el siguiente:
#define VID ((unsigned short (*)[80])0xB8000)
void foo() {
VID[4][1] = 0x1F00 | 'A';
}
Por ejemplo, en C
int *money;
char *bags;
money ser�a un puntero entero y bags ser�a un puntero char. Lo siguiente dar�a una
advertencia del compilador de "asignaci�n desde un tipo de puntero" bajo GCC
bags = money;
porque money y bags fueron declarados con diferentes tipos. Para suprimir la
advertencia del compilador, debe quedar expl�cita de que realmente se desea hacer
la cesi�n por encasillamiento.
que dice emitir el puntero entero de money a un puntero char y asignarlo a bags.
Aunque por lo general sea imposible determinar en tiempo de compilaci�n que arroja
son seguros, algunos lenguajes almacenan el tipo de informaci�n en tiempo de
ejecuci�n que puede ser utilizado para confirmar que estos peligrosos moldes son
v�lidos en tiempo de ejecuci�n. Otros lenguajes simplemente aceptan una
aproximaci�n conservadora de moldes seguros, o ninguno en absoluto.
Haciendo m�s seguros a los punteros
El texto que sigue es una traducci�n defectuosa.
Si quieres colaborar con Wikipedia, busca el art�culo original y mejora esta
traducci�n.
Copia y pega el siguiente c�digo en la p�gina de discusi�n del autor: {{subst:Aviso
mal traducido|Puntero (inform�tica)}} ~~~~
Como un puntero permite que un programa intente acceder a un objeto que puede no
estar definido, dichos punteros pueden ser el origen de una variedad de errores de
programaci�n. Sin embargo, la utilidad de los punteros es tan grande que puede ser
dif�cil realizar tareas de programaci�n sin ellos. En consecuencia, muchos
lenguajes han creado construcciones dise�adas para proporcionar algunas de las
caracter�sticas �tiles de los punteros sin algunas de sus trampas, tambi�n
denominadas algunas veces peligros de punteros. En este contexto, los punteros que
se dirigen directamente a la memoria (como se usa en este art�culo) se conocen como
punteros crudos o sin procesar, en contraste con punteros inteligentes u otras
variantes.
Uno de los mayores problemas con los punteros es que al poderse manipular
directamente como un n�mero, se pueden hacer que este apunte a direcciones no
utilizadas o a datos que se est� utilizando para otros fines. Muchos lenguajes,
incluyendo lenguajes de programaci�n funcionales y los �ltimos lenguajes
imperativos como Java, reemplazan los punteros con un tipo m�s opaco de referencia,
t�picamente referido simplemente como referencia, que solo puede ser usado para
referirse a los objetos y no manipula a los n�meros, previniendo este tipo de
error. La indexaci�n de una matriz se trata como un caso especial.
Algunos lenguajes, como C++, soportan punteros inteligentes, que utilizan una forma
simple de conteo de referencias con el fin de ayudar a la asignaci�n de un registro
de la memoria din�mica, adem�s de actuar como referencia. En la ausencia de ciclos
de referencia, donde un objeto se auto refiere indirectamente mediante una
secuencia de punteros inteligentes, �stos eliminan la posibilidad de punteros
colgantes y p�rdidas de memoria. Las cadenas en Delphi soportan, de forma nativa,
recuento de referencias.
Puntero nulo
Un puntero nulo tiene un valor reservado para indicar que el puntero no se refiere
a un objeto v�lido. Los punteros nulos se utilizan habitualmente para representar
las condiciones tales como el final de una lista de longitud desconocida o el
fracaso para llevar a cabo alg�n tipo de acci�n, lo que el uso de punteros nulos se
puede comparar con los tipos que aceptan valores NULL y el valor de nada en un tipo
de opci�n.
En C, dos punteros nulos de cualquier tipo est�n garantidos para comparar iguales
tipo de datos10? El macro NULL es una implementaci�n definida por una constante de
puntero NULL,6? que en C99 se puede expresar portablemente como un valor entero 0
convertido impl�cita o expl�citamente al tipo void*.11?
Puntero base
struct element
{
struct element * next;
int value;
};
Puntero salvaje
int func(void)
{
char *p1 = malloc(sizeof(char)); /* (valor (indefinido) de alg�n lugar del
mont�n */
char *p2; /* puntero salvaje (sin inicializar) */
*p1 = 'a'; /* Esto est� bien, asumiendo que malloc() no haya devuelto
NULL. */
*p2 = 'b'; /* As� se invoca un comportamiento indefinido */
}
Las estructuras de datos reservan segmentos en memoria separados para cada miembro,
esto significa que cada miembro tiene su propia direcci�n en memoria (su propio
puntero).
1 1 4 Bytes.
+-----+-----+---------+
| A | B | C | Miembros.
+-----+-----+---------+
0x1 0x2 0x3 Direcci�n.
^
|
Puntero base de la estructura completa.
Como se puede ver, existen 3 m�todos de tipo num�rico en memoria llamados "A","B" y
"C", los dos primeros m�todos (A y B) son de tipo Byte y tienen reservado 1 byte
cada uno en distintos segmentos en la memoria, por lo que tienen diferentes
direcciones (0x01 y 0x02 en su respectivo orden).
Por ejemplo:
4 Bytes.
+-----------+
| A B C | Miembros.
+-----------+
0x1 Direcci�n.
Los miembros "A" y "C" solo pueden contener valores entre 0 y 255 (Tipo Byte), el
miembro "B" puede tener valores entre 0 y 4.294.967.295 (Tipo Entero), si el
miembro "A" cambia su valor a 13, tambi�n lo hacen los miembros "B" y "C" (A,B y C
son igual a 13), si el miembro "B" cambia su valor a 4000, los miembros "A" y "C"
se quedan �nicamente en 160 ya que tratan de traducir el valor 4000 a byte (A y C
son igual a 160, B = 4000), el tama�o total de la uni�n es de 4 bytes debido a que
los miembros comparten la misma memoria (la uni�n pesa lo mismo que su miembro con
mayor reserva de memoria).
Matrices
Las matrices son casi igual que las estructuras, reservan memoria para cada matriz,
la direcci�n en memoria de cada miembro es consecutiva a la suma de sus anteriores,
mas sus tama�os y la direcci�n de la matriz total es igual a la del primer miembro,
la �nica diferencia entre una matriz y una estructura es que cada matriz tiene el
mismo tipo de dato (los miembros de una estructura pueden ser de distintos tipos).
4 4 4 Bytes.
+-----+-----+-----+
| 0 | 1 | 2 | Identificador.
+-----+-----+-----+
0x1 0x5 0x9 Direcci�n.
Como se puede apreciar, cada miembro tiene una direcci�n en memoria con 4 bytes de
diferencia entre s�. El puntero base de la matriz entera es la direcci�n de su
primer matriz (Matriz@ = Matriz[0]@).
Soporte en lenguajes de programaci�n
Ada
Ada es un lenguaje fuertemente tipado en el cual todos los punteros son tipados y
solamente se permiten conversiones de tipos de seguros. Todos los indicadores est�n
por defecto inicializado en null, y cualquier intento de acceder a la informaci�n a
trav�s de un puntero a null provoca una excepci�n. En Ada, los punteros se llaman
tipos de acceso. Ada-83 no permit�a aritm�tica en tipos de acceso (aunque los
distintos compiladores la suministren como una funcionalidad fuera del patr�n),
pero Ada-95 soporta tipos aritm�ticos en tipos de acceso seguro por el paquete
System.Storage_Elements.
BASIC
Varias versiones antiguas de BASIC para la plataforma Windows ten�an soporte para
STRPTR() para devolver la direcci�n de una cadena, y para VARPTR() para devolver la
direcci�n de una variable. Visual Basic 5 tambi�n ten�a soporte para OBJPTR() para
devolver la direcci�n de una interfaz de objeto, y para un operador ADDRESSOF para
devolver la direcci�n de una funci�n. Los tipos de todos estos son n�meros enteros,
pero sus valores son equivalentes a estos valores por tipos de puntero.
Sin embargo, dialectos m�s recientes de BASIC, como FreeBASIC o BlitzMax, tienen
implementaciones de puntero exhaustivas. En FreeBASIC, la aritm�tica en punteros
ANY (equivalente al void* de C) son tratados como si el puntero ANY fuera un ancho
de bytes. A diferencia de C, los punteros ANY no pueden ser desreferenciados.
Adem�s, la conversi�n entre ANY y cualquier otro tipo de punteros no generar�
ninguna advertencia.
En C y C++ los punteros son variables que almacenan direcciones y pueden ser null.
Cada puntero tiene un tipo que apunta, pero el programador puede convertir
libremente entre tipos de puntero (pero no entre un puntero a funci�n y no la
funci�n de tipo de puntero). Un tipo de puntero especial llamado el "vac�o puntero"
permite que apunta a cualquier tipo de variable (no funci�n), pero es limitada por
el hecho de que no se puede eliminar las referencias de forma directa. La direcci�n
en s� a veces puede ser manipulada directamente mediante colada un puntero hacia y
desde un tipo entero de tama�o suficiente, aunque los resultados se han definido
por la implementaci�n y de hecho pueden causar un comportamiento indefinido;
mientras que los est�ndares anteriores a C no tengan un tipo entero que garantice
que sea lo suficientemente grande, C99 especifica el nombre definido uintptr_?
typedef en < stdint.h>, pero una aplicaci�n no tiene por qu� proporcionarla.
int x = 4;
void* q = &x;
int* p = q; /* void* convierte impl�citamente a int*: v�lido en C, pero no en C++
*/
int i = *p;
int j = *(int*)q; /* cuando se desreferencia en l�nea, no hay conversi�n impl�cita
*/
int x = 4;
void* q = &x;
// int* p = q; Esto falla en C++: no hay conversi�n impl�cita de void*
int* a = (int*)q; // cast estilo C
int* b = static_cast<int*>(q); // C++ cast
En el lenguaje de programaci�n C#, los punteros son compatibles solo bajo ciertas
condiciones: cualquier bloque de c�digo que incluya punteros debe ser marcada con
la palabra clave unsafe. Generalmente, tales bloques requieren permisos de
seguridad superiores a c�digo pointerless que se le permitiera correr. La sintaxis
es esencialmente la misma que en C++, y la direcci�n apuntada se puede gestionar
tanto memoria administrada como no administrado. Sin embargo, los punteros a
memoria administrada (cualquier puntero a un objeto administrado) deben ser
declarado usando la palabra clave fixed, lo que evita que la recolector de basura
del movimiento del objeto apuntado, como parte de la gesti�n de memoria mientras el
puntero est� a su alcance, lo que mantiene v�lida la direcci�n del puntero.
El lenguaje PL/I proporciona soporte completo para punteros a todos los tipos de
datos (incluyendo punteros a estructuras), recursividad, multitarea, manejo de
cadenas, y amplias funciones incorporadas. PL/I era un salto absoluto hacia
adelante en comparaci�n con los lenguajes de programaci�n de su tiempo.[cita
requerida]
D
type real_list_t
real :: sample_data(100)
type (real_list_t), pointer :: next => null ()
end type
Los punteros son fuertemente implementados como en Pascal, al igual que los
par�metros VAR en las llamadas a procedimiento. Modula-2 es m�s inflexible incluso
que Pascal, con al menos v�as de escape del sistema de tipos. Algunas de las
variantes de Modula-2 (como Modula-3) incluyen recolecci�n de basura.
Oberon
Al igual que Modula-2, los punteros est�n disponibles. A�n hay un menor n�mero de
maneras de evadir el sistema de tipos y as� Oberon y sus variantes son a�n m�s
seguros con respecto a los punteros de Modula-2 o sus variantes. Al igual que con
Modula-3, la recolecci�n de basura es una parte de la especificaci�n del lenguaje.
Pascal
A diferencia de muchas lenguajes que cuentan con punteros, el est�ndar ISO Pascal
solo permite punteros para hacer referencia a las variables creadas din�micamente
que son an�nimas y no les permiten referenciar est�ndares est�ticos o variables
locales.21? No tiene aritm�tica de punteros. Los punteros deben tambi�n de tener un
tipo asociado, y un puntero a un tipo no es compatible con un puntero a otro tipo
(por ejemplo, un puntero a un char no es compatible con un puntero a un entero).
Esto ayuda a eliminar los problemas de seguridad inherentes tipo con otras
implementaciones de puntero, especialmente los utilizados para PL/I o C. Tambi�n
elimina algunos riesgos causados por punteros colgados, pero la capacidad de dejar
de lado el espacio de forma din�mica se hace referencia mediante el procedimiento
est�ndar dispose (que tiene el mismo efecto que la funci�n de la liber�a free
encontrada en C) significa que el riesgo de punteros no se ha eliminado por
completo.22?