Resumen de Punteros

22

Click here to load reader

Transcript of Resumen de Punteros

Page 1: Resumen de Punteros

Republica Bolivariana de Venezuela

Ministerio de Educación y Deporte

Colegio Universitario Francisco de Miranda

Programación

Trabajo de Programación: Punteros

Integrantes:

Contreras Jonathan

Zerpa Gabriel

Caracas

Page 2: Resumen de Punteros

Introducción

Como vimos anteriormente, las estructuras de datos son aquellas cuya ocupación de

memoria puede aumentar o disminuir durante el tiempo de ejecución. Mediante los

punteros, tema que estudiaremos a continuación, podemos crear estructuras de datos

dinámicas que tienen capacidad de variar en tamaño y ocupar tanta memoria como

realmente requieran. Estas estructuras son llamadas punteros.

Desarrollo

Page 3: Resumen de Punteros

Punteros

Un puntero es una variable que contiene una dirección de memoria, y utilizando

punteros su programa puede realizar muchas tareas que no sería posible utilizando tipos

de datos estándar .En este capítulo se estudiarán los diferentes aspectos de los punteros

Cada vez que se declara una variable C, el compilador establece un área de memoria

para almacenar el contenido de la variable. Cuando se declara una variable i n t (entera),

por ejemplo, el compilador asignados bytes de memoria. El espacio para esa variable se

sitúa en una posición específica de la memoria, conocida como dirección de memoria.

Cuando se referencia (se hace uso) al valor de la variable, el compilador de C accede

automáticamente a la dirección de memoria donde se almacena el entero. Se puede

ganar en eficacia en el acceso a esta dirección de memoria utilizando un puntero.

Declaración de punteros

Al igual que cualquier variable, las variables punteros han de ser declaradas antes de

utilizarlas. La declaración de una variable puntero debe indicar al compilador el tipo de

dato al que apunta el puntero para ello se hace preceder a su nombre con un asterisco

(*), mediante el siguiente formato:

<tipo de dato apuntado> *<identificador de puntero>

Un operador * en una declaración indica que la variable declarada almacenará una

dirección de un tipo de dato especificado. La variable ptrl almacenará la dirección de un

entero, la variable ptr2 almacenará la dirección de un dato tipo long, etc.

Page 4: Resumen de Punteros

Siempre que aparezca un asterisco ( * ) en una definición de una variable, ésta es una

variable puntero.

Inicialización* (iniciación) de punteros

AI igual que otras variables, C no inicializa los punteros cuando se declaran y es preciso

inicializarlos antes de su uso. La inicialización de un puntero proporciona a ese puntero

la dirección del dato correspondiente. Después de la inicialización, se puede utilizar el

puntero para referenciar los datos direccionados. Para asignar una dirección de memoria

a un puntero se utiliza el operador de referencia (&). Así, por ejemplo, & valor

Significa «la dirección de valor». Por consiguiente, el método de inicialización

(iniciación), también denominado estático, requiere:

Asignar memoria (estáticamente) definiendo una variable y a continuación hacer que el

puntero apunte al valor de la variable.

int i; / * define una variable i * /

int *p; / * define un puntero a un entero p*/

