Está en la página 1de 15

INTRODUCCIÓN

En ciencias de la computación, un puntero es un objeto del lenguaje de


programación, cuyo valor se refiere a (o "apunta a") otro valor almacenado en otra
parte de la memoria del ordenador utilizando su dirección. Un puntero referencia a
una ubicación en memoria, y a la obtención del valor almacenado en esa
ubicación se la conoce como desreferenciación del puntero. A modo de analogía,
un número de página en el índice de un libro podría considerarse un puntero a la
página correspondiente; desreferenciar un puntero sería como ir a la página con el
número de página especificada en el índice.

Los apuntadores en C y C++ son una herramienta muy potente de programación


que suele causar mucha confusión en los estudiantes que la están aprendiendo.
Además, cuando los programadores cometen un error en su utilización, puede ser
muy difícil encontrar el error, por lo cual es importante saber utilizarlos muy bien.
El uso de apuntadores en C y C++ es muy importante debido a que permite hacer
los programas más eficientes y más flexibles. En en este artículo se explica de una
manera sencilla y breve todo lo referente a la utilización de apuntadores tanto en C
como en C++.
¿Qué es un apuntador?

Los Punteros o Apuntadores, son variables que contienen la dirección de otra


variable.
Los usos principales, que tienen, los punteros, son los siguientes:
Nos ayuda, para que una función devuelva más de un valor. Por ejemplo,
una función que devuelva un vector de enteros, en dicha función
mandamos la dirección del primer elemento a la función principal, y a partir
de ella, imprimimos todos los valores contenidos en el vector.
Mejor uso de la memoria dinámica. Esto es lo que más nos tiene cuenta, el
lector debe tener presente que, el uso de punteros, ayuda a ahorrar
memoria y por consiguiente, hace más efectivo el uso y administración de la
misma.
 
Declaración de Punteros.
La forma de declarar un apuntador, es la siguiente:
int *p;
int indica que, es un puntero hacia un entero.
* indica al compilador que esa variable, es un puntero
P Es el identificador del puntero.

Otros ejemplos:
float *q; /*apuntador hacia un flotante*/

char *z; /*puntero que contiene la dirección de una variable que guarda un
carácter */

Para referirnos a un valor a través de un apuntador, lo hacemos mediante un


proceso llamado indirección.
Por ejemplo, para mandar a impresión el valor entero, hacia el cual a punta “p”,
sería así: printf(“%d”, *p);
Los punteros, pueden ser inicializados a 0, NULL ó alguna dirección válida:
float *p1;
p1=0;
p1=NULL;

Ahora bien, para guardar la dirección de alguna variable, en un puntero se tiene &-
>Operador de Dirección.
 
P1=&a;
6.1 Representación de un apuntador

Un puntero o apuntador es una variable que contiene la dirección de memoria de


una variable dinámica donde se podrá almacenar un valor.
Cuando se declara un puntero, de igual manera que con cualquier variable, su
contenido es indefinido hasta que se le asigne un valor. Mientras esto no ocurra no
se puede decir que exista una variable referenciada, en esta situación se dice que
el puntero no está apuntado a una dirección válida. Un apuntador puede
inicializarse en NULL que corresponde a una dirección 0 o nula. NULL es una
constante simbólica definida en el archivo de cabeceras stddef.h el cual a su vez
es incluido en el archivo de cabeceras stdio.h. Al inicializar un puntero en NULL se
garantiza que el puntero no apunte a una dirección inválida, pero con esto
tampoco se define una variable referenciada.

Declaración de un Puntero
tipo [near] ¦ [far] *variable;
Ejemplo:
int *a;
float far *k;
int near *b;

En entornos de desarrollo como el Borland C++, un puntero cercano o near


pointer es una variable que se define en 2 bytes, esto se debe a que este tipo de
puntero sólo puede recibir una dirección de memoria que se encuentre en el
segmento de datos, por lo tanto sólo requiere almacenar el desplazamiento (offset)
de la dirección, el segmento de la dirección se maneje a través del registro DS.
Un puntero lejano o far pointer, emplea 4 bytes para definir una variable, la razón
de esto es que este tipo de puntero puede almacenar cualquier dirección de
memoria, por lo tanto se debe guardar en ella tanto el segmento como el
desplazamiento de la memoria.
En entornos de desarrollo que empleen Win32, como DEV-C++, Visual C++, etc,
no se distingue entre direcciones de memoria cercanas y lejanas. Así las cláusulas
near y far son ignoradas, y todos los punteros son tratados de la misma manera.
C/C++ requiere una definición para cada variable. Para definir una variable
apuntador dirección RAM que pueda contener la dirección de una variable int, se
escribe:
int *direccionRAM;
Realmente existen dos partes separadas en esta declaración. El tipo de dato de
direccionRAM es:
int *
y el identificador para la variable es
direccionRAM
El asterisco que sigue a int significa “apuntador a”. Esto es, el siguiente tipo de
dato es una variable apuntador que puede contener una dirección a un int: int *
En C/C++ una variable apuntador contiene la dirección de un tipo de dato
particular:
char *direccion_char;
char *direccion_int;
El tipo de dato de dirección char es diferente del tipo de dato de la variable
apuntador dirección int. En un programa que define un apuntador a un tipo de dato
y utiliza este para apuntar a otro tipo de dato, pueden ocurrir errores en tiempo de
ejecución y advertencias en tiempo de compilación. Una práctica de programación
pobre sería definir un apuntador de una forma y luego utilizar ´este de alguna otra
forma. Por ejemplo:
int *direccion_
int; float un_float =
98.34; direccion_int = &un_float;
6.2 precedencia de operadores de apuntadores

