SlideShare una empresa de Scribd logo
1 de 80
Lenguaje C
Para Estudiantes de
Programación I
Script II - Punteros
Lenguaje C
¿Por qué punteros ahora?
Después de todo, hablar de Lenguaje C es casi como hablar de punteros. Esta en todas
partes del lenguaje y esta en todas sus librerías estándar. Casi todo tiene que ver con
ellos de una u otra forma. Y por desgracia, se requiere buena disciplina para usarlos.
Todo programador novato se ha roto la cabeza intentando explicarse porque un simple
printf termina en una violación de segmento o porque no compila su programa y se
soluciona colocando caracteres extraños como & y *
Estoy convencido que mientras más rápido usemos los punteros, más rápido
aprenderemos el lenguaje C y menos errores sin sentido nos agobiaran al programar.
Conocer lo que hace a este lenguaje tan poderoso sin duda nos dará la mejor de las
ventajas
Lenguaje C
MAXIMA: «Sin punteros
no hay paraíso…»
Lenguaje C
Punteros en C
SCRIPT II
Lenguaje C
Script II – Punteros en C
>> Repasando las Variables
>> Usando Variables
>> Los operadores & y *&
>> Qué es un puntero
>> Puntero Endemoniado
>> Tipos de datos básicos para punteros
>> Asignación de punteros
>> Funciones en C
>> Paso de punteros a funciones
>> Punteros y Arrays
>> Punteros y Cadenas
>> Arrays de Punteros
>> Punteros a Punteros
>> Punteros NULL y VOID
>> Punteros constantes
>> Punteros a funciones
>> Callbacks
>> Bonus Track - Recomendaciones
Lenguaje C
REPASANDO LAS VARIABLES
Como ya sabemos, las variables en el
lenguaje C tienen 5 elementos que
debemos tener presente:
1. Nombre de la Variable
2.Tipo de Dato
3.Tamaño
4.Valor
5.Dirección de Memoria
Para comprender el uso de punteros es
indispensable conocer el uso de las
variables. Un error muy común es
desconocer la relación entre estos
elementos y como se almacenan
10
edad
int
0xf0113b1
32 bits
Lenguaje C
REPASANDO LAS VARIABLES
Para empezar a utilizar punteros en C,
debemos prestar especial atención a las
direcciones de memoria.
Aunque parezca mentira, y a pesar de que
casi no las miramos, las direcciones de
memoria son la clave para entender las
bases del uso de punteros. Saber usar una
dirección de memoria y el valor de una
dirección de memoria es el quebradero de
cabeza mas común en miles de
programadores en todo el mundo.
10
edad
int
0xf0113b1
32 bits
Lenguaje C
USANDO VARIABLES
edad
int
¿Cómo acceder a los elementos de una variable?
Tanto el tipo de dato int como el nombre de la
variable edad no pueden ser accedidos de ninguna
manera. Esto se debe a que el Lenguaje C no
soporta características reflexivas que permitan
conocer detalles de las variables en tiempo de
ejecución.
Esto nos da a entender que somos responsables de
conocer bien todas las variables que utilizamos y de
conocer sus tipos de datos.
El resto de los elementos (tamaño, valor y dirección
de memoria) si pueden ser conocidos y accedidos
en tiempo de ejecución. Saber como hacerlo es el
primer paso para entender a los punteros
Lenguaje C
USANDO VARIABLES
edad
int
32 bits
¿Cómo saber el tamaño de una variable?
La función sizeof() nos permite calcular el tamaño
en bytes de una determinada variable. El resultado
debe ser multiplicado por 8 si queremos conocer el
valor en bits
int edad;
sizeof(edad);
sizeof(unsigned int);
Tipos básicos de datos
• Las variables tipo char se usan para almacenar caracteres ASCII como
“A”,”1”,”&”, etc.
• Cuando se desea trabajar con enteros, dependiendo del rango, se puede usar
short, int o long, con signo o sin signo.
• Para trabajar con enteros sin signo, se debe anteponer la palabra reservada
unsigned delante del tipo (unsigned int). Esto nos permite aumentar el
rango del tipo.
• Por defecto son con signo, no hace falta anteponer la palabra signed.
Tipos de variables
Programación en C 11
long double 96 18 3.3621e-4932 1.18973e+493
Lenguaje C
USANDO VARIABLES
10
edad
int
32 bits
¿Cómo ver o alterar el valor de una variable?
Es broma !
Simplemente hacemos referencia a ella por su
nombre en cualquier asignación o función
Lenguaje C
USANDO VARIABLES
10
edad
int
0x7fff2960d0ac
32 bits
¿Cómo saber la dirección de memoria de una
variable?
Para saber la dirección de memoria de cualquier
variable debemos usar el signo ampersand (&)
ATENCION !
Las direcciones de memoria
cambian con cada ejecución
ESPECIFICADORES DE FORMATO PARA SCANF Y PRINTF
SECUENCIAS DE ESCAPE EN C
Cuando estamos escribiendo un programa puede que necesitemos representar la información de una forma
especial, con ciertas alineaciones, tabulaciones o estilos, en C es posible realizar estas tareas mediante las
llamadas secuencias de escape.
Lenguaje C
Los operadores & y *&
10 edad
int
0x7fff2960d0ac&
*&
¿Qué significan estos símbolos?
& = Referencia o Dirección de Memoria
*& = Dereferencia, Indirección, Valor de dirección de memoria, Valor Apuntado
Lenguaje C
Los operadores & y *&
10 edad
int
0x7f5f0ac
USO DE LOS OPERADORES
Estos operadores se usan con cualquier objeto en memoria (variables, estructuras, arrays,
funciones, etc), sin embargo no pueden ser aplicadas a expresiones, constantes o variables
del tipo register
El operador & nos devolverá la dirección de memoria. Así de simple
&edad 0x7f5f0ac
*&edad 10
0x7f5f0ac 10*
Lenguaje C
Los operadores & y *&
10 edad
int
0x7f5f0ac
&edad 0x7f5f0ac
*&edad 10
USO DE LOS OPERADORES
El operador * tiene varios usos. Uno de ellos es la Indirección el cual permite acceder al
valor guardado en una dirección de memoria.
Para efectuar una indirección es indispensable que el operador * se aplique a una dirección
de memoria (por ejemplo *0x7f5f0ac)
0x7f5f0ac 10*
Lenguaje C
Los operadores & y *&
DEMOSTRADO
La dirección de memoria se puede
obtener al usar el operador & en
cualquier variable
El operador de indirección (*) es
aplicado a direcciones de memoria
y permite acceder al valor
almacenado en ella
Las direcciones de memoria
pueden utilizarse en su forma
hexadecimal
Nota: Debido a que las direcciones memoria son asignadas en tiempo de
ejecución, no es sencillo saber que dirección ocupara una determinada variable.
Es por eso que se ha utilizado el depurador gdb para hacer esta demostración
Lenguaje C
Los operadores & y *&
10 edad
int
0x7f5f0ac
*&edad
0x7f5f0ac
*
10VALGAN VERDADES
A nadie en su sano juicio se le ocurrirá utilizar una dirección de memoria dentro del código
fuente. Ni que decir de la sentencia *&edad. ¿Para que alguien tendría que utilizar esta
extraña sintaxis cuando simplemente puede usar la variable con su simple nombre?.
edad = 10; // Este modo es el mas cuerdo
*&edad = 10; // A quien se le ocurriría usar esto por Dios !
*0x7f5f0ac = 10; // Definitivamente ya no tiene amigos
¿CUAL USARIAS ?
Lenguaje C
QUE ES UN PUNTERO
¿Recuerdan que nadie en su sano juicio usaría la sentencia así: *0x7f5f0ac?
Un puntero da solución a ese problema !. Conocer las direcciones de memoria brinda lo
que hace al lenguaje C tan potente y requerido: Su velocidad.
Un puntero es una variable especial capaz de guardar una dirección de memoria de tal
forma que no tenemos que recurrir a escribirlas dentro del código. Al poder guardar
cualquier dirección de memoria, un puntero puede tomar posesión de cualquier variable
de su tipo y literalmente jugar con ella
10 edad
int
0x7f5f0ac
0x7f5f0ac ptr
int*
0x503fb43
22
Un puntero es un objeto que apunta a otro objeto. Es decir,
una variable cuyo valor es la dirección de memoria de otra
variable.
Las direcciones de memoria dependen de la arquitectura
del ordenador y de la gestión que el sistema operativo haga
de ella.
Punteros
Lenguaje C
Lenguaje C
QUE ES UN PUNTERO
Examinando un Puntero
Un puntero es una variable, y como tal, tiene
todos los elementos de cualquier variable (tipo
de dato, nombre, tamaño y dirección de
memoria) . La única diferencia visible es que al
declararla, su tipo de dato debe ir acompañado
del símbolo *
Debido a que debe contener direcciones de
memoria, su tamaño debe ser lo suficientemente
grande para poder guardar cualquier dirección
de memoria del sistema operativo. Por esta razón
es muy común que su tamaño sea de 64 bits (8
bytes) que son suficientes para hacer referencia a
muchos terabytes de memoria
0x7f5f0ac
ptr
int*
0x503fb43
64 bits
Lenguaje C
QUE ES UN PUNTERO
Declaración de un puntero
En mi humilde opinión, la confusión de muchos
programadores se debe a que el símbolo * se usa
para diferentes cosas, entre ellas para declarar
un puntero.
int *ptr = &edad;
*ptr = 19;
El código anterior demuestra la facilidad con la
que puede confundir a mas de un programador
puesto que se puede llegar erróneamente a
deducir que el puntero ptr puede guardar valores
como el 19 y direcciones de memoria como
&edad. Lo cual es peligroso asumir
0x7f5f0ac
ptr
int*
0x503fb43
64 bits
Lenguaje C
QUE ES UN PUNTERO
Declaración de un puntero
A pesar que la gran mayoría utiliza la declaración
del modo int *ptr como la normal, usar la
siguiente declaración ayuda a evitar confundirla
con la indirección:
int* ptr = &edad;
*ptr = 19;
El código anterior separa claramente lo que es la
variable puntero ptr y lo que es la operación de
indirección al puntero ptr. Al parecer el estándar
C99 se percato de esto y recomendó crear tipos
de datos como intptr_t y uintptr_t que no hacen
mas que retirar el signo * de la declaración de un
puntero
0x7f5f0ac
ptr
int*
0x503fb43
64 bits
Lenguaje C
QUE ES UN PUNTERO
DEMOSTRADO
Un puntero guarda direcciones de memoria. Así
mismo un puntero al ser una variable, tiene su
propia dirección de memoria
Con la indirección no solo accedemos al valor de
la variable apuntada, sino que también podemos
modificar su valor.
Un puntero obtiene su valor a partir de la
referencia de una variable que se consigue con el
operador &
El tamaño de un puntero puede ser obtenido
mediante la función sizeof()
Punteros
Programación en C 27
• Los gestión de punteros admite dos operadores
básicos:
– Si px es un puntero (dirección): *px es el contenido
del puntero (el valor almacenado en la dirección).
– Si x es una variable: &x es la dirección de memoria
donde está almacenada la variable.
Punteros
int main()
{
int *px,y=3;
px=&y;
/* px apunta a y */
*px=5;
/* y vale 5 */
}
Programación en C 28
Dirección
px-> 35:
y -> 39:
Contenido Gráfica
? ? ? ?
0 0 0 3
?
px
3
y
px-> 35:
y -> 39:
0 0 0 39
0 0 0 3
39
3
y
px
px-> 35:
y -> 39:
0 0 0 39
0 0 0 5
39
5
y
px
Punteros
Programación en C 29
La declaración de punteros genéricos a
direcciones se asocian al tipo void.
Declarar una variable (que no sea un puntero) de
tipo void no tiene sentido.
Ejemplo:
void *px,v; /* La variable v
está mal
declarada */
Lenguaje C
PUNTERO ENDEMONIADO
¿Por qué los punteros tienen fama de ser
complicados?
La desventaja de los punteros es que debemos
ser muy disciplinados en su uso y no es tarea
fácil. Entre los errores mas comunes tenemos
• Punteros no inicializados
• Asignación de punteros errónea
• Punteros con tipos distintos
• Indirección errónea
• Uso incorrecto de punteros nulos
Como podrás apreciar, son muchas cosas las que
pueden ir mal, es por eso que los punteros
requieren especial atención y cuidado
0x7f5f0ac
ptr
int*
0x503fb43
64 bits
Lenguaje C
PUNTERO ENDEMONIADO
Punteros no inicializados
Todo puntero ANTES de ser utilizado debe ser
inicializado apropiadamente. Es decir, su valor
debe ser NULO o debe contener la dirección de
memoria de una variable de su tipo de dato.
int edad = 10;
int* p;
*p = 19;
Si un puntero no esta inicializado y hace uso de la
operación indirección se produce una Violación
de Segmento y el programa terminará de forma
abrupta
Lenguaje C
PUNTERO ENDEMONIADO
Violación de Segmento
Lamentablemente cuando se declara un puntero,
toma como valor inicial una dirección aleatoria
usualmente fuera del segmento de memoria del
programa.
La Violación de Segmento se produce porque un
programa intenta modificar o acceder a un
segmento de memoria que no le corresponde. El
Sistema Operativo al detectar esta intrusión se
protege y detiene el programa ‘agresor’
indicando que ha violado un segmento que no le
corresponde.
Lenguaje C
PUNTERO ENDEMONIADO
Inicialización de puntero errónea
Otro error común es olvidar colocar el signo
ampersand (&) al inicializar un puntero.
Con ello se consigue que el puntero guarde el
valor de la variable y no su dirección de
memoria, la cual al ser accedida provoca una
violación de segmento
En el ejemplo que vemos, erróneamente le
estamos indicando que la dirección de memoria
guardada por ptr será la posición 0x10 (lo que
guarda la variable edad). Luego intentaremos
cambiar el valor de la posición 0x10 a 19 lo cual
produce un crash en nuestro programa
Lenguaje C
PUNTERO ENDEMONIADO
Punteros con tipos de datos distintos
Los punteros deben ser declarados según el
tipo de dato al que apuntarán.
Si un puntero apunta a una variable cuyo tipo
de dato es distinto puede convertirse en un
problema si el tamaño del tipo de dato al que
se apunta es menor.
En el ejemplo podemos ver un puntero de tipo
int haciendo referencia a la dirección de una
variable de tipo char. Esto conlleva a que se
produzca un desborde y el programa se
detenga por producir una violación de
segmento ya que ptr usara 4 bytes y no 1
Lenguaje C
PUNTERO ENDEMONIADO
Indirección errónea
Al ser la operación mas común de un puntero,
la indirección será errónea siempre y cuando la
declaración o incialización este mal hecha
La indirección en si misma no es un error. El
error viene al usarla en un contexto erróneo.
En el ejemplo podemos ver que la indirección
no produce una violación de segmento, pero
ha sido un error alterar el valor mediante la
indirección debido a que estamos desbordando
una variable de tipo char
Lenguaje C
PUNTERO ENDEMONIADO
Uso incorrecto de punteros nulos
El lenguaje C permite nulificar un puntero para
evitar acceder de forma accidental a otra
dirección de memoria fuera de nuestro
segmento permitido.
Sin embargo, veamos que pasa cuando no
utilizamos adecuadamente los punteros nulos
En el ejemplo podemos ver que a pesar de
poner un puntero a NULL podemos causar
problemas si realizamos una indirección. Esto
naturalmente tiene sentido debido a que la
dirección 0x0 (NULL) no puede ser alterada.
Lenguaje C
TIPOS DE DATOS BASICOS PARA PUNTEROS
¿Y a que tipos de datos puedo apuntar?
En realidad, podemos apuntar a cualquier
tipo de dato que usemos en el Lenguaje C
Los tipos de datos comunes suelen ser los
tipos de datos básicos a los cuales un
puntero podrá hacer referencia.
Incluso podemos usar el puntero void* que
nos permite apuntar a cualquier tipo de
dato. El resto de punteros solo puede
apuntar a su tipo de datos ( por ejemplo el
puntero float* solo podrá apuntar a variables
float, etc)
char*
int*
float*
double*
void*
Lenguaje C
ASIGNACION DE PUNTEROS
La clave en el uso de todo puntero es su correcta
asignación (inicialización).
La asignación de punteros es una operación que
permite indicar que dirección de memoria
tomará un puntero determinado.
Hay 2 tipos de asignación de punteros
• Asignación de variable a puntero
• Asignación de puntero a puntero
La primera es la habitual, que permite apuntar a
una variable determinada.
0x7f5f0ac
ptr
int*
0x503fb43
64 bits
Lenguaje C
ASIGNACION DE PUNTEROS
Asignación de variable a puntero
Para asignar una variable a un puntero podemos
usar la declaración del puntero
int edad = 10;
int* ptr = &edad;
Sin embargo, también podemos usar esta forma
int edad = 10;
int* ptr;
ptr = &edad;
La 2da forma no se recomienda por ser peligrosa
0x7f5f0ac
ptr
int*
0x503fb43
64 bits
Lenguaje C
ASIGNACION DE PUNTEROS
Asignación de puntero a puntero
Una característica muy útil es que los punteros
pueden compartir sus datos entre si. Es decir,
mas de un puntero puede apuntar a la misma
variable
int edad = 10;
int* ptr1 = &edad;
int* ptr2 = ptr1; // No requiere &
*ptr2 = 19;
La ventaja es que lo que cambia un puntero se ve
reflejado en el otro. Solo debemos tener en
cuenta que al asignar un puntero a otro, NO ES
NECESARIO usar el signo &
Sobre una variable puntero se pueden realizar una serie de operaciones que veremos a
continuación:
− Dirección: el operador de dirección no es realmente uno que se aplique sobre las variables
puntero (normalmente), sino sobre otros tipos de variable. Éste operador, representado con
el símbolo ampersand (&) obtiene la dirección de memoria de la variable a la que precede.
Así, si la variable entera w está almacenada en la posición de memoria 32012, la operación
int *punt; punt= &w; asignará el valor 32012 a la variable punt.
− Indirección: el operador de desreferenciación o de indirección sí se aplica a valores de tipo
puntero. Éste operador se representa por un asterisco (*) y devuelve un valor del tipo
apuntado por el operando. Este valor es el contenido en la posición apuntada por el puntero.
Así, en el siguiente código
float *p; float q= 1.44;
p= &q; print("%fn", *p);
el valor que se imprime es 1.44, ya que p apunta a la dirección de q. En general, si el
puntero x apunta a un tipo de datos T, la expresión *x es de tipo T.
OPERACIONES CON LOS PUNTEROS
Asignación de punteros: Es posible asignar una dirección de una variable a un puntero (ej1)
Es posible asignar el contenido de un puntero a otro puntero (ej2)
OPERACIONES CON LOS PUNTEROS
Aritmética de punteros: Se trata de sumar y restar, incrementar o decrementar
variables de tipo puntero Debe entenderse como cambios en la dirección a la
que apunta el puntero (se produce un cambio en la dirección de memoria
contenida en el puntero). El incremento o decremento de un puntero depende
exclusivamente del tipo de dato base dado en la declaración del puntero. Al
declarar un puntero es necesario indicar a qué tipo de dato apunta para que
cuando se utilicen los incrementos o decrementos se conozca cuánto hay que
sumar o restar. La operación de sumar 1 a un puntero hace que su dirección se
incremente la cantidad necesaria para pasar a apuntar al siguiente dato del
mismo tipo (cantidad que coincide con el número de bytes que ocupa dicho
tipo de dato). Por lo tanto, sólo en el caso de variables que ocupan 1 byte en
memoria (variables de tipo “char”) la operación de incremento aumenta en 1
la dirección de memoria; en los demás casos aumenta más.
OPERACIONES CON LOS PUNTEROS
− Incremento, decremento: los valores de tipo puntero se pueden incrementar y
decrementar, siempre en valores enteros. Se admiten los operadores ’+’ , ’−’ , ’++’ y ’−−’.
OPERACIONES CON LOS PUNTEROS
OPERACIONES CON LOS PUNTEROS
OPERACIONES CON LOS PUNTEROS
Arrays y punteros
El identificador de una variable array tiene el valor
de la dirección de comienzo del mismo. Por lo
tanto, su valor puede usarse como un puntero.
int *pb,*pc;
int a[5]={10,20,30,40,50};
pb=a;
*pb=11;
pc=&a[3];
*pc=44;
Programación en C 49
10 20 30 40 50a
pb pc
11 20 30 40 50a
pb pc
11 20 30 44 50a
pb pc
#include <stdio.h>
main()
{
int v[10];
int i, *p;
for (i=0; i < 10; i++) v[i] = i;
for (i=0; i < 10; i++) printf ("n%d", v[i]);
p = v;
for (i=0; i < 10; i++) printf ("n%d", *p++);
/* Tras cada p++ el puntero señala a la siguiente posición en v */
return 0;
}
RECORRIDO DE UN VECTOR UTILIZANDO
ÍNDICES Y PUNTEROS
Punteros y vectores
• Una de las aplicaciones más frecuentes de los punteros es el manejo de vectores y
cadenas de caracteres.
• Como todos los elementos de un vector se almacenan en posiciones consecutivas de
memoria, basta conocer la posición de memoria del primer elemento para poder
recorrer todo el vector con un puntero.
Lenguaje C
PUNTEROS Y ARRAYS
Existe una estrecha relación entre los punteros y los arrays…(eso ya no suena a
novedad). De hecho están tan relacionados que todas las operaciones que se realizan
con arrays pueden ser realizadas por punteros. La diferencia claro esta es que con
punteros las cosas van mas rápido
char a[4+1] = «HOLA0»;
char* ptr = &a[0];
a
a[0] a[1] a[2] a[3] a[4]
‘H’ ‘O’ ‘L’ ‘A’ ‘0’
0x503f5 0x503f6 0x503f7 0x503f8 0x503f90x765d3
0x503f5
char*
ptr
Lenguaje C
PUNTEROS Y ARRAYS
Operación con Punteros Equivalente en Array
char a[4+1] = «HOLA0»;
char* ptr = &a[0];
*ptr = ‘F’;
a
a[0] a[1] a[2] a[3] a[4]
‘F’ ‘O’ ‘L’ ‘A’ ‘0’
0x503f5 0x503f6 0x503f7 0x503f8 0x503f90x765d3
0x503f5
char*
ptr
char a[4+1] = «HOLA0»;
a[0] = ‘F’;
Lenguaje C
PUNTEROS Y ARRAYS
Operación con Punteros Equivalente en Array
char a[4+1] = «HOLA0»;
char* ptr = &a[0];
*ptr = ‘F’;
ptr=ptr+2;
*ptr = ‘C’;
a
a[0] a[1] a[2] a[3] a[4]
‘F’ ‘O’ ‘C’ ‘A’ ‘0’
0x503f5 0x503f6 0x503f7 0x503f8 0x503f90x765d3
0x503f7
char*
ptr
char a[4+1] = «HOLA0»;
a[0] = ‘F’;
a[2] = ‘C’;
Lenguaje C
PUNTEROS Y ARRAYS
Aritmética de Punteros
a
a[0] a[1] a[2] a[3] a[4]
‘H’ ‘O’ ‘L’ ‘A’ ‘0’
0x503f5 0x503f6 0x503f7 0x503f8 0x503f90x765d3
0x503f5
char*
ptr
ptr+1 ptr+2 *(ptr+3) ptr+4
A un puntero se le puede sumar o restar un número entero, lo cual es usado para
moverse por un array. Aplicando el operador ++ o -- a un puntero se consigue que
avance a la siguiente dirección de memoria o a la anterior según sea el caso
Lenguaje C
PUNTEROS Y ARRAYS
Aritmética de Punteros
a
a[0] a[1] a[2] a[3] a[4]
‘H’ ‘O’ ‘L’ ‘A’ ‘0’
0x503f5 0x503f6 0x503f7 0x503f8 0x503f90x765d3
0x503f5
char*
ptr
ptr+1 ptr+2 *(ptr+3) ptr+4
Operaciones Aritmeticas no permitidas:
• Sumar, Multiplicar o Dividir 2 punteros
Lenguaje C
PUNTEROS Y ARRAYS
Diferencias?
a
a[0] a[1] a[2] a[3] a[4]
‘H’ ‘O’ ‘L’ ‘A’ ‘0’
0x503f5 0x503f6 0x503f7 0x503f8 0x503f90x765d3
0x503f5
char*
ptr
Por diseño, un array se comporta como un puntero, en el sentido en que un array es un
‘sinónimo’ para la dirección de memoria del elemento inicial.
Esto quiere decir, que según el ejemplo el array a tiene el mismo valor que ptr
ptr+1 ptr+2 *(ptr+3) ptr+4
*(a+3)*(a+0) *(a+1) *(a+2) *(a+4)
Lenguaje C
PUNTEROS Y ARRAYS
Diferencias?
a
0x765d3
0x503f5
char*
ptr
Esto quiere decir que la sentencia
ptr = a es equivalente a ptr = &a[0] ptr+1 ptr+2 *(ptr+3) ptr+4
Incluso podemos ver que la referencia de a[i] puede ser escrita como *(a+i) donde i es
el índice del array. De hecho el lenguaje C hace esta conversión de forma interna para
todo array
a[0] a[1] a[2] a[3] a[4]
‘H’ ‘O’ ‘L’ ‘A’ ‘0’
0x503f5 0x503f6 0x503f7 0x503f8 0x503f9
ptr+1 ptr+2 *(ptr+3) ptr+4
*(a+3)*(a+0) *(a+1) *(a+2) *(a+4)
Lenguaje C
PUNTEROS Y ARRAYS
Diferencias
a
0x765d3
0x503f5
char*
ptr
Solo hay una diferencia entre un puntero y un array
Siguiendo el ejemplo: El puntero ptr es una variable, pero el nombre del array a no lo
es por lo tanto sentencias como a++ o a=ptr no son permitidas. Un nombre de array es
un puntero constante dado que no puede agregar ni eliminar elementos a su lista
a[0] a[1] a[2] a[3] a[4]
‘H’ ‘O’ ‘L’ ‘A’ ‘0’
0x503f5 0x503f6 0x503f7 0x503f8 0x503f9
Lenguaje C
PUNTEROS Y ARRAYS
Demostrado !
Lenguaje C
PUNTEROS Y CADENAS
¿Que es una cadena?
os
0x765d3
0x503f5
char*
ptr
Una cadena no es mas que un array de tipo char
El lenguaje C NO existe el tipo de dato string, pero mediante arrays se puede conseguir
el tratamiento de cadenas de caracteres sin la cual cualquier lenguaje de programación
no serviría de mucho.
os[0] os[1] os[2] os[3] os[4]
‘U’ ‘N’ ‘I’ ‘X’ ‘0’
0x503f5 0x503f6 0x503f7 0x503f8 0x503f9
char os[4+1] = «UNIX0»;
Lenguaje C
PUNTEROS Y CADENAS
¿Que es una cadena?
os
0x765d3
0x503f5
char*
ptr
Las cadenas son un elemento tan importante que es quizá sin exagerar el aspecto más
crítico en el Lenguaje C. La gran mayoría de problemas de seguridad se deben al
inadecuado uso de las cadenas. Incluso el propio lenguaje nos ofrece funciones que son
inseguras debido a que delegan toda la responsabilidad del correcto tratamiento de
cadenas al programador. Hemos ingresado ya en terreno minado !
os[0] os[1] os[2] os[3] os[4]
‘U’ ‘N’ ‘I’ ‘X’ ‘0’
0x503f5 0x503f6 0x503f7 0x503f8 0x503f9
char os[4+1] = «UNIX0»;
Lenguaje C
PUNTEROS Y CADENAS
Marcando el final
os
0x765d3
0x503f5
char*
ptr
El gran problema con las cadenas es que debemos indicar donde terminan, es decir
debemos indicarle explícitamente cual es el final de una cadena, asignarle una marca
que permita al lenguaje C reconocer donde detenerse. Incluso si una cadena no utiliza
todos sus elementos debemos indicarlo de lo contrario algo podría explotar
Esa marca es el carácter NULL o también denotado por el símbolo ‘0’
os[0] os[1] os[2] os[3] os[4]
‘U’ ‘N’ ‘I’ ‘X’ ‘0’
0x503f5 0x503f6 0x503f7 0x503f8 0x503f9
char os[4+1] = «UNIX0»;
Lenguaje C
PUNTEROS Y CADENAS
El origen de todos los males
En el ejemplo podemos apreciar un error muy común (y sobretodo peligroso) en el
manejo de cadenas: El Desbodarmiento.
Aparentemente se ve inofensivo, pero en realidad copiar una cadena de mayor tamaño
en una menor ocasiona que se sobrescriba memoria ajena que puede detener el
programa e incluso poner en riesgo todo un sistema.
os[0] os[1] os[2] os[3] os[4]
‘W’ ‘I’ ‘N’ ‘D’ ‘O’
0x503f5 0x503f6 0x503f7 0x503f8 0x503f9
char os[4+1];
strcpy(os,
«WINDOWS7»);
printf(«%s»,os);
memoria no reservada
‘W’ ‘S’ ‘ 7’
0x503fa 0x503fb 0x503fc
Lenguaje C
PUNTEROS Y CADENAS
Operaciones comunes / Copiado
‘U’ ‘N’ ‘I’ ‘X’‘¡’ ‘?’ ‘$’ ‘0’ ‘?’
‘U’ ‘N’ ‘I’ ‘X’ ‘0’
auxos
char* strcpy(os, aux)
os
CODIGO
char os[4+1];
char aux[4] = «UNIX»;
strcpy(os,aux);
Nótese que en el ejemplo, la variable os al ser declarada su valor es aleatorio (debido a
que no ha sido inicializada). Así también se puede apreciar que la función strcpy agrega al
final de la cadena el delimitador nulo (‘0’).
Lenguaje C
PUNTEROS Y CADENAS
Operaciones comunes / Copiado
‘W’ ‘I’ ‘N’ ‘D’‘U’ ‘N’ ‘I’ ‘X’ ‘0’
‘W’ ‘I’ ‘N’ ‘X’ ‘0’
auxos
char* strncpy(os, aux,3)
os
CODIGO
char os[4+1]=«UNIX0»;
char aux[7] = «WINDOWS»;
strncpy(os,aux,3);
La función strncpy también copia cadenas, sin embargo podemos indicarle el número de
caracteres a copiar. En el ejemplo vemos que solo se copiaran 3 caracteres de la cadena
aux en la cadena os. Nótese que el carácter X aun permanece
‘O’ ‘W’ ‘0’
Lenguaje C
PUNTEROS Y CADENAS
Operaciones comunes / Concatenar
‘X’ ‘P’ ‘0’‘W’ ‘I’ ‘N’ ‘0’ ‘8’
‘W’ ‘I’ ‘N’ ‘X’ ‘P’
auxos
char* strcat(os, aux)
os
CODIGO
char os[5+1]=«WIN08Z»;
char aux[2] = «XP»;
strcat(os,aux);
La función strcat permite copiar una cadena al final de otra. Podemos ver como se copia la
cadena XP al final de la variable os. Nótese como la función considera al carácter nulo (‘0’)
de os como final cuando realmente no lo es. Al final le agrega el signo ‘0’
‘Z’
‘0’
Lenguaje C
PUNTEROS Y CADENAS
Operaciones comunes / Concatenar
‘W’ ‘I’ ‘N’ ‘D’‘U’ ‘0’ ‘I’ ‘X’ ‘0’
‘U’ ‘W’ ‘I’ ‘N’ ‘0’
auxos
char* strncat(os, aux,3)
os
CODIGO
char os[4+1]=«U0IX0»;
char aux[7] = «WINDOW0»;
strncat(os,aux,3);
La función strncat también concatena cadenas, sin embargo podemos indicarle el número
de caracteres a concatenar. En el ejemplo vemos que solo se concatenarán 3 caracteres de
la cadena aux en la cadena os.
‘O’ ‘W’ ‘0’
Lenguaje C
PUNTEROS Y CADENAS
Operaciones comunes / Comparar
‘U’ ‘N’ ‘I’ ‘X’‘U’ ‘N’ ‘I’ ‘X’ ‘0’ auxos
int strcmp(os, aux)
CODIGO
char os[5]=«UNIX0»;
char aux[5] = «UNIX0»;
int r = strcmp(os,aux);
La función strcmp es diferente puesto que devuelve un valor entero. Compara 2 cadenas y
evalúa su similitud. Si las cadenas son iguales retorna el valor cero (0). Es importante
recordar que la evaluación diferencia mayúsculas de minúsculas (p.e A es distinto de a)
‘0’
0r
Lenguaje C
PUNTEROS Y CADENAS
Operaciones comunes / Comparar
‘I’ ‘O’ ‘S’ ‘4’‘U’ ‘N’ ‘I’ ‘X’ ‘0’ auxos
int strcmp(os, aux)
CODIGO
char os[5]=«UNIX0»;
char aux[5] = «WIN70»;
int r = strcmp(os,aux);
La función strcmp devuelve un número positivo (>0) si la primera cadena enviada es mayor
que la segunda. ¿Cómo puede ser una cadena mayor que otra?. Se comparan sus valores.
Por ejemplo la letra U=85 mientras que la I=73. Luego se devuelve la diferencia de ambas
‘0’
12r
Lenguaje C
PUNTEROS Y CADENAS
Operaciones comunes / Comparar
‘P’ ‘H’ ‘P’ ‘5’‘P’ ‘E’ ‘R’ ‘L’ ‘0’ auxlang
int strcmp(lang, aux)
CODIGO
char lang[5]=«PERL0»;
char aux[5] = «PHP50»;
int r = strcmp(lang,aux);
La función strcmp devuelve un número negativo(<0) si la primera cadena es menor que la
segunda. ¿Cómo puede ser una cadena menor que otra?. Se comparan sus valores uno por
uno. Por ejemplo la letra E=69 mientras que la H=72. Luego se devuelve 69-72=-3
‘0’
-3r
Lenguaje C
PUNTEROS Y CADENAS
Operaciones comunes / Comparar
‘P’ ‘H’ ‘P’ ‘5’‘P’ ‘H’ ‘P’ ‘4’ ‘0’ auxlang
int strncmp(lang, aux,3)
CODIGO
char lang[5]=«PHP40»;
char aux[5] = «PHP50»;
int r = strncmp(lang,aux,3);
La función strncmp funciona con la misma lógica que strcmp. La única diferencia es que
solo toma en cuenta la comparación de N caracteres indicados. En el ejemplo, el resultado
es 0 debido a que solo se comparan los 3 primeros caracteres que resultan ser iguales
‘0’
0r
Lenguaje C
PUNTEROS Y CADENAS
Operaciones comunes / Búsqueda
‘H’‘P’ ‘H’ ‘P’ ‘4’ ‘0’ auxlang
char* strchr(lang, aux)
CODIGO
char lang[5]=«PHP40»;
char aux= «H»;
char* ptr;
ptr = strchr(lang,aux);
La función strchr permite buscar una cadena dentro de otra. Si la encuentra devuelve un
puntero en la primera ocurrencia, caso contrario devolverá un puntero a NULL. En el
ejemplo se busca el carácter H dentro de PHP4 retornando un puntero a la posición 1
ptr
Lenguaje C
PUNTEROS Y CADENAS
Operaciones comunes / Búsqueda
‘P’‘P’ ‘H’ ‘P’ ‘4’ ‘0’ auxlang
char* strrchr(lang, aux)
CODIGO
char lang[5]=«PHP40»;
char aux= «P»;
char* ptr;
ptr = strrchr(lang,aux);
La función strrchr devuelve la ultima ocurrencia de una cadena. En el ejemplo podemos
ver que la función retorna un puntero a la posición nro 2 en lugar de la posición 0. Es decir,
devuelve la ultima ocurrencia de la letra P que ha sido buscada.
ptr
Lenguaje C
ARRAYS DE PUNTEROS
Como funcionan
‘L’ ‘I’ ‘N’ ‘U’ ‘X’
Un array de punteros funciona de forma similar a un array de cualquier otro tipo de datos.
Donde cada elemento puede apuntar a un valor del tipo de dato declarado previamente.
En el ejemplo podemos apreciar como se declara un array de 3 elementos que contienen
punteros a char. Incluso podemos inicializar de forma inmediata sus valores.
‘0’
‘W’ ‘I’ ‘N’ ‘D’ ‘O’ ‘W’ ‘S’ ‘0’
‘U’ ‘N’ ‘I’ ‘X’ ‘0’
osptr 0
1
2
char* osptr[3]={«LINUX0», «WINDOWS0», «UNIX0»};

