Sunteți pe pagina 1din 7

Universidad Mariano Gálvez

Facultad de Ingeniería en Sistemas de Información


Y Ciencias de la Computación
Centro Universitario “Chinautla”
Curso: Programación 1
Catedrático: Ing. Ilonkka Cabrera Cintora

Resumen de Punteros

Nombre Carne
Rosa Alicia Ascuc Suret 5990-19-15250

Guatemala, abril 2020


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 un 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.
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 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 * /
*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 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 otro 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;
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
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 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 = "Ramírez";
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 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 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.
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.
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.

S-ar putea să vă placă și