p = &i; /* asigna la dirección de i a p * /

Asignar un valor a la dirección de memoria.

*p = 50;

Cuando ya se ha definido un puntero, el asterisco delante de la variable puntero indica el

contenido de en de la memoria apuntada por el puntero y será del tipo dado. Este tipo de

inicialización es estática, ya que la asignación de memoria utilizada para almacenar el

valor es fijo y no puede desaparecer. Una vez que la variable se define, el compilador

establece suficiente memoria para almacenar un valor del tipo de dato dado. La

memoria permanece reservada para esta variable y no se puede utilizar para otra cosa

Page 5: Resumen de Punteros

durante la ejecución del programa. En otras palabras, no se puede liberar la memoria

reservada para una variable. El puntero a esa variable se puede cambiar, pero

permanecerá la cantidad de memoria reservada.

El operador devuelve la dirección de la variable a la cual se aplica,

Es un error asignar un valor, a un contenido de una variable puntero si previamente no

se ha inicializado con la dirección de una variable, o bien se le ha asignado

dinámicamente memoria. Por ejemplo:

float* px; / * puntero a float * /

*px = 23.5; / * error, px no contiene dirección * /

Indirección de punteros

Cuando ya se ha definido un puntero, el asterisco delante de la variable puntero indica el

contenido de en de la memoria apuntada por el puntero y será del tipo dado. Este tipo de

inicialización es estática, ya que la asignación de memoria utilizada para almacenar el

valor es fijo y no puede desaparecer. Una vez que la variable se define, el compilador

establece suficiente memoria para almacenar un valor del tipo de dato dado. La

memoria permanece reservada para esta variable y no se puede utilizar para otra cosa

durante la ejecución del programa. En otras palabras, no se puede liberar la memoria

reservada para una variable. El puntero a esa variable se puede cambiar, pero

permanecerá la cantidad de memoria reservada.

El operador devuelve la dirección de la variable a la cual se aplica,

Es un error asignar un valor, a un contenido de una variable puntero si previamente no

se ha inicializado con la dirección de una variable, o bien se le ha asignado

dinámicamente memoria. Por ejemplo:

float* px; / * puntero a float * /

Page 6: Resumen de Punteros

*px = 23.5; / * error, px no contiene dirección * /

Punteros y verificación de tipos

Los punteros se enlazan a tipos de datos específicos, de modo que C verificará si se

asigna la dirección de un tipo de dato al tipo correcto de puntero. Así, por ejemplo, si se

define un puntero a float, no se le puede asignar la dirección de un carácter o un entero.

Por ejemplo, este segmento de código no funcionará:

float *fp;

char c;

fp = &c; / * no es válido * /

C no permite la asignación de la dirección de c a f p, ya que f p es una variable puntero

que apunta a datos de tipo real, float.

C requiere que las variables puntero diseccionen realmente variables del mismo tipo de

dato que está ligado a los punteros en sus declaraciones.

Punteros null y void

Normalmente un puntero inicializado adecuadamente apunta a alguna posición

específica de la memoria .Sin embargo, un puntero no inicializado, como cualquier

variable, tiene un valor aleatorio hasta que se inicial iza el puntero. En consecuencia,

será preciso asegurarse que las variables puntero utilicen direcciones de memoria válida.

Existen dos tipos de punteros especiales muy utilizados en el tratamiento de sus

programas: los punteros void y null (nulo).

Un puntero nulo no apunta a ninguna parte -dato válido- en particular, es decir, «un

puntero nulo no direcciona ningún dato válido en memoria». Un puntero nulo se utiliza

para proporcionar a un programa un medio de conocer cuando una variable puntero no

Page 7: Resumen de Punteros

direcciona a un dato válido. Para declarar un puntero nulo se utiliza la macro NULL,

definida en los archivos de cabecera STDEF . H, STDIO. H,STDLIB. H y STRING. H.

Se debe incluir uno o más de estos archivos de cabecera antes de que se pueda utilizar la

macro NULL. Ahora bien, se puede definir NULL en la parte superior de su programa

(o en un archivo de cabecera personal) con la línea:

Forma de declarar un puntero nulo es asignar un valor

de O. Por ejemplo,

int *ptr = (int * ) O; / * ptr es un puntero nulo * /

Nunca se utiliza un puntero nulo para referenciar un valor. Como antes se ha

comentado, los punteros nulos se utilizan en un test condicional para determinar si un

puntero se ha inicializado.

Punteros a Punteros

Un puntero puede apuntar a otra variable puntero. Este concepto se utiliza con mucha

frecuencia en programas complejos de C. Para declarar un puntero a un puntero se hace

preceder a la variable con dos asteriscos ( * * ) .

En el ejemplo siguiente ptr5 es un puntero a un puntero.

int valor-e = 100;

i n t *ptrl = &valor-e;

int **ptr5 = &ptrl;

Page 8: Resumen de Punteros

Punteros y Arrays

Los arrays y punteros están fuertemente relacionados en el lenguaje C. Se pueden

direccionar arrays como si fueran punteros y punteros como si fueran arrays. La

posibilidad de almacenar y acceder a punteros y arrays, implica que se pueden

almacenar cadenas de datos en elementos de arrays. Sin punteros eso no es posible, ya

que no existe el tipo de dato cadena (string) en C. No existen variables de cadena.

Únicamente constantes de cadena.

Nombres de arrays como punteros

Un nombre de un array es simplemente un puntero. Supongamos que se tiene la

siguiente declaración de un array:

int lista[5] = 110, 20, 3 0 , 40, 501;

Por consiguiente, para imprimir (visualizar), almacenar o calcular un elemento de un

array, se puede utilizar notación de subíndices o notación de punteros. Dado que un

nombre de un array contiene la dirección del primer elemento del array, se debe in

direccionar el puntero para obtener el valor del elemento.

El nombre de un array es un puntero, contiene la dirección en memoria de comienzo de

la secuencia de elementos que forma el array. Es un puntero constante ya que no se

puede modificar, sólo se puede acceder para indexar a los elementos del array. En el

ejemplo se pone de manifiesto operaciones correctas y erróneas con nombres de array.

Punteros de Cadenas

Page 9: Resumen de Punteros

Los punteros se pueden utilizar en lugar de índices de arrays. Considérese la siguiente

declaración de un array de caracteres que contiene las veintiséis letras del alfabeto

internacional

Punteros versus arrays

El siguiente programa implementa una función para contar el número de caracteres de

una cadena. Primer programa, la cadena se describe utilizando un array, y en el

segundo, se describe utilizando un puntero.

Aritmética de punteros

Al contrario que un nombre de array, que es un puntero constante y no se puede

modificar, un puntero es una variable que se puede modificar. Como consecuencia, se

pueden realizar ciertas operaciones aritméticas sobre punteros.

Punteros constantes

Para crear un puntero constante diferente de un nombre de un array, se debe utilizar el

siguiente formato:

<tipo de dato > *const <nombre puntero> = <dirección de variable >;

Como ejemplo de una definición de punteros de constantes, considérense las siguientes

sentencias:

int x;

int y;

int *const pl = &x;

pl es un puntero de constantes que apunta a x, por lo que pl es una constante, pero *pl es

una variable. Por consiguiente, se puede cambiar el valor de *pl , pero no pl .Por

Page 10: Resumen de Punteros

ejemplo, la siguiente asignación es legal, dado que se cambia el contenido de memoria a

donde apunta PI, pero no el puntero en sí.

Punteros a constantes

El formato para definir un puntero a una constante es:

const <tipo de dato elemento> *<nombre puntero> =

<dirección de constante >;

Una definición de un puntero constante tiene la palabra reservada const delante del

nombre del puntero, mientras que el puntero a una definición constante requiere que la

palabra reservada const se sitúe antes del tipo de dato. Así, la definición en el primer

caso se puede leer como «punteros constante o de constante», mientras que en el

segundo caso la definición se lee «puntero a tipo constante de dato»

La creación de un puntero a una constante cadena se puede hacer del modo siguiente:

const char *apellido = "Remirez";

En el prototipo de la siguiente función se declara el argumento como puntero a una

constante:

float cargo (const float "v) ;

Punteros constante frente a punteros a constantes

Ya está familiarizado con punteros constantes, como es el caso de un nombre de un

array. Un puntero constante es un puntero que no se puede cambiar, pero que los datos

Page 11: Resumen de Punteros

apuntados por el puntero pueden ser cambiados. Por otra parte, un puntero a una

constante se puede modificar para apuntar a una constante diferente, pero los datos

apuntados por el puntero no se pueden cambiar.

El último caso a considerar es crear punteros constantes a constantes utilizando el

formato siguiente:

Const <tipo de dato elemento> *const <nombre puntero> =

<dirección de constante >;

Esta definición se puede leer como <<un tipo constante de dato y un puntero constante.

Un ejemplo

const int x = 25;

const int "const pl = &x;

Que indica: «PI es un puntero constante que apunta a la constante entera x». Cualquier

intento de modificar pl o bien *pl producirá un error de compilación.

Regla:

Si sabe que un puntero siempre apuntará a la misma posición y nunca necesita

ser reubicado

Si sabe que el dato apuntado por el puntero nunca necesitará cambiar, defina el

puntero como (recolocado), defínalo como un puntero constante. un puntero a

una constante.

Punteros como argumentos de funciones

Con frecuencia se desea que una función calcule y devuelva más de un valor, o bien se

desea que una función modifique las variables que se pasan como argumentos. Cuando

se pasa una variable a una función (paso por valor) no se puede cambiar el valor de esa

variable. Sin embargo, si se pasa un puntero a una variable a una función (paso por

dirección) se puede cambiar el valor de la variable. Cuando una variable es local a una

función, se puede hacer la variable visible a otra función pasándola como argumento. Se

Page 12: Resumen de Punteros

puede pasar un puntero a una variable local como argumento y cambiarla variable en la

otra función.

Punteros a funciones

Hasta este momento se han analizado punteros a datos. Es posible declarar punteros a

cualquier tipo de variables, estructura o array. De igual modo, las funciones pueden

declarar parámetros punteros para permitir que sentencias pasen las direcciones de los

argumentos a esas funciones .Es posible también crear punteros que apunten a

funciones. En lugar de direccionar datos, los punteros de funciones apuntan a código

ejecutable. Al igual que los datos, las funciones se almacenan en memoria y tienen

direcciones iniciales. En C se pueden asignar las direcciones iniciales de funciones a

punteros. Tales funciones se pueden llamar en un modo indirecto, es decir, mediante un

puntero cuyo valor es igual a la dirección inicial de la función en cuestión.

La sintaxis general para la declaración de un puntero a una función es:

Tipo-de-retorno (*PunteroFuncion) (<lista de parámetros>);

Este formato indica al compilador que PunteroFunci es un puntero a una función que

devuelve

El tipo Tipo-de-retorno y tiene una lista de parámetros.

Un puntero a una función es simplemente un puntero cuyo valor es la dirección del

nombre de la función. Dado que el nombre es, en sí mismo, un puntero; un puntero a

una función es un puntero a un puntero constante.

Page 13: Resumen de Punteros

Inicialización de un puntero a una función

La función asignada debe tener el mismo tipo de retorno y lista de parámetros que el

puntero a función; en caso contrario, se producirá un error de compilación. Así,

Los punteros a funciones también permiten pasar una función como un argumento a otra

función .Para pasar el nombre de una función como un argumento función, se especifica

el nombre de la función como argumento. Supongamos que se desea pasar la función m

i f unc ( ) a la función suf unc ( )

Aplicación de punteros a función para ordenación

Algunas de las funciones de la biblioteca, tal como qsort ( ) o bsearch( ) , requieren

pasar un argumento que consta de un puntero a una función. Se debe pasar a ambas,

qsort ( ) y bsearch ( ) , un puntero de función que apunta hacia una función que se debe

definir. Qsort ( ) utiliza el algoritmo de ordenación rápida (quicksort) para ordenar un

array de cualquier tipo de dato. Bsearch ( ) utiliza la búsqueda binaria para determinar si

un elemento está en un array. La función que debe de proporcionarse es para realizar

comparaciones de elementos de array. En el programa siguiente, la función comparar

( )se pasa a qsort ( y a bsearch ( ) . La función comparar ( ) compara entradas del array

tabla y devuelve (retorna) un número negativo si argl es menor que arg2, devuelve cero

si son iguales, o un número positivo si argl es mayor que arg2 .

Arrays de punteros de funciones

Ciertas aplicaciones requieren disponer de numerosas funciones, basadas en el

cumplimiento de ciertas condiciones. Un método para implementar tal aplicación es

utilizar una sentencia switch con muchos selectores case. Otra solución es utilizar un

array de punteros de función. Se puede seleccionar una función de la lista y llamarla.

Page 14: Resumen de Punteros

La sintaxis general de un array de punteros de función es:

Tipo Retorno(*PunteroFunc[LongArray])( <Lista de parámetros>);

Punteros a estructuras

Un puntero también puede apuntar a una estructura. Se puede declarar un puntero a una

estructura tal como se declara un puntero a cualquier otro objeto y se declara un puntero

estructura tal como se declara cualquier otra variable estructura: especificando un

puntero en lugar del nombre de la variable estructura.

struct persona

{

char nombre [30 I ;

int edad;

int altura;

int peso;

} ;

struct persona empleado = {"Amigo, Pepe", 47, 182, 85);

struct persona *p; / * se crea un puntero de estructura * /

p = &empleado;

Cuando se referencia un miembro de la estructura utilizando el nombre de la estructura,

se especifica la estructura y el nombre del miembro separado por un punto (.). Para

referenciar el nombre de un apersona, utilice empleado. nombre. Se referencia una

estructura utilizando el puntero estructura. Se utiliza el operador -> para acceder a un

miembro de ella.

Page 15: Resumen de Punteros

Conclusión

Como hemos visto los punteros es necesario para ejecutar un comando e realizar una

programación ya que son puntos de inicio que da a corregir fallas y son puntos de

claves para hacer funcionar el dicho programa

Esto demuestra gran importancias se puede decir que sin esto punteros el programa no

funciona ya que no hay inicio y no hay un comando que el vea para ejecutar así lo

hemos visto y en podido entender todo eso…