Más contenido relacionado

La actualidad más candente

Lenguajes diapositivas
Lenguajes diapositivasLenguajes diapositivas
Lenguajes diapositivas
starduslex
 
Presentacion1 lenguaje de-programacion_c
Presentacion1 lenguaje de-programacion_cPresentacion1 lenguaje de-programacion_c
Presentacion1 lenguaje de-programacion_c
Monica Martinez
 
Lenguaje Borland C - Estructura y Componentes
Lenguaje Borland C - Estructura y ComponentesLenguaje Borland C - Estructura y Componentes
Lenguaje Borland C - Estructura y Componentes
Karina Arguedas Ruelas
 
Repaso del lenguaje C++
Repaso del lenguaje C++Repaso del lenguaje C++
Repaso del lenguaje C++
g_torrealba
 

La actualidad más candente (19)

Programacion c
Programacion cProgramacion c
Programacion c
 
Lenguajes diapositivas
Lenguajes diapositivasLenguajes diapositivas
Lenguajes diapositivas
 
Funciones C (gnu/linux)
Funciones C (gnu/linux)Funciones C (gnu/linux)
Funciones C (gnu/linux)
 
2do parcial c
2do parcial c2do parcial c
2do parcial c
 
Lenguaje de-programación-c
Lenguaje de-programación-cLenguaje de-programación-c
Lenguaje de-programación-c
 