El lenguaje C++ incluye todos los operadores de C y agrega varios operadores


nuevos. Los operadores especifican una evaluación que se realizará en uno o más
operandos.
La precedencia de operadores especifica el orden de las operaciones en
expresiones que contienen más de un operador. La asociatividad del operador
especifica si, en una expresión que contiene varios operadores con la misma
prioridad, un operando se agrupa con el que se encuentra a la izquierda o a la
derecha. La tabla siguiente muestra la prioridad y la asociatividad de los
operadores de C++ (de mayor a menor prioridad). Los operadores que tienen el
mismo número de prioridad tienen la misma prioridad, a menos que se fuerce otra
relación explícitamente mediante paréntesis.

Prioridad y asociatividad de los operadores de C++


TABLA 1
Descripción del
Operador
operador

Precedencia de grupo 1, sin asociatividad

Resolución de ámbito ::

Precedencia de grupo 2, asociatividad de izquierda a derecha

Selección de miembro . o->


(objeto o puntero)

Subíndice de matriz []

Llamada de función ()

Incremento de postfijo ++

Decremento de postfijo --

Nombre de tipo typeid

Conversión de tipos const_cast


constante
TABLA 1
Descripción del
Operador
operador

Conversión dinámica de dynamic_cast


tipos

Conversión de tipos reinterpret_cast


reinterpretada

Conversión de tipos static_cast


estáticos

Precedencia de grupo 3, asociatividad de derecha a izquierda

Tamaño del objeto o tipo sizeof

Incremento de prefijo ++

Decremento de prefijo --

Complemento de uno ~

Not lógico [!](../cpp/logical-negation-operator-exclpt.md)

Negación unaria -

Signo más unario +

Dirección de &

Direccionamiento *
indirecto

Crear objeto nuevo

Destruir objeto delete

Cast ()

Precedencia de grupo 4, asociatividad de izquierda a derecha

Puntero a miembro . * o->*


(objetos o punteros)
TABLA 1
Descripción del
Operador
operador

Precedencia de grupo 5, asociatividad de izquierda a derecha

Multiplicación *

División /

Módulo %

Precedencia de grupo 6, asociatividad de izquierda a derecha

Suma +

Resta -

Precedencia de grupo 7, asociatividad de izquierda a derecha

Desplazamiento a la
<<
izquierda

Desplazamiento a la
>>
derecha

Precedencia de grupo 8, asociatividad de izquierda a derecha

Menor que <

Mayor que >

Menor o igual que <=

Mayor o igual que >=

Precedencia de grupo 9, asociatividad de izquierda a derecha

Igualdad ==

Desigualdad [!=](../cpp/equality-operators-equal-equal-and-exclpt-
equal.md)
TABLA 1
Descripción del
Operador
operador

Precedencia de grupo 10 de izquierda a derecha

AND bit a bit &

Precedencia de grupo 11, asociatividad de izquierda a derecha

Or exclusivo bit a bit ^

Precedencia de grupo 12, asociatividad de izquierda a derecha

Or inclusivo bit a bit |

Precedencia de grupo 13, asociatividad de izquierda a derecha

Y lógico &&

Precedencia de grupo 14, asociatividad de izquierda a derecha

O lógico ||

Precedencia de grupo 15, asociatividad de derecha a izquierda

Instrucción ?:

Precedencia de grupo 16, asociatividad de derecha a izquierda

Asignación =

Asignación de *=
multiplicación

Asignación de división /=

Asignación de módulo %=

Asignación de suma +=

Asignación de resta -=

Asignación de <<=
desplazamiento a la
TABLA 1
Descripción del
Operador
operador

izquierda

Asignación de >>=
desplazamiento a la
derecha

Asignación and bit a bit &=

Asignación or inclusivo |=
bit a bit

Asignación OR exclusiva ^=
bit a bit

Precedencia de grupo 17, asociatividad de derecha a izquierda

expresión Throw throw

Precedencia de grupo 18, asociatividad de izquierda a derecha

Coma ,
6.3 llamadas por referencia
Hay dos formas de pasar argumentos por referencia: llamado por referencia con
argumentos de referencia y llamado por referencia con argumentos de apuntador.
Los apuntadores pueden servir para pasar apuntadores a objetos de datos
grandes, evitando la sobrecarga de pasar los objetos mediante llamadas por valor.
En el caso de arrays, el nombre de estos es la localidad inicial del mismo en
memoria (el nombre del arreglo es equivalente a &nombre arreglo [0]). Veremos
los parámetros de referencia que son otra forma de pasar argumentos por
referencia.
Para indicar que el parámetro de una función se pasa por referencia colocamos un
& después del tipo del parámetro en el prototipo de la función.
Utilizamos la misma convención en el tipo del encabezado de la función. Veamos
el ejemplo de intercambio, la declaración de la función sería:
void intercambio (int &x, int &y)
{
int temp;
temp=x;
x=y;
y=temp;
}
en la llamada de la función, mencionamos la variable por nombre y esta será
pasada por referencia, por ejemplo:
intercambio(a,b)
En el cuerpo de la función llamada, la variable es mencionada por su nombre de
parámetro. Esto hará referencia a la variable original del invocador, la cual puede
ser modificada en la función llamada. El prototipo de la función debe coincidir con
su encabezado
Las referencias también pueden servir como alias de otras variables, por ejemplo:
int count=1; /* declara variable entera count */
int &cref = count; /* crea cref como alias de count */
++cref; /* incrementa count (utilizando su alias) */
las variables de referencia deben inicializarse en sus declaraciones. Una vez que
una referencia se declara como alias de otra variable todas las operaciones
realizadas sobre el alias se realizan en la variable original. El alias simplemente es
otro nombre de la variable.
6.4 utilización de apuntadores

Los apuntadores son una parte fundamental de C. Si usted no puede usar los
apuntadores apropiadamente entonces esta perdiendo la potencia y la flexibilidad
que C ofrece básicamente. El secreto para C esta en el uso de apuntadores.
C, usa los apuntadores en forma extensiva. ¿Por qué?
 Es la única forma de expresar algunos cálculos.
 Se genera código compacto y eficiente.
 Es una herramienta muy poderosa.
C, usa apuntadores explícitamente con:
 Es la única forma de expresar algunos cálculos.
 Se genera código compacto y eficiente.
 Es una herramienta muy poderosa.
C, usa apuntadores explícitamente con:
 Arreglos,
 Estructuras y
 Funciones
El uso de apuntadores en C y C++ es muy importante debido a que permite hacer
los programas más eficientes y más flexibles. En este artículo se explica de una
manera sencilla y breve todo lo referente a la utilización de apuntadores tanto en C
como en C++.
Todo lo explicado en este artículo aplica tanto para C como para C++, a menos
que se especifique un lenguaje en particular. En algunos ejemplos de código que
son aplicables a C aparecen instrucciones de entrada y salida de las librerías
estándar de C++.
CONCLUSIÓN
 los punteros son una herramienta indispensable para los sistemas embebidos. Un
sólido conocimiento de punteros y la habilidad de utilizarlos eficientemente hace la
diferencia entre un programador novato y uno experto. Ellos proporcionan soporte
para asignación de memoria dinámica y agregan otra dimensión al control de flujo
en un programa.
Los punteros tienen varios usos, incluyendo:
 Crean código eficiente y rápido
 Proporcionan asignación de memoria dinámica
 Hacen expresiones compactas y concisas
 Protegen datos pasados como parámetros a una función
 Proporcionan la capacidad de pasar estructuras de datos mediante un
puntero sin ocasionar un exceso de código conocido como “overhead”
Los punteros crean código eficiente y rápido ya que están más cerca del
hardware. Esto significa que el compilador puede traducir más fácilmente la
operación en código máquina.
Bibliografía:

 https://www.cimat.mx/~alram/cpa/pointersC.pdf
 http://agora.pucp.edu.pe/inf2170681/8.htm
 https://utch2009.files.wordpress.com/2010/04/apuntadores.pdf
 http://www.disc.ua.es/~gil/punteros.pdf
 https://docs.microsoft.com/es-es/cpp/cpp/cpp-built-in-operators-
precedence-and-associativity?view=vs-2019
 https://www.fing.edu.uy/tecnoinf/mvd/cursos/eda/material/teo/ED
A-teorico7.pdf
 http://odin.fi-b.unam.mx/salac/practicasEDAA/eda1_p2.pdf
 https://codingornot.com/01-apuntadores-la-memoria-de-tu-
computadora
 http://dignal.com/importancia-de-utilizar-punteros-en-lenguaje-c/

También podría gustarte