ClubEnsayos.com - Ensayos de Calidad, Tareas y Monografias
Buscar

Apuntadores Y Ejemplos

Kely311022 de Noviembre de 2014

3.994 Palabras (16 Páginas)391 Visitas

Página 1 de 16

Introducción

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++.

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++.

1. Definici´on de apuntador

Cuando se declara una variable, el compilador reserva un espacio de memoria para ella y asocia el nombre de ´esta a la dirección de memoria desde donde comienzan los datos de esa variable. Las direcciones de memoria se suelen describir como nu´meros en hexadecimal.

Un apuntador es una variable cuyo valor es la dirección de memoria de otra variable. Se dice que un apuntador “apunta” a la variable cuyo valor se almacena a partir de la dirección de memoria que contiene el apuntador. Por ejemplo, si un apuntador p almacena la dirección de una variable x, se dice que “p apunta a x ”.

2. Referenciación

La referenciación es la obtención de la dirección de una variable. En C y C++ esto se hace a trav´es del operador ‘&’, aplicado a la variable a la cual se desea saber su dirección. N´otese que se trata de un operador unario. Ejemplo:

int x = 25;

Código C y C++

cout << "La dirección de x es: " << &x << endl;

Este código imprime un valor del estilo “0x4fffd34”. Este valor puede variar durante cada ejecución del programa, debido a que el programa puede reservar distintos espacios de memoria durante cada ejecución.

3. Operaciones Básicas de Apuntadores

#define NULO ((void *)0)

void main()

{

int i=5, j; // Datos

int *p=NULO, *q=NULO; // Apuntadores

printf("\ni=%d, p=%p, q=%p", i, p, q);

p = q = &i; // Apuntar al dato

*p = 7; // ..afectar dato (indirección)

printf("\ni=%d, p=%p, q=%p", i, p, q);

if ( p == q ) // Son iguales?

printf("\np es igual a q");

++*p; // incrementa dato, lee dato

printf("\ni=%d",i); // i=8

j = *q++; // lee dato, incrementa dirección

printf("\nj=%d, p=%p, q=%p", j, p, q); // j=?

if ( p != q ) // Diferentes?

printf("\np es diferente a q");

if ( q > p ) // Cuál es mayor?

printf("\nq es mayor que p");

}

4. Declaraci´on de apuntadores

Para declarar un apuntador se especifica el tipo de dato al que apunta, el operador ‘*’, y el nombre del apuntador. La sintaxis es la siguiente:

<tipo de dato apuntado> *<indentificador del apuntador>

A continuación se muestran varios ejemplos:

Codigo C y C++

int *ptr1; // Apuntador a un dato de tipo entero (int)

char *cad1, *cad2; // Dos apuntadores a datos de tipo car´acter (char)

float *ptr2; // Apuntador a un dato de tipo punto-flotante (float)

5. Asignaci´on de apuntadores

Se pueden asignar a un apuntador direcciones de variables a trav´es del operador de referenciación (‘&’) o direcciones almacenadas en otros apuntadores. Ejemplos:

int i = 5;

int *p, *q;

Codigo C y C++

p = &i; // Se le asigna a ’p’ la direcci´on de ’i’

q = p; // Se le asigna a ’q’ la direcci´on almacenada en ’p’ (la misma de ’i’)

6. Des referenciación de apuntadores

La desreferenciaci´on es la obtenci´on del valor almacenado en el espacio de memoria donde apunta un apuntador. En C y C++ esto se hace a trav´es del operador ‘*’, aplicado al apuntador que contiene la dirección del valor. Nótese que se trata de un operador unario. Ejemplos:

int x = 17, y;

int *p;

Codigo C y C++

p = &x;

cout << "El valor de x es: " << *p << endl; // Imprime 17 y = *p + 3; // A ’y’ se le asigna 20

C++ además provee el operador binario ‘->’, utilizado para obtener campos de un registro con un apunta- dor al mismo de una manera más fácil y legible. Muchos compiladores de C tambi´en soportan este operador. Ejemplo:

struct Data

{

Codigo C++

char nombre[20];

int edad;

};

Data d;

Data *pd = &d;

(*pd).edad = 23; // Acceso al campo ’edad’ utilizando el operador ’.’

pd->edad = 23; // Acceso al campo ’edad’ utilizando el operador ’->’

7. Verificaci´on de tipos en apuntadores

Al igual que el resto de las variables, los apuntadores se enlazan a tipos de datos espec´ıficos (apuntadores a variables de cierto tipo), de manera que a un apuntador solo se le pueden asignar direcciones de variables del tipo especificado en la declaración del apuntador. Ejemplo:

int *p1; float *p2; int x;

Codigo C y C++

p1 = &x; // Esto es valido

p2 = &x; // Esto no es valido (el compilador genera un error)

8. Direcciones inv´alidas y la dirección NULL

Normalmente, un apuntador inicializado adecuadamente apunta a alguna posición espec´ıfica de la memo- ria. Sin embargo, algunas veces es posible que un apuntador no contenga una dirección valida, en cuyo caso es incorrecto desreferenciarlo (obtener el valor al que apunta) porque el programa tendr´a un comportamiento impredecible y probablemente err´oneo, aunque es posible que funcione bien. Un apuntador puede contener una dirección invalida debido a dos razones:

1. Cuando un apuntador se declara, al igual que cualquier otra variable, el mismo posee un valor cualquiera que no se puede conocer con antelación, hasta que se inicialice con algu´n valor (dirección). Ejemplo:

Codigo C y C++

float *p;

cout << "El valor apuntado por p es: " << *p << endl; // Incorrecto

*p = 3.5; // Incorrecto

2. Despu´es de que un apuntador ha sido inicializado, la dirección que posee puede dejar de ser v´alida si se libera la memoria reservada en esa dirección, ya sea porque la variable asociada termina su ambito o porque ese espacio de memoria fue reservado dinámicamente y luego se liber´o1 . Ejemplo:

1 La asignaci´on din´amica de memoria se explica en la seccion 13

int *p, y; void func()

{

int x = 40;

p = &x;

y = *p; // Correcto

*p = 23; // Correcto

}

void main()

{

func();

y = *p; // Incorrecto

*p = 25; // Incorrecto

}

Si se intenta desreferenciar un apuntador que contiene una dirección invalida pueden ocurrir cosas como las siguientes:

Se obtiene un valor incorrecto en una o más variables debido a que no fue debidamente inicializada la zona de memoria que se accede a trav´es de la direcci´on en cuestio´n. Esto puede ocasionar que el programa genere resultados incorrectos.

Si casualmente la dirección es la misma de otra variable utilizada en el programa, o est´a dentro del rango de direcciones de una zona de memoria utilizada, existe el riesgo de sobreescribir datos de otras variables.

Existe la posibilidad de que la dirección est´e fuera de la zona de memoria utilizada para almacenar datos y mas bien est´e, por ejemplo, en la zona donde se almacenan las instrucciones del programa. Al intentar escribir en dicha zona, fácilmente puede ocurrir que el programa genere un error de ejecución y el sistema operativo lo detenga, o que el programa no responda y deje al sistema operativo inestable.

En muchos casos el sistema operativo detecta el acceso inadecuado a una dirección de memoria, en cuyo caso detiene abruptamente el programa.

Cuando no se desea que un apuntador apunte a algo, se le suele asignar el valor NULL, en cuyo caso se dice que el apuntador es nulo (no apunta a nada). NULL es una macro t´ıpicamente definida

...

Descargar como (para miembros actualizados) txt (20 Kb)
Leer 15 páginas más »
Disponible sólo en Clubensayos.com