Presentacion1 lenguaje de-programacion_c
Presentacion1 lenguaje de-programacion_cPresentacion1 lenguaje de-programacion_c
Presentacion1 lenguaje de-programacion_c
 
Sintaxis de lenguaje de programacion
Sintaxis de lenguaje de programacionSintaxis de lenguaje de programacion
Sintaxis de lenguaje de programacion
 
Introduccion al lenguaje de programacion c
Introduccion al lenguaje de programacion cIntroduccion al lenguaje de programacion c
Introduccion al lenguaje de programacion c
 
Introduccion del Lenguaje C
Introduccion del Lenguaje CIntroduccion del Lenguaje C
Introduccion del Lenguaje C
 
LENGUAJE DE PROGRAMACION C++ INTRODUCCION
LENGUAJE DE PROGRAMACION C++ INTRODUCCIONLENGUAJE DE PROGRAMACION C++ INTRODUCCION
LENGUAJE DE PROGRAMACION C++ INTRODUCCION
 
PROGRAMACION EN C
PROGRAMACION EN CPROGRAMACION EN C
PROGRAMACION EN C
 
Lenguaje Borland C - Estructura y Componentes
Lenguaje Borland C - Estructura y ComponentesLenguaje Borland C - Estructura y Componentes
Lenguaje Borland C - Estructura y Componentes
 
Lenguaje c
Lenguaje c Lenguaje c
Lenguaje c
 
Lenguaje de programacion en c
Lenguaje de programacion en cLenguaje de programacion en c
Lenguaje de programacion en c
 
Estructura de Lenguaje C++
Estructura de Lenguaje C++Estructura de Lenguaje C++
Estructura de Lenguaje C++
 
Clase 1 Lenguaje C++
Clase 1 Lenguaje C++Clase 1 Lenguaje C++
Clase 1 Lenguaje C++
 
Repaso del lenguaje C++
Repaso del lenguaje C++Repaso del lenguaje C++
Repaso del lenguaje C++
 
Guia referencia mc
Guia referencia mcGuia referencia mc
Guia referencia mc
 
Transparencias4
Transparencias4Transparencias4
Transparencias4
 

Destacado

Specifications week 16
Specifications week 16Specifications week 16
Specifications week 16
Alison Hardy
 
Literacy assessment case study
Literacy assessment case studyLiteracy assessment case study
Literacy assessment case study
Julia Becker
 
What is the curriculum and how is it designed
What is the curriculum and how is it designedWhat is the curriculum and how is it designed
What is the curriculum and how is it designed
Alison Hardy
 
Pregnancy and the symptoms of pregnancy to watch
Pregnancy and the symptoms of pregnancy to watchPregnancy and the symptoms of pregnancy to watch
Pregnancy and the symptoms of pregnancy to watch
Ronald Reviews
 

Destacado (20)

Specifications week 16
Specifications week 16Specifications week 16
Specifications week 16
 
Plantilla de gant
Plantilla de gantPlantilla de gant
Plantilla de gant
 
Literacy assessment case study
Literacy assessment case studyLiteracy assessment case study
Literacy assessment case study
 
Mobile marketing
Mobile marketingMobile marketing
Mobile marketing
 
Referral program
Referral programReferral program
Referral program
 
What is the curriculum and how is it designed
What is the curriculum and how is it designedWhat is the curriculum and how is it designed
What is the curriculum and how is it designed
 
Defending a school subject (Sweden)
Defending a school subject (Sweden)Defending a school subject (Sweden)
Defending a school subject (Sweden)
 
Sugars of carbohydrates!
Sugars of carbohydrates!Sugars of carbohydrates!
Sugars of carbohydrates!
 
Voicemail as a science
Voicemail as a science  Voicemail as a science
Voicemail as a science
 
Music Video Analysis
Music Video Analysis Music Video Analysis
Music Video Analysis
 
Developing an ITE framework for D&T (TERC 2012)
Developing an ITE framework for D&T (TERC 2012)Developing an ITE framework for D&T (TERC 2012)
Developing an ITE framework for D&T (TERC 2012)
 
DTES2: Session 1
DTES2: Session 1DTES2: Session 1
DTES2: Session 1
 
Christmas- The true meanings of colors and symbols/ Le vraie sens de Noel sy...
Christmas- The true meanings of  colors and symbols/ Le vraie sens de Noel sy...Christmas- The true meanings of  colors and symbols/ Le vraie sens de Noel sy...
Christmas- The true meanings of colors and symbols/ Le vraie sens de Noel sy...
 
Engaging pre-service teachers in the modernization of the secondary school de...
Engaging pre-service teachers in the modernization of the secondary school de...Engaging pre-service teachers in the modernization of the secondary school de...
Engaging pre-service teachers in the modernization of the secondary school de...
 
Globalização
GlobalizaçãoGlobalização
Globalização
 
Pregnancy and the symptoms of pregnancy to watch
Pregnancy and the symptoms of pregnancy to watchPregnancy and the symptoms of pregnancy to watch
Pregnancy and the symptoms of pregnancy to watch
 
Compensation speakasia-
Compensation speakasia-Compensation speakasia-
Compensation speakasia-
 
Ntu characteristics of performance
Ntu characteristics of performanceNtu characteristics of performance
Ntu characteristics of performance
 
General info th en
General info th enGeneral info th en
General info th en
 
Memoria dinamica
Memoria dinamicaMemoria dinamica
Memoria dinamica
 

Similar a Punteros y funciones abril agosto 2016

Lenguajec 1
Lenguajec 1Lenguajec 1
Lenguajec 1
joeshego
 
12 13 dominguez simon duran william programacion 29 10-2019
12 13 dominguez simon duran william programacion 29 10-201912 13 dominguez simon duran william programacion 29 10-2019
12 13 dominguez simon duran william programacion 29 10-2019
William10050
 
1390229945 843 _lenguaje_c-introduccion
1390229945 843 _lenguaje_c-introduccion1390229945 843 _lenguaje_c-introduccion
1390229945 843 _lenguaje_c-introduccion
Jair BG
 
Intro a c sharp
Intro a c sharpIntro a c sharp
Intro a c sharp
starduslex
 

Similar a Punteros y funciones abril agosto 2016 (20)

Lenguaje C para Administradores de Red - Script II Punteros
Lenguaje C para Administradores de Red - Script II PunterosLenguaje C para Administradores de Red - Script II Punteros
Lenguaje C para Administradores de Red - Script II Punteros
 
Punteros en c
Punteros en cPunteros en c
Punteros en c
 
Lenguajec diapositivas
Lenguajec diapositivasLenguajec diapositivas
Lenguajec diapositivas
 
Lenguajec 1
Lenguajec 1Lenguajec 1
Lenguajec 1
 
Manual c++01
Manual c++01Manual c++01
Manual c++01
 
12 13 dominguez simon duran william programacion 29 10-2019
12 13 dominguez simon duran william programacion 29 10-201912 13 dominguez simon duran william programacion 29 10-2019
12 13 dominguez simon duran william programacion 29 10-2019
 
Cesar ivan lenguaje_c
Cesar ivan lenguaje_cCesar ivan lenguaje_c
Cesar ivan lenguaje_c
 
1390229945 843 _lenguaje_c-introduccion
1390229945 843 _lenguaje_c-introduccion1390229945 843 _lenguaje_c-introduccion
1390229945 843 _lenguaje_c-introduccion
 
Intro a c sharp
Intro a c sharpIntro a c sharp
Intro a c sharp
 
02. lenguaje c autor enrique vicente bonet esteban
02. lenguaje c autor enrique vicente bonet esteban02. lenguaje c autor enrique vicente bonet esteban
02. lenguaje c autor enrique vicente bonet esteban
 
Lenguaje c
Lenguaje cLenguaje c
Lenguaje c
 
Lenguaje C
Lenguaje CLenguaje C
Lenguaje C
 
Lenguaje c
Lenguaje cLenguaje c
Lenguaje c
 
Gran Libro de C en Español
Gran Libro de C en EspañolGran Libro de C en Español
Gran Libro de C en Español
 
Lenguaje c
Lenguaje cLenguaje c
Lenguaje c
 
ELEMENTOS DE PROGRA 30-05.pdf
ELEMENTOS DE PROGRA 30-05.pdfELEMENTOS DE PROGRA 30-05.pdf
ELEMENTOS DE PROGRA 30-05.pdf
 
Lenguaje de programación C
Lenguaje de programación CLenguaje de programación C
Lenguaje de programación C
 
Elementos basicos de_programacion
Elementos basicos de_programacionElementos basicos de_programacion
Elementos basicos de_programacion
 
Actividades 1 7
Actividades 1 7Actividades 1 7
Actividades 1 7
 
Actividades 1 7
Actividades 1 7Actividades 1 7
Actividades 1 7
 

Más de Cesar Oswaldo Osorio Agualongo

Más de Cesar Oswaldo Osorio Agualongo (20)

Aprendizaje de Lenguaje de Programación Python
Aprendizaje de Lenguaje de Programación PythonAprendizaje de Lenguaje de Programación Python
Aprendizaje de Lenguaje de Programación Python
 
Notas 2 do parcial
Notas 2 do parcialNotas 2 do parcial
Notas 2 do parcial
 
Repaso excel
Repaso excelRepaso excel
Repaso excel
 
Notas 2490
Notas 2490Notas 2490
Notas 2490
 
Notas 2625
Notas 2625Notas 2625
Notas 2625
 
Unidad 2 curso c
Unidad 2 curso cUnidad 2 curso c
Unidad 2 curso c
 
Parte i curso c
Parte i curso cParte i curso c
Parte i curso c
 
Memoria dinamica
Memoria dinamicaMemoria dinamica
Memoria dinamica
 
Material estudio c
Material estudio cMaterial estudio c
Material estudio c
 
Estructuras en c++
Estructuras en c++Estructuras en c++
Estructuras en c++
 
Practica 6 manejo de archivos v1
Practica 6 manejo de archivos v1Practica 6 manejo de archivos v1
Practica 6 manejo de archivos v1
 
Estructuras en c++
Estructuras en c++Estructuras en c++
Estructuras en c++
 
Funciones recursivas
Funciones recursivasFunciones recursivas
Funciones recursivas
 
Programacion semanal programacion i
Programacion semanal programacion iProgramacion semanal programacion i
Programacion semanal programacion i
 
Silabo programacion i abril2016 agosto2016
Silabo programacion i abril2016 agosto2016Silabo programacion i abril2016 agosto2016
Silabo programacion i abril2016 agosto2016
 
Gestion de archivos
Gestion de archivosGestion de archivos
Gestion de archivos
 
Definiciones lideres evaluado
Definiciones lideres evaluadoDefiniciones lideres evaluado
Definiciones lideres evaluado
 
Herencia
HerenciaHerencia
Herencia
 
Formato de proyecto
Formato de proyectoFormato de proyecto
Formato de proyecto
 
Carteles
CartelesCarteles
Carteles
 

Último

NUEVAS DIAPOSITIVAS POSGRADO Gestion Publica.pdf
NUEVAS DIAPOSITIVAS POSGRADO Gestion Publica.pdfNUEVAS DIAPOSITIVAS POSGRADO Gestion Publica.pdf
NUEVAS DIAPOSITIVAS POSGRADO Gestion Publica.pdf
UPTAIDELTACHIRA
 
6°_GRADO_-_MAYO_06 para sexto grado de primaria
6°_GRADO_-_MAYO_06 para sexto grado de primaria6°_GRADO_-_MAYO_06 para sexto grado de primaria
6°_GRADO_-_MAYO_06 para sexto grado de primaria
Wilian24
 
TALLER DE DEMOCRACIA Y GOBIERNO ESCOLAR-COMPETENCIAS N°3.docx
TALLER DE DEMOCRACIA Y GOBIERNO ESCOLAR-COMPETENCIAS N°3.docxTALLER DE DEMOCRACIA Y GOBIERNO ESCOLAR-COMPETENCIAS N°3.docx
TALLER DE DEMOCRACIA Y GOBIERNO ESCOLAR-COMPETENCIAS N°3.docx
NadiaMartnez11
 
RESULTADOS DE LA EVALUACIÓN DIAGNÓSTICA 2024 - ACTUALIZADA.pptx
RESULTADOS DE LA EVALUACIÓN DIAGNÓSTICA 2024 - ACTUALIZADA.pptxRESULTADOS DE LA EVALUACIÓN DIAGNÓSTICA 2024 - ACTUALIZADA.pptx
RESULTADOS DE LA EVALUACIÓN DIAGNÓSTICA 2024 - ACTUALIZADA.pptx
pvtablets2023
 
TEMA 14.DERIVACIONES ECONÓMICAS, SOCIALES Y POLÍTICAS DEL PROCESO DE INTEGRAC...
TEMA 14.DERIVACIONES ECONÓMICAS, SOCIALES Y POLÍTICAS DEL PROCESO DE INTEGRAC...TEMA 14.DERIVACIONES ECONÓMICAS, SOCIALES Y POLÍTICAS DEL PROCESO DE INTEGRAC...
TEMA 14.DERIVACIONES ECONÓMICAS, SOCIALES Y POLÍTICAS DEL PROCESO DE INTEGRAC...
jlorentemartos
 

Último (20)

Plan-de-la-Patria-2019-2025- TERCER PLAN SOCIALISTA DE LA NACIÓN.pdf
Plan-de-la-Patria-2019-2025- TERCER PLAN SOCIALISTA DE LA NACIÓN.pdfPlan-de-la-Patria-2019-2025- TERCER PLAN SOCIALISTA DE LA NACIÓN.pdf
Plan-de-la-Patria-2019-2025- TERCER PLAN SOCIALISTA DE LA NACIÓN.pdf
 
Infografía EE con pie del 2023 (3)-1.pdf
Infografía EE con pie del 2023 (3)-1.pdfInfografía EE con pie del 2023 (3)-1.pdf
Infografía EE con pie del 2023 (3)-1.pdf
 
NUEVAS DIAPOSITIVAS POSGRADO Gestion Publica.pdf
NUEVAS DIAPOSITIVAS POSGRADO Gestion Publica.pdfNUEVAS DIAPOSITIVAS POSGRADO Gestion Publica.pdf
NUEVAS DIAPOSITIVAS POSGRADO Gestion Publica.pdf
 
Usos y desusos de la inteligencia artificial en revistas científicas
Usos y desusos de la inteligencia artificial en revistas científicasUsos y desusos de la inteligencia artificial en revistas científicas
Usos y desusos de la inteligencia artificial en revistas científicas
 
6°_GRADO_-_MAYO_06 para sexto grado de primaria
6°_GRADO_-_MAYO_06 para sexto grado de primaria6°_GRADO_-_MAYO_06 para sexto grado de primaria
6°_GRADO_-_MAYO_06 para sexto grado de primaria
 
Prueba de evaluación Geografía e Historia Comunidad de Madrid 4ºESO
Prueba de evaluación Geografía e Historia Comunidad de Madrid 4ºESOPrueba de evaluación Geografía e Historia Comunidad de Madrid 4ºESO
Prueba de evaluación Geografía e Historia Comunidad de Madrid 4ºESO
 
PINTURA DEL RENACIMIENTO EN ESPAÑA (SIGLO XVI).ppt
PINTURA DEL RENACIMIENTO EN ESPAÑA (SIGLO XVI).pptPINTURA DEL RENACIMIENTO EN ESPAÑA (SIGLO XVI).ppt
PINTURA DEL RENACIMIENTO EN ESPAÑA (SIGLO XVI).ppt
 
Factores que intervienen en la Administración por Valores.pdf
Factores que intervienen en la Administración por Valores.pdfFactores que intervienen en la Administración por Valores.pdf
Factores que intervienen en la Administración por Valores.pdf
 
Power Point E. S.: Los dos testigos.pptx
Power Point E. S.: Los dos testigos.pptxPower Point E. S.: Los dos testigos.pptx
Power Point E. S.: Los dos testigos.pptx
 
Lecciones 06 Esc. Sabática. Los dos testigos
Lecciones 06 Esc. Sabática. Los dos testigosLecciones 06 Esc. Sabática. Los dos testigos
Lecciones 06 Esc. Sabática. Los dos testigos
 
Los avatares para el juego dramático en entornos virtuales
Los avatares para el juego dramático en entornos virtualesLos avatares para el juego dramático en entornos virtuales
Los avatares para el juego dramático en entornos virtuales
 
semana 4 9NO Estudios sociales.pptxnnnn
semana 4  9NO Estudios sociales.pptxnnnnsemana 4  9NO Estudios sociales.pptxnnnn
semana 4 9NO Estudios sociales.pptxnnnn
 
SISTEMA RESPIRATORIO PARA NIÑOS PRIMARIA
SISTEMA RESPIRATORIO PARA NIÑOS PRIMARIASISTEMA RESPIRATORIO PARA NIÑOS PRIMARIA
SISTEMA RESPIRATORIO PARA NIÑOS PRIMARIA
 
Tema 11. Dinámica de la hidrosfera 2024
Tema 11.  Dinámica de la hidrosfera 2024Tema 11.  Dinámica de la hidrosfera 2024
Tema 11. Dinámica de la hidrosfera 2024
 
TALLER DE DEMOCRACIA Y GOBIERNO ESCOLAR-COMPETENCIAS N°3.docx
TALLER DE DEMOCRACIA Y GOBIERNO ESCOLAR-COMPETENCIAS N°3.docxTALLER DE DEMOCRACIA Y GOBIERNO ESCOLAR-COMPETENCIAS N°3.docx
TALLER DE DEMOCRACIA Y GOBIERNO ESCOLAR-COMPETENCIAS N°3.docx
 
RESULTADOS DE LA EVALUACIÓN DIAGNÓSTICA 2024 - ACTUALIZADA.pptx
RESULTADOS DE LA EVALUACIÓN DIAGNÓSTICA 2024 - ACTUALIZADA.pptxRESULTADOS DE LA EVALUACIÓN DIAGNÓSTICA 2024 - ACTUALIZADA.pptx
RESULTADOS DE LA EVALUACIÓN DIAGNÓSTICA 2024 - ACTUALIZADA.pptx
 
ACRÓNIMO DE PARÍS PARA SU OLIMPIADA 2024. Por JAVIER SOLIS NOYOLA
ACRÓNIMO DE PARÍS PARA SU OLIMPIADA 2024. Por JAVIER SOLIS NOYOLAACRÓNIMO DE PARÍS PARA SU OLIMPIADA 2024. Por JAVIER SOLIS NOYOLA
ACRÓNIMO DE PARÍS PARA SU OLIMPIADA 2024. Por JAVIER SOLIS NOYOLA
 
Análisis de los Factores Externos de la Organización.
Análisis de los Factores Externos de la Organización.Análisis de los Factores Externos de la Organización.
Análisis de los Factores Externos de la Organización.
 
TEMA 14.DERIVACIONES ECONÓMICAS, SOCIALES Y POLÍTICAS DEL PROCESO DE INTEGRAC...
TEMA 14.DERIVACIONES ECONÓMICAS, SOCIALES Y POLÍTICAS DEL PROCESO DE INTEGRAC...TEMA 14.DERIVACIONES ECONÓMICAS, SOCIALES Y POLÍTICAS DEL PROCESO DE INTEGRAC...
TEMA 14.DERIVACIONES ECONÓMICAS, SOCIALES Y POLÍTICAS DEL PROCESO DE INTEGRAC...
 
Biografía de Charles Coulomb física .pdf
Biografía de Charles Coulomb física .pdfBiografía de Charles Coulomb física .pdf
Biografía de Charles Coulomb física .pdf
 

Punteros y funciones abril agosto 2016

  • 1. Lenguaje C Para Estudiantes de Programación I Script II - Punteros
  • 2. Lenguaje C ¿Por qué punteros ahora? Después de todo, hablar de Lenguaje C es casi como hablar de punteros. Esta en todas partes del lenguaje y esta en todas sus librerías estándar. Casi todo tiene que ver con ellos de una u otra forma. Y por desgracia, se requiere buena disciplina para usarlos. Todo programador novato se ha roto la cabeza intentando explicarse porque un simple printf termina en una violación de segmento o porque no compila su programa y se soluciona colocando caracteres extraños como & y * Estoy convencido que mientras más rápido usemos los punteros, más rápido aprenderemos el lenguaje C y menos errores sin sentido nos agobiaran al programar. Conocer lo que hace a este lenguaje tan poderoso sin duda nos dará la mejor de las ventajas
  • 3. Lenguaje C MAXIMA: «Sin punteros no hay paraíso…»
  • 5. Lenguaje C Script II – Punteros en C >> Repasando las Variables >> Usando Variables >> Los operadores & y *& >> Qué es un puntero >> Puntero Endemoniado >> Tipos de datos básicos para punteros >> Asignación de punteros >> Funciones en C >> Paso de punteros a funciones >> Punteros y Arrays >> Punteros y Cadenas >> Arrays de Punteros >> Punteros a Punteros >> Punteros NULL y VOID >> Punteros constantes >> Punteros a funciones >> Callbacks >> Bonus Track - Recomendaciones
  • 6. Lenguaje C REPASANDO LAS VARIABLES Como ya sabemos, las variables en el lenguaje C tienen 5 elementos que debemos tener presente: 1. Nombre de la Variable 2.Tipo de Dato 3.Tamaño 4.Valor 5.Dirección de Memoria Para comprender el uso de punteros es indispensable conocer el uso de las variables. Un error muy común es desconocer la relación entre estos elementos y como se almacenan 10 edad int 0xf0113b1 32 bits
  • 7. Lenguaje C REPASANDO LAS VARIABLES Para empezar a utilizar punteros en C, debemos prestar especial atención a las direcciones de memoria. Aunque parezca mentira, y a pesar de que casi no las miramos, las direcciones de memoria son la clave para entender las bases del uso de punteros. Saber usar una dirección de memoria y el valor de una dirección de memoria es el quebradero de cabeza mas común en miles de programadores en todo el mundo. 10 edad int 0xf0113b1 32 bits
  • 8. Lenguaje C USANDO VARIABLES edad int ¿Cómo acceder a los elementos de una variable? Tanto el tipo de dato int como el nombre de la variable edad no pueden ser accedidos de ninguna manera. Esto se debe a que el Lenguaje C no soporta características reflexivas que permitan conocer detalles de las variables en tiempo de ejecución. Esto nos da a entender que somos responsables de conocer bien todas las variables que utilizamos y de conocer sus tipos de datos. El resto de los elementos (tamaño, valor y dirección de memoria) si pueden ser conocidos y accedidos en tiempo de ejecución. Saber como hacerlo es el primer paso para entender a los punteros
  • 9. Lenguaje C USANDO VARIABLES edad int 32 bits ¿Cómo saber el tamaño de una variable? La función sizeof() nos permite calcular el tamaño en bytes de una determinada variable. El resultado debe ser multiplicado por 8 si queremos conocer el valor en bits int edad; sizeof(edad); sizeof(unsigned int);
  • 10. Tipos básicos de datos • Las variables tipo char se usan para almacenar caracteres ASCII como “A”,”1”,”&”, etc. • Cuando se desea trabajar con enteros, dependiendo del rango, se puede usar short, int o long, con signo o sin signo. • Para trabajar con enteros sin signo, se debe anteponer la palabra reservada unsigned delante del tipo (unsigned int). Esto nos permite aumentar el rango del tipo. • Por defecto son con signo, no hace falta anteponer la palabra signed.
  • 11. Tipos de variables Programación en C 11 long double 96 18 3.3621e-4932 1.18973e+493
  • 12. Lenguaje C USANDO VARIABLES 10 edad int 32 bits ¿Cómo ver o alterar el valor de una variable? Es broma ! Simplemente hacemos referencia a ella por su nombre en cualquier asignación o función
  • 13. Lenguaje C USANDO VARIABLES 10 edad int 0x7fff2960d0ac 32 bits ¿Cómo saber la dirección de memoria de una variable? Para saber la dirección de memoria de cualquier variable debemos usar el signo ampersand (&) ATENCION ! Las direcciones de memoria cambian con cada ejecución
  • 14. ESPECIFICADORES DE FORMATO PARA SCANF Y PRINTF
  • 15. SECUENCIAS DE ESCAPE EN C Cuando estamos escribiendo un programa puede que necesitemos representar la información de una forma especial, con ciertas alineaciones, tabulaciones o estilos, en C es posible realizar estas tareas mediante las llamadas secuencias de escape.
  • 16. Lenguaje C Los operadores & y *& 10 edad int 0x7fff2960d0ac& *& ¿Qué significan estos símbolos? & = Referencia o Dirección de Memoria *& = Dereferencia, Indirección, Valor de dirección de memoria, Valor Apuntado
  • 17. Lenguaje C Los operadores & y *& 10 edad int 0x7f5f0ac USO DE LOS OPERADORES Estos operadores se usan con cualquier objeto en memoria (variables, estructuras, arrays, funciones, etc), sin embargo no pueden ser aplicadas a expresiones, constantes o variables del tipo register El operador & nos devolverá la dirección de memoria. Así de simple &edad 0x7f5f0ac *&edad 10 0x7f5f0ac 10*
  • 18. Lenguaje C Los operadores & y *& 10 edad int 0x7f5f0ac &edad 0x7f5f0ac *&edad 10 USO DE LOS OPERADORES El operador * tiene varios usos. Uno de ellos es la Indirección el cual permite acceder al valor guardado en una dirección de memoria. Para efectuar una indirección es indispensable que el operador * se aplique a una dirección de memoria (por ejemplo *0x7f5f0ac) 0x7f5f0ac 10*
  • 19. Lenguaje C Los operadores & y *& DEMOSTRADO La dirección de memoria se puede obtener al usar el operador & en cualquier variable El operador de indirección (*) es aplicado a direcciones de memoria y permite acceder al valor almacenado en ella Las direcciones de memoria pueden utilizarse en su forma hexadecimal Nota: Debido a que las direcciones memoria son asignadas en tiempo de ejecución, no es sencillo saber que dirección ocupara una determinada variable. Es por eso que se ha utilizado el depurador gdb para hacer esta demostración
  • 20. Lenguaje C Los operadores & y *& 10 edad int 0x7f5f0ac *&edad 0x7f5f0ac * 10VALGAN VERDADES A nadie en su sano juicio se le ocurrirá utilizar una dirección de memoria dentro del código fuente. Ni que decir de la sentencia *&edad. ¿Para que alguien tendría que utilizar esta extraña sintaxis cuando simplemente puede usar la variable con su simple nombre?. edad = 10; // Este modo es el mas cuerdo *&edad = 10; // A quien se le ocurriría usar esto por Dios ! *0x7f5f0ac = 10; // Definitivamente ya no tiene amigos ¿CUAL USARIAS ?
  • 21. Lenguaje C QUE ES UN PUNTERO ¿Recuerdan que nadie en su sano juicio usaría la sentencia así: *0x7f5f0ac? Un puntero da solución a ese problema !. Conocer las direcciones de memoria brinda lo que hace al lenguaje C tan potente y requerido: Su velocidad. Un puntero es una variable especial capaz de guardar una dirección de memoria de tal forma que no tenemos que recurrir a escribirlas dentro del código. Al poder guardar cualquier dirección de memoria, un puntero puede tomar posesión de cualquier variable de su tipo y literalmente jugar con ella 10 edad int 0x7f5f0ac 0x7f5f0ac ptr int* 0x503fb43
  • 22. 22 Un puntero es un objeto que apunta a otro objeto. Es decir, una variable cuyo valor es la dirección de memoria de otra variable. Las direcciones de memoria dependen de la arquitectura del ordenador y de la gestión que el sistema operativo haga de ella. Punteros Lenguaje C
  • 23. Lenguaje C QUE ES UN PUNTERO Examinando un Puntero Un puntero es una variable, y como tal, tiene todos los elementos de cualquier variable (tipo de dato, nombre, tamaño y dirección de memoria) . La única diferencia visible es que al declararla, su tipo de dato debe ir acompañado del símbolo * Debido a que debe contener direcciones de memoria, su tamaño debe ser lo suficientemente grande para poder guardar cualquier dirección de memoria del sistema operativo. Por esta razón es muy común que su tamaño sea de 64 bits (8 bytes) que son suficientes para hacer referencia a muchos terabytes de memoria 0x7f5f0ac ptr int* 0x503fb43 64 bits
  • 24. Lenguaje C QUE ES UN PUNTERO Declaración de un puntero En mi humilde opinión, la confusión de muchos programadores se debe a que el símbolo * se usa para diferentes cosas, entre ellas para declarar un puntero. int *ptr = &edad; *ptr = 19; El código anterior demuestra la facilidad con la que puede confundir a mas de un programador puesto que se puede llegar erróneamente a deducir que el puntero ptr puede guardar valores como el 19 y direcciones de memoria como &edad. Lo cual es peligroso asumir 0x7f5f0ac ptr int* 0x503fb43 64 bits
  • 25. Lenguaje C QUE ES UN PUNTERO Declaración de un puntero A pesar que la gran mayoría utiliza la declaración del modo int *ptr como la normal, usar la siguiente declaración ayuda a evitar confundirla con la indirección: int* ptr = &edad; *ptr = 19; El código anterior separa claramente lo que es la variable puntero ptr y lo que es la operación de indirección al puntero ptr. Al parecer el estándar C99 se percato de esto y recomendó crear tipos de datos como intptr_t y uintptr_t que no hacen mas que retirar el signo * de la declaración de un puntero 0x7f5f0ac ptr int* 0x503fb43 64 bits
  • 26. Lenguaje C QUE ES UN PUNTERO DEMOSTRADO Un puntero guarda direcciones de memoria. Así mismo un puntero al ser una variable, tiene su propia dirección de memoria Con la indirección no solo accedemos al valor de la variable apuntada, sino que también podemos modificar su valor. Un puntero obtiene su valor a partir de la referencia de una variable que se consigue con el operador & El tamaño de un puntero puede ser obtenido mediante la función sizeof()
  • 27. Punteros Programación en C 27 • Los gestión de punteros admite dos operadores básicos: – Si px es un puntero (dirección): *px es el contenido del puntero (el valor almacenado en la dirección). – Si x es una variable: &x es la dirección de memoria donde está almacenada la variable.
  • 28. Punteros int main() { int *px,y=3; px=&y; /* px apunta a y */ *px=5; /* y vale 5 */ } Programación en C 28 Dirección px-> 35: y -> 39: Contenido Gráfica ? ? ? ? 0 0 0 3 ? px 3 y px-> 35: y -> 39: 0 0 0 39 0 0 0 3 39 3 y px px-> 35: y -> 39: 0 0 0 39 0 0 0 5 39 5 y px
  • 29. Punteros Programación en C 29 La declaración de punteros genéricos a direcciones se asocian al tipo void. Declarar una variable (que no sea un puntero) de tipo void no tiene sentido. Ejemplo: void *px,v; /* La variable v está mal declarada */
  • 30. Lenguaje C PUNTERO ENDEMONIADO ¿Por qué los punteros tienen fama de ser complicados? La desventaja de los punteros es que debemos ser muy disciplinados en su uso y no es tarea fácil. Entre los errores mas comunes tenemos • Punteros no inicializados • Asignación de punteros errónea • Punteros con tipos distintos • Indirección errónea • Uso incorrecto de punteros nulos Como podrás apreciar, son muchas cosas las que pueden ir mal, es por eso que los punteros requieren especial atención y cuidado 0x7f5f0ac ptr int* 0x503fb43 64 bits
  • 31. Lenguaje C PUNTERO ENDEMONIADO Punteros no inicializados Todo puntero ANTES de ser utilizado debe ser inicializado apropiadamente. Es decir, su valor debe ser NULO o debe contener la dirección de memoria de una variable de su tipo de dato. int edad = 10; int* p; *p = 19; Si un puntero no esta inicializado y hace uso de la operación indirección se produce una Violación de Segmento y el programa terminará de forma abrupta
  • 32. Lenguaje C PUNTERO ENDEMONIADO Violación de Segmento Lamentablemente cuando se declara un puntero, toma como valor inicial una dirección aleatoria usualmente fuera del segmento de memoria del programa. La Violación de Segmento se produce porque un programa intenta modificar o acceder a un segmento de memoria que no le corresponde. El Sistema Operativo al detectar esta intrusión se protege y detiene el programa ‘agresor’ indicando que ha violado un segmento que no le corresponde.
  • 33. Lenguaje C PUNTERO ENDEMONIADO Inicialización de puntero errónea Otro error común es olvidar colocar el signo ampersand (&) al inicializar un puntero. Con ello se consigue que el puntero guarde el valor de la variable y no su dirección de memoria, la cual al ser accedida provoca una violación de segmento En el ejemplo que vemos, erróneamente le estamos indicando que la dirección de memoria guardada por ptr será la posición 0x10 (lo que guarda la variable edad). Luego intentaremos cambiar el valor de la posición 0x10 a 19 lo cual produce un crash en nuestro programa
  • 34. Lenguaje C PUNTERO ENDEMONIADO Punteros con tipos de datos distintos Los punteros deben ser declarados según el tipo de dato al que apuntarán. Si un puntero apunta a una variable cuyo tipo de dato es distinto puede convertirse en un problema si el tamaño del tipo de dato al que se apunta es menor. En el ejemplo podemos ver un puntero de tipo int haciendo referencia a la dirección de una variable de tipo char. Esto conlleva a que se produzca un desborde y el programa se detenga por producir una violación de segmento ya que ptr usara 4 bytes y no 1
  • 35. Lenguaje C PUNTERO ENDEMONIADO Indirección errónea Al ser la operación mas común de un puntero, la indirección será errónea siempre y cuando la declaración o incialización este mal hecha La indirección en si misma no es un error. El error viene al usarla en un contexto erróneo. En el ejemplo podemos ver que la indirección no produce una violación de segmento, pero ha sido un error alterar el valor mediante la indirección debido a que estamos desbordando una variable de tipo char
  • 36. Lenguaje C PUNTERO ENDEMONIADO Uso incorrecto de punteros nulos El lenguaje C permite nulificar un puntero para evitar acceder de forma accidental a otra dirección de memoria fuera de nuestro segmento permitido. Sin embargo, veamos que pasa cuando no utilizamos adecuadamente los punteros nulos En el ejemplo podemos ver que a pesar de poner un puntero a NULL podemos causar problemas si realizamos una indirección. Esto naturalmente tiene sentido debido a que la dirección 0x0 (NULL) no puede ser alterada.
  • 37. Lenguaje C TIPOS DE DATOS BASICOS PARA PUNTEROS ¿Y a que tipos de datos puedo apuntar? En realidad, podemos apuntar a cualquier tipo de dato que usemos en el Lenguaje C Los tipos de datos comunes suelen ser los tipos de datos básicos a los cuales un puntero podrá hacer referencia. Incluso podemos usar el puntero void* que nos permite apuntar a cualquier tipo de dato. El resto de punteros solo puede apuntar a su tipo de datos ( por ejemplo el puntero float* solo podrá apuntar a variables float, etc) char* int* float* double* void*
  • 38. Lenguaje C ASIGNACION DE PUNTEROS La clave en el uso de todo puntero es su correcta asignación (inicialización). La asignación de punteros es una operación que permite indicar que dirección de memoria tomará un puntero determinado. Hay 2 tipos de asignación de punteros • Asignación de variable a puntero • Asignación de puntero a puntero La primera es la habitual, que permite apuntar a una variable determinada. 0x7f5f0ac ptr int* 0x503fb43 64 bits
  • 39. Lenguaje C ASIGNACION DE PUNTEROS Asignación de variable a puntero Para asignar una variable a un puntero podemos usar la declaración del puntero int edad = 10; int* ptr = &edad; Sin embargo, también podemos usar esta forma int edad = 10; int* ptr; ptr = &edad; La 2da forma no se recomienda por ser peligrosa 0x7f5f0ac ptr int* 0x503fb43 64 bits
  • 40. Lenguaje C ASIGNACION DE PUNTEROS Asignación de puntero a puntero Una característica muy útil es que los punteros pueden compartir sus datos entre si. Es decir, mas de un puntero puede apuntar a la misma variable int edad = 10; int* ptr1 = &edad; int* ptr2 = ptr1; // No requiere & *ptr2 = 19; La ventaja es que lo que cambia un puntero se ve reflejado en el otro. Solo debemos tener en cuenta que al asignar un puntero a otro, NO ES NECESARIO usar el signo &
  • 41. Sobre una variable puntero se pueden realizar una serie de operaciones que veremos a continuación: − Dirección: el operador de dirección no es realmente uno que se aplique sobre las variables puntero (normalmente), sino sobre otros tipos de variable. Éste operador, representado con el símbolo ampersand (&) obtiene la dirección de memoria de la variable a la que precede. Así, si la variable entera w está almacenada en la posición de memoria 32012, la operación int *punt; punt= &w; asignará el valor 32012 a la variable punt. − Indirección: el operador de desreferenciación o de indirección sí se aplica a valores de tipo puntero. Éste operador se representa por un asterisco (*) y devuelve un valor del tipo apuntado por el operando. Este valor es el contenido en la posición apuntada por el puntero. Así, en el siguiente código float *p; float q= 1.44; p= &q; print("%fn", *p); el valor que se imprime es 1.44, ya que p apunta a la dirección de q. En general, si el puntero x apunta a un tipo de datos T, la expresión *x es de tipo T. OPERACIONES CON LOS PUNTEROS
  • 42. Asignación de punteros: Es posible asignar una dirección de una variable a un puntero (ej1) Es posible asignar el contenido de un puntero a otro puntero (ej2) OPERACIONES CON LOS PUNTEROS
  • 43. Aritmética de punteros: Se trata de sumar y restar, incrementar o decrementar variables de tipo puntero Debe entenderse como cambios en la dirección a la que apunta el puntero (se produce un cambio en la dirección de memoria contenida en el puntero). El incremento o decremento de un puntero depende exclusivamente del tipo de dato base dado en la declaración del puntero. Al declarar un puntero es necesario indicar a qué tipo de dato apunta para que cuando se utilicen los incrementos o decrementos se conozca cuánto hay que sumar o restar. La operación de sumar 1 a un puntero hace que su dirección se incremente la cantidad necesaria para pasar a apuntar al siguiente dato del mismo tipo (cantidad que coincide con el número de bytes que ocupa dicho tipo de dato). Por lo tanto, sólo en el caso de variables que ocupan 1 byte en memoria (variables de tipo “char”) la operación de incremento aumenta en 1 la dirección de memoria; en los demás casos aumenta más. OPERACIONES CON LOS PUNTEROS
  • 44. − Incremento, decremento: los valores de tipo puntero se pueden incrementar y decrementar, siempre en valores enteros. Se admiten los operadores ’+’ , ’−’ , ’++’ y ’−−’. OPERACIONES CON LOS PUNTEROS
  • 47.
  • 48.
  • 49. Arrays y punteros El identificador de una variable array tiene el valor de la dirección de comienzo del mismo. Por lo tanto, su valor puede usarse como un puntero. int *pb,*pc; int a[5]={10,20,30,40,50}; pb=a; *pb=11; pc=&a[3]; *pc=44; Programación en C 49 10 20 30 40 50a pb pc 11 20 30 40 50a pb pc 11 20 30 44 50a pb pc
  • 50. #include <stdio.h> main() { int v[10]; int i, *p; for (i=0; i < 10; i++) v[i] = i; for (i=0; i < 10; i++) printf ("n%d", v[i]); p = v; for (i=0; i < 10; i++) printf ("n%d", *p++); /* Tras cada p++ el puntero señala a la siguiente posición en v */ return 0; } RECORRIDO DE UN VECTOR UTILIZANDO ÍNDICES Y PUNTEROS
  • 51.
  • 52.
  • 53. Punteros y vectores • Una de las aplicaciones más frecuentes de los punteros es el manejo de vectores y cadenas de caracteres. • Como todos los elementos de un vector se almacenan en posiciones consecutivas de memoria, basta conocer la posición de memoria del primer elemento para poder recorrer todo el vector con un puntero.
  • 54.
  • 55.
  • 56.
  • 57. Lenguaje C PUNTEROS Y ARRAYS Existe una estrecha relación entre los punteros y los arrays…(eso ya no suena a novedad). De hecho están tan relacionados que todas las operaciones que se realizan con arrays pueden ser realizadas por punteros. La diferencia claro esta es que con punteros las cosas van mas rápido char a[4+1] = «HOLA0»; char* ptr = &a[0]; a a[0] a[1] a[2] a[3] a[4] ‘H’ ‘O’ ‘L’ ‘A’ ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f90x765d3 0x503f5 char* ptr
  • 58. Lenguaje C PUNTEROS Y ARRAYS Operación con Punteros Equivalente en Array char a[4+1] = «HOLA0»; char* ptr = &a[0]; *ptr = ‘F’; a a[0] a[1] a[2] a[3] a[4] ‘F’ ‘O’ ‘L’ ‘A’ ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f90x765d3 0x503f5 char* ptr char a[4+1] = «HOLA0»; a[0] = ‘F’;
  • 59. Lenguaje C PUNTEROS Y ARRAYS Operación con Punteros Equivalente en Array char a[4+1] = «HOLA0»; char* ptr = &a[0]; *ptr = ‘F’; ptr=ptr+2; *ptr = ‘C’; a a[0] a[1] a[2] a[3] a[4] ‘F’ ‘O’ ‘C’ ‘A’ ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f90x765d3 0x503f7 char* ptr char a[4+1] = «HOLA0»; a[0] = ‘F’; a[2] = ‘C’;
  • 60. Lenguaje C PUNTEROS Y ARRAYS Aritmética de Punteros a a[0] a[1] a[2] a[3] a[4] ‘H’ ‘O’ ‘L’ ‘A’ ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f90x765d3 0x503f5 char* ptr ptr+1 ptr+2 *(ptr+3) ptr+4 A un puntero se le puede sumar o restar un número entero, lo cual es usado para moverse por un array. Aplicando el operador ++ o -- a un puntero se consigue que avance a la siguiente dirección de memoria o a la anterior según sea el caso
  • 61. Lenguaje C PUNTEROS Y ARRAYS Aritmética de Punteros a a[0] a[1] a[2] a[3] a[4] ‘H’ ‘O’ ‘L’ ‘A’ ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f90x765d3 0x503f5 char* ptr ptr+1 ptr+2 *(ptr+3) ptr+4 Operaciones Aritmeticas no permitidas: • Sumar, Multiplicar o Dividir 2 punteros
  • 62. Lenguaje C PUNTEROS Y ARRAYS Diferencias? a a[0] a[1] a[2] a[3] a[4] ‘H’ ‘O’ ‘L’ ‘A’ ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f90x765d3 0x503f5 char* ptr Por diseño, un array se comporta como un puntero, en el sentido en que un array es un ‘sinónimo’ para la dirección de memoria del elemento inicial. Esto quiere decir, que según el ejemplo el array a tiene el mismo valor que ptr ptr+1 ptr+2 *(ptr+3) ptr+4 *(a+3)*(a+0) *(a+1) *(a+2) *(a+4)
  • 63. Lenguaje C PUNTEROS Y ARRAYS Diferencias? a 0x765d3 0x503f5 char* ptr Esto quiere decir que la sentencia ptr = a es equivalente a ptr = &a[0] ptr+1 ptr+2 *(ptr+3) ptr+4 Incluso podemos ver que la referencia de a[i] puede ser escrita como *(a+i) donde i es el índice del array. De hecho el lenguaje C hace esta conversión de forma interna para todo array a[0] a[1] a[2] a[3] a[4] ‘H’ ‘O’ ‘L’ ‘A’ ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9 ptr+1 ptr+2 *(ptr+3) ptr+4 *(a+3)*(a+0) *(a+1) *(a+2) *(a+4)
  • 64. Lenguaje C PUNTEROS Y ARRAYS Diferencias a 0x765d3 0x503f5 char* ptr Solo hay una diferencia entre un puntero y un array Siguiendo el ejemplo: El puntero ptr es una variable, pero el nombre del array a no lo es por lo tanto sentencias como a++ o a=ptr no son permitidas. Un nombre de array es un puntero constante dado que no puede agregar ni eliminar elementos a su lista a[0] a[1] a[2] a[3] a[4] ‘H’ ‘O’ ‘L’ ‘A’ ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9
  • 65. Lenguaje C PUNTEROS Y ARRAYS Demostrado !
  • 66. Lenguaje C PUNTEROS Y CADENAS ¿Que es una cadena? os 0x765d3 0x503f5 char* ptr Una cadena no es mas que un array de tipo char El lenguaje C NO existe el tipo de dato string, pero mediante arrays se puede conseguir el tratamiento de cadenas de caracteres sin la cual cualquier lenguaje de programación no serviría de mucho. os[0] os[1] os[2] os[3] os[4] ‘U’ ‘N’ ‘I’ ‘X’ ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9 char os[4+1] = «UNIX0»;
  • 67. Lenguaje C PUNTEROS Y CADENAS ¿Que es una cadena? os 0x765d3 0x503f5 char* ptr Las cadenas son un elemento tan importante que es quizá sin exagerar el aspecto más crítico en el Lenguaje C. La gran mayoría de problemas de seguridad se deben al inadecuado uso de las cadenas. Incluso el propio lenguaje nos ofrece funciones que son inseguras debido a que delegan toda la responsabilidad del correcto tratamiento de cadenas al programador. Hemos ingresado ya en terreno minado ! os[0] os[1] os[2] os[3] os[4] ‘U’ ‘N’ ‘I’ ‘X’ ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9 char os[4+1] = «UNIX0»;
  • 68. Lenguaje C PUNTEROS Y CADENAS Marcando el final os 0x765d3 0x503f5 char* ptr El gran problema con las cadenas es que debemos indicar donde terminan, es decir debemos indicarle explícitamente cual es el final de una cadena, asignarle una marca que permita al lenguaje C reconocer donde detenerse. Incluso si una cadena no utiliza todos sus elementos debemos indicarlo de lo contrario algo podría explotar Esa marca es el carácter NULL o también denotado por el símbolo ‘0’ os[0] os[1] os[2] os[3] os[4] ‘U’ ‘N’ ‘I’ ‘X’ ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9 char os[4+1] = «UNIX0»;
  • 69. Lenguaje C PUNTEROS Y CADENAS El origen de todos los males En el ejemplo podemos apreciar un error muy común (y sobretodo peligroso) en el manejo de cadenas: El Desbodarmiento. Aparentemente se ve inofensivo, pero en realidad copiar una cadena de mayor tamaño en una menor ocasiona que se sobrescriba memoria ajena que puede detener el programa e incluso poner en riesgo todo un sistema. os[0] os[1] os[2] os[3] os[4] ‘W’ ‘I’ ‘N’ ‘D’ ‘O’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9 char os[4+1]; strcpy(os, «WINDOWS7»); printf(«%s»,os); memoria no reservada ‘W’ ‘S’ ‘ 7’ 0x503fa 0x503fb 0x503fc
  • 70. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Copiado ‘U’ ‘N’ ‘I’ ‘X’‘¡’ ‘?’ ‘$’ ‘0’ ‘?’ ‘U’ ‘N’ ‘I’ ‘X’ ‘0’ auxos char* strcpy(os, aux) os CODIGO char os[4+1]; char aux[4] = «UNIX»; strcpy(os,aux); Nótese que en el ejemplo, la variable os al ser declarada su valor es aleatorio (debido a que no ha sido inicializada). Así también se puede apreciar que la función strcpy agrega al final de la cadena el delimitador nulo (‘0’).
  • 71. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Copiado ‘W’ ‘I’ ‘N’ ‘D’‘U’ ‘N’ ‘I’ ‘X’ ‘0’ ‘W’ ‘I’ ‘N’ ‘X’ ‘0’ auxos char* strncpy(os, aux,3) os CODIGO char os[4+1]=«UNIX0»; char aux[7] = «WINDOWS»; strncpy(os,aux,3); La función strncpy también copia cadenas, sin embargo podemos indicarle el número de caracteres a copiar. En el ejemplo vemos que solo se copiaran 3 caracteres de la cadena aux en la cadena os. Nótese que el carácter X aun permanece ‘O’ ‘W’ ‘0’
  • 72. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Concatenar ‘X’ ‘P’ ‘0’‘W’ ‘I’ ‘N’ ‘0’ ‘8’ ‘W’ ‘I’ ‘N’ ‘X’ ‘P’ auxos char* strcat(os, aux) os CODIGO char os[5+1]=«WIN08Z»; char aux[2] = «XP»; strcat(os,aux); La función strcat permite copiar una cadena al final de otra. Podemos ver como se copia la cadena XP al final de la variable os. Nótese como la función considera al carácter nulo (‘0’) de os como final cuando realmente no lo es. Al final le agrega el signo ‘0’ ‘Z’ ‘0’
  • 73. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Concatenar ‘W’ ‘I’ ‘N’ ‘D’‘U’ ‘0’ ‘I’ ‘X’ ‘0’ ‘U’ ‘W’ ‘I’ ‘N’ ‘0’ auxos char* strncat(os, aux,3) os CODIGO char os[4+1]=«U0IX0»; char aux[7] = «WINDOW0»; strncat(os,aux,3); La función strncat también concatena cadenas, sin embargo podemos indicarle el número de caracteres a concatenar. En el ejemplo vemos que solo se concatenarán 3 caracteres de la cadena aux en la cadena os. ‘O’ ‘W’ ‘0’
  • 74. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Comparar ‘U’ ‘N’ ‘I’ ‘X’‘U’ ‘N’ ‘I’ ‘X’ ‘0’ auxos int strcmp(os, aux) CODIGO char os[5]=«UNIX0»; char aux[5] = «UNIX0»; int r = strcmp(os,aux); La función strcmp es diferente puesto que devuelve un valor entero. Compara 2 cadenas y evalúa su similitud. Si las cadenas son iguales retorna el valor cero (0). Es importante recordar que la evaluación diferencia mayúsculas de minúsculas (p.e A es distinto de a) ‘0’ 0r
  • 75. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Comparar ‘I’ ‘O’ ‘S’ ‘4’‘U’ ‘N’ ‘I’ ‘X’ ‘0’ auxos int strcmp(os, aux) CODIGO char os[5]=«UNIX0»; char aux[5] = «WIN70»; int r = strcmp(os,aux); La función strcmp devuelve un número positivo (>0) si la primera cadena enviada es mayor que la segunda. ¿Cómo puede ser una cadena mayor que otra?. Se comparan sus valores. Por ejemplo la letra U=85 mientras que la I=73. Luego se devuelve la diferencia de ambas ‘0’ 12r
  • 76. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Comparar ‘P’ ‘H’ ‘P’ ‘5’‘P’ ‘E’ ‘R’ ‘L’ ‘0’ auxlang int strcmp(lang, aux) CODIGO char lang[5]=«PERL0»; char aux[5] = «PHP50»; int r = strcmp(lang,aux); La función strcmp devuelve un número negativo(<0) si la primera cadena es menor que la segunda. ¿Cómo puede ser una cadena menor que otra?. Se comparan sus valores uno por uno. Por ejemplo la letra E=69 mientras que la H=72. Luego se devuelve 69-72=-3 ‘0’ -3r
  • 77. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Comparar ‘P’ ‘H’ ‘P’ ‘5’‘P’ ‘H’ ‘P’ ‘4’ ‘0’ auxlang int strncmp(lang, aux,3) CODIGO char lang[5]=«PHP40»; char aux[5] = «PHP50»; int r = strncmp(lang,aux,3); La función strncmp funciona con la misma lógica que strcmp. La única diferencia es que solo toma en cuenta la comparación de N caracteres indicados. En el ejemplo, el resultado es 0 debido a que solo se comparan los 3 primeros caracteres que resultan ser iguales ‘0’ 0r
  • 78. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Búsqueda ‘H’‘P’ ‘H’ ‘P’ ‘4’ ‘0’ auxlang char* strchr(lang, aux) CODIGO char lang[5]=«PHP40»; char aux= «H»; char* ptr; ptr = strchr(lang,aux); La función strchr permite buscar una cadena dentro de otra. Si la encuentra devuelve un puntero en la primera ocurrencia, caso contrario devolverá un puntero a NULL. En el ejemplo se busca el carácter H dentro de PHP4 retornando un puntero a la posición 1 ptr
  • 79. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Búsqueda ‘P’‘P’ ‘H’ ‘P’ ‘4’ ‘0’ auxlang char* strrchr(lang, aux) CODIGO char lang[5]=«PHP40»; char aux= «P»; char* ptr; ptr = strrchr(lang,aux); La función strrchr devuelve la ultima ocurrencia de una cadena. En el ejemplo podemos ver que la función retorna un puntero a la posición nro 2 en lugar de la posición 0. Es decir, devuelve la ultima ocurrencia de la letra P que ha sido buscada. ptr
  • 80. Lenguaje C ARRAYS DE PUNTEROS Como funcionan ‘L’ ‘I’ ‘N’ ‘U’ ‘X’ Un array de punteros funciona de forma similar a un array de cualquier otro tipo de datos. Donde cada elemento puede apuntar a un valor del tipo de dato declarado previamente. En el ejemplo podemos apreciar como se declara un array de 3 elementos que contienen punteros a char. Incluso podemos inicializar de forma inmediata sus valores. ‘0’ ‘W’ ‘I’ ‘N’ ‘D’ ‘O’ ‘W’ ‘S’ ‘0’ ‘U’ ‘N’ ‘I’ ‘X’ ‘0’ osptr 0 1 2 char* osptr[3]={«LINUX0», «WINDOWS0», «UNIX0»};

Notas del editor

  1. 22