Punteros y funciones

112
Lenguaje C Programación I Script II - Punteros

Transcript of Punteros y funciones

Page 1: Punteros y funciones

Lenguaje CProgramación I

Script II - Punteros

Page 2: Punteros y funciones

Lenguaje C

¿Por qué punteros ahora?

Después de todo, hablar de Lenguaje C es casi como hablar de punteros. Esta en todaspartes del lenguaje y esta en todas sus librerías estándar. Casi todo tiene que ver conellos 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 simpleprintf termina en una violación de segmento o porque no compila su programa y sesoluciona colocando caracteres extraños como & y *

Estoy convencido que mientras más rápido usemos los punteros, más rápidoaprenderemos 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 lasventajas

Page 3: Punteros y funciones

Lenguaje C

Punteros en C

SCRIPT II

Page 4: Punteros y funciones

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

Page 5: Punteros y funciones

Lenguaje C

REPASANDO LAS VARIABLES

Como ya sabemos, las variables en ellenguaje C tienen 5 elementos quedebemos tener presente:

1. Nombre de la Variable2.Tipo de Dato3.Tamaño4.Valor5.Dirección de Memoria

Para comprender el uso de punteros esindispensable conocer el uso de lasvariables. Un error muy común esdesconocer la relación entre estoselementos y como se almacenan

10edad

int

0xf0113b1

32 bits

Page 6: Punteros y funciones

Lenguaje C

REPASANDO LAS VARIABLES

Para empezar a utilizar punteros en C,debemos prestar especial atención a lasdirecciones de memoria.

Aunque parezca mentira, y a pesar de quecasi no las miramos, las direcciones dememoria son la clave para entender lasbases del uso de punteros. Saber usar unadirección de memoria y el valor de unadirección de memoria es el quebradero decabeza mas común en miles deprogramadores en todo el mundo.

10edad

int

0xf0113b1

32 bits

Page 7: Punteros y funciones

• La memoria es un conjunto de celdas contiguas donde se almacenan datos.

• La unidad de memoria más pequeña es el bit.

• El byte es un conjunto de 8 bits. Unidad de memoria.

• El lugar (ubicación) de cada byte es único y es su dirección.

• Si los bytes son consecutivos la dirección se ira incrementando secuencialmente.

• Cada celda tiene dos valores asociados: Dirección y Contenido.

1 2 3 4 5 6 7 8 9 A B C D E F

1 0 1 1 0 0 1 1

171 186 137 99

10101011 10111010 10001001 1100011

Dirección:0xC100

Dirección +1: 0xC101

Dirección + 3: 0xC103

Celda: Valor Decimal

Celda: Valor Binario

Memoria.

Page 8: Punteros y funciones

• Una variable es una porción de memoria identificada por un nombre.• El tipo de dato define su representación binaria y longitud.• Tiene tres valores asociados: Nombre, Contenido y Dirección.

• Declaramos: “int n=1523, m=121;”

• Contenido:– n 1523– m 121

• Dirección: – &n C102– &m C100

• Es contenido binario se codifica (bits) de acuerdo al tipo de variable.

0000000 01111001 00000101 11110011

Dirección: C100 Dirección: C102

Valor: 121 Valor: 1523

Variables.

Page 9: Punteros y funciones

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 lavariable edad no pueden ser accedidos de ningunamanera. Esto se debe a que el Lenguaje C nosoporta características reflexivas que permitanconocer detalles de las variables en tiempo deejecución.

Esto nos da a entender que somos responsables deconocer bien todas las variables que utilizamos y deconocer sus tipos de datos.

El resto de los elementos (tamaño, valor y direcciónde memoria) si pueden ser conocidos y accedidosen tiempo de ejecución. Saber como hacerlo es elprimer paso para entender a los punteros

Page 10: Punteros y funciones

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);

Page 11: Punteros y funciones

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.

Page 12: Punteros y funciones

Tipos de variables

Programación en C 12

long double 96 18 3.3621e-4932 1.18973e+493

Page 13: Punteros y funciones

Lenguaje C

USANDO VARIABLES

10

edad

int

32 bits

¿Cómo ver o alterar el valor de una variable?

Simplemente hacemos referencia a ella por su nombre en cualquier asignación o función

Page 14: Punteros y funciones

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

Page 15: Punteros y funciones

ESPECIFICADORES DE FORMATO PARA SCANF Y PRINTF

Page 16: Punteros y funciones

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

Page 17: Punteros y funciones

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 100x7f5f0ac 10*

Page 18: Punteros y funciones

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*

Page 19: Punteros y funciones

Lenguaje C

Los operadores & y *&DEMOSTRADO

La dirección de memoria se puedeobtener al usar el operador & encualquier variable

El operador de indirección (*) esaplicado a direcciones de memoriay permite acceder al valoralmacenado en ella

Las direcciones de memoriapueden utilizarse en su formahexadecimal

Nota: Debido a que las direcciones memoria son asignadas en tiempo deejecución, no es sencillo saber que dirección ocupara una determinada variable.

Page 20: Punteros y funciones

Lenguaje C

Los operadores & y *&

10 edad

int

0x7f5f0ac

*&edad

0x7f5f0ac*10

VALGAN 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 ?

Page 21: Punteros y funciones

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

Page 22: Punteros y funciones

23

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

Page 23: Punteros y funciones

Lenguaje C

QUE ES UN PUNTEROExaminando 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

Page 24: Punteros y funciones

Lenguaje C

QUE ES UN PUNTERODeclaración de un puntero

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

Page 25: Punteros y funciones

Lenguaje C

QUE ES UN PUNTERODEMOSTRADO

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()

Page 26: Punteros y funciones

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.

Page 27: Punteros y funciones

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 339

3

y

px

px-> 35:

y -> 39:

0 0 0 39

0 0 0 539

5

y

px

Page 28: Punteros y funciones

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 */

Page 29: Punteros y funciones

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

Page 30: Punteros y funciones

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

Page 31: Punteros y funciones

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.

Page 32: Punteros y funciones

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

Page 33: Punteros y funciones

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

Page 34: Punteros y funciones

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ónno 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

Page 35: Punteros y funciones

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.

Page 36: Punteros y funciones

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*

Page 37: Punteros y funciones

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

Page 38: Punteros y funciones

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

Page 39: Punteros y funciones

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 &

Page 40: Punteros y funciones

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 variablespuntero (normalmente), sino sobre otros tipos de variable. Éste operador, representado conel 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ónint *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 tipopuntero. Éste operador se representa por un asterisco (*) y devuelve un valor del tipoapuntado por el operando. Este valor es el contenido en la posición apuntada por el puntero.Así, en el siguiente códigofloat *p; float q= 1.44;p= &q; print("%f\n", *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

Page 41: Punteros y funciones

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

Page 42: Punteros y funciones

Aritmética de punteros: Se trata de sumar y restar, incrementar o decrementarvariables de tipo puntero Debe entenderse como cambios en la dirección a laque apunta el puntero (se produce un cambio en la dirección de memoriacontenida en el puntero). El incremento o decremento de un puntero dependeexclusivamente del tipo de dato base dado en la declaración del puntero. Aldeclarar un puntero es necesario indicar a qué tipo de dato apunta para quecuando se utilicen los incrementos o decrementos se conozca cuánto hay quesumar o restar. La operación de sumar 1 a un puntero hace que su dirección seincremente la cantidad necesaria para pasar a apuntar al siguiente dato delmismo tipo (cantidad que coincide con el número de bytes que ocupa dichotipo de dato). Por lo tanto, sólo en el caso de variables que ocupan 1 byte enmemoria (variables de tipo “char”) la operación de incremento aumenta en 1la dirección de memoria; en los demás casos aumenta más.

OPERACIONES CON LOS PUNTEROS

Page 43: Punteros y funciones

− 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

Page 44: Punteros y funciones

OPERACIONES CON LOS PUNTEROS

Page 45: Punteros y funciones

OPERACIONES CON LOS PUNTEROS

Page 46: Punteros y funciones
Page 47: Punteros y funciones
Page 48: Punteros y funciones

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

Page 49: Punteros y funciones

#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

Page 50: Punteros y funciones
Page 51: Punteros y funciones
Page 52: Punteros y funciones

Punteros y vectores

• Una de las aplicaciones más frecuentes de los punteros es el manejo de vectores ycadenas de caracteres.

• Como todos los elementos de un vector se almacenan en posiciones consecutivas dememoria, basta conocer la posición de memoria del primer elemento para poderrecorrer todo el vector con un puntero.

Page 53: Punteros y funciones
Page 54: Punteros y funciones
Page 55: Punteros y funciones
Page 56: Punteros y funciones

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] = «HOLA\0»;

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

Page 57: Punteros y funciones

Lenguaje C

PUNTEROS Y ARRAYS

Operación con Punteros Equivalente en Array

char a[4+1] = «HOLA\0»;

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] = «HOLA\0»;

a[0] = ‘F’;

Page 58: Punteros y funciones

Lenguaje C

PUNTEROS Y ARRAYS

Operación con Punteros Equivalente en Array

char a[4+1] = «HOLA\0»;

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] = «HOLA\0»;

a[0] = ‘F’;

a[2] = ‘C’;

Page 59: Punteros y funciones

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

Page 60: Punteros y funciones

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

Page 61: Punteros y funciones

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)

Page 62: Punteros y funciones

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)

Page 63: Punteros y funciones

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

Page 64: Punteros y funciones

Lenguaje C

PUNTEROS Y ARRAYS

Demostrado !

Page 65: Punteros y funciones

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] = «UNIX\0»;

Page 66: Punteros y funciones

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

os[0] os[1] os[2] os[3] os[4]

‘U’ ‘N’ ‘I’ ‘X’ ‘\0’

0x503f5 0x503f6 0x503f7 0x503f8 0x503f9

char os[4+1] = «UNIX\0»;

Page 67: Punteros y funciones

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] = «UNIX\0»;

Page 68: Punteros y funciones

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

Page 69: Punteros y funciones

Lenguaje C

PUNTEROS Y CADENAS

Operaciones comunes / Copiado

‘U’ ‘N’ ‘I’ ‘X’‘¡’ ‘?’ ‘$’ ‘0’ ‘?’

‘U’ ‘N’ ‘I’ ‘X’ ‘\0’

auxos

char* strcpy(os, aux)

os

CODIGOchar os[4+1];char aux[5] = «UNIX»;strcpy(os,aux);

Nótese que en el ejemplo, la variable os al ser declarada su valor es aleatorio (debido aque no ha sido inicializada). Así también se puede apreciar que la función strcpy agrega alfinal de la cadena el delimitador nulo (‘\0’).

Page 70: Punteros y funciones

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

CODIGOchar os[4+1]=«UNIX\0»;char aux[7] = «WINDOW\0»;strncpy(os,aux,3);

La función strncpy también copia cadenas, sin embargo podemos indicarle el número decaracteres a copiar. En el ejemplo vemos que solo se copiaran 3 caracteres de la cadenaaux en la cadena os. Nótese que el carácter X aun permanece

‘O’ ‘W’ ‘\0’

Page 71: Punteros y funciones

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

CODIGOchar os[5+1]=«WIN\08Z»;char aux[2] = «XP»;strcat(os,aux);

La función strcat permite copiar una cadena al final de otra. Podemos ver como se copia lacadena 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’

Page 72: Punteros y funciones

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

CODIGOchar os[4+1]=«U\0IX\0»;char aux[7] = «WINDOW\0»;strncat(os,aux,3);

La función strncat también concatena cadenas, sin embargo podemos indicarle el númerode caracteres a concatenar. En el ejemplo vemos que solo se concatenarán 3 caracteres dela cadena aux en la cadena os.

‘O’ ‘W’ ‘\0’

Page 73: Punteros y funciones

Lenguaje C

PUNTEROS Y CADENAS

Operaciones comunes / Comparar

‘U’ ‘N’ ‘I’ ‘X’‘U’ ‘N’ ‘I’ ‘X’ ‘\0’ auxos

int strcmp(os, aux)CODIGOchar os[5]=«UNIX\0»;char aux[5] = «UNIX\0»;int r = strcmp(os,aux);

La función strcmp es diferente puesto que devuelve un valor entero. Compara 2 cadenas yevalúa su similitud. Si las cadenas son iguales retorna el valor cero (0). Es importanterecordar que la evaluación diferencia mayúsculas de minúsculas (p.e A es distinto de a)

‘\0’

0r

Page 74: Punteros y funciones

Lenguaje C

PUNTEROS Y CADENAS

Operaciones comunes / Comparar

‘I’ ‘O’ ‘S’ ‘4’‘U’ ‘N’ ‘I’ ‘X’ ‘\0’ auxos

int strcmp(os, aux)CODIGOchar os[5]=«UNIX\0»;char aux[5] = «WIN7\0»;int r = strcmp(os,aux);

La función strcmp devuelve un número positivo (>0) si la primera cadena enviada es mayorque 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

Page 75: Punteros y funciones

Lenguaje C

PUNTEROS Y CADENAS

Operaciones comunes / Comparar

‘P’ ‘H’ ‘P’ ‘5’‘P’ ‘E’ ‘R’ ‘L’ ‘\0’ auxlang

int strcmp(lang, aux)CODIGOchar lang[5]=«PERL\0»;char aux[5] = «PHP5\0»;int r = strcmp(lang,aux);

La función strcmp devuelve un número negativo(<0) si la primera cadena es menor que lasegunda. ¿Cómo puede ser una cadena menor que otra?. Se comparan sus valores uno poruno. Por ejemplo la letra E=69 mientras que la H=72. Luego se devuelve 69-72=-3

‘\0’

-3r

Page 76: Punteros y funciones

Lenguaje C

PUNTEROS Y CADENAS

Operaciones comunes / Comparar

‘P’ ‘H’ ‘P’ ‘5’‘P’ ‘H’ ‘P’ ‘4’ ‘\0’ auxlang

int strncmp(lang, aux,3)CODIGOchar lang[5]=«PHP4\0»;char aux[5] = «PHP5\0»;int r = strncmp(lang,aux,3);

La función strncmp funciona con la misma lógica que strcmp. La única diferencia es quesolo toma en cuenta la comparación de N caracteres indicados. En el ejemplo, el resultadoes 0 debido a que solo se comparan los 3 primeros caracteres que resultan ser iguales

‘\0’

0r

Page 77: Punteros y funciones

Lenguaje C

PUNTEROS Y CADENAS

Operaciones comunes / Búsqueda

‘H’‘P’ ‘H’ ‘P’ ‘4’ ‘\0’ auxlang

char* strchr(lang, aux)CODIGOchar lang[5]=«PHP4\0»;char aux= «H»;char* ptr;ptr = strchr(lang,aux);

La función strchr permite buscar una cadena dentro de otra. Si la encuentra devuelve unpuntero en la primera ocurrencia, caso contrario devolverá un puntero a NULL. En elejemplo se busca el carácter H dentro de PHP4 retornando un puntero a la posición 1

ptr

Page 78: Punteros y funciones

Lenguaje C

PUNTEROS Y CADENAS

Operaciones comunes / Búsqueda

‘P’‘P’ ‘H’ ‘P’ ‘4’ ‘\0’ auxlang

char* strrchr(lang, aux)CODIGOchar lang[5]=«PHP4\0»;char aux= «P»;char* ptr;ptr = strrchr(lang,aux);

La función strrchr devuelve la ultima ocurrencia de una cadena. En el ejemplo podemosver 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

Page 79: Punteros y funciones

Lenguaje CPUNTEROS TIPO VOID

Un puntero void es un puntero genérico, ya que puede apuntar acualquier dirección de memoria y/o a cualquier tipo de dato. Sedeclara como un puntero normal, pero con un tipo void *: void *p;// puntero void o puntero genéricoTenga en cuenta que:void *f; es un comando válidovoid f(); es un comando válidovoid f[]; es un comando erróneovoid f; es un comando erróneo

Page 80: Punteros y funciones

Lenguaje C

PUNTEROS NULL y VOID

Como funcionan

‘L’ ‘I’ ‘N’ ‘U’ ‘X’

El puntero NULL no apunta a ningún dato válido en memoria, por lo que es muy utilizadopara indicar cuando un puntero no contiene valor alguno.Por otro lado un puntero VOID puede apuntar a cualquier dato válido en memoria, sinimportar su tipo de dato. La única condición que debemos tener presente es saber bien eltipo de dato que se ha asignado en todo momento.

‘\0’

19

multi

0

1

2

void* multi[3];char os[5+1]=«LINUX\0»;int num=19;multi[0] = os;multi[1] = &num;multi[2] = NULL; NULL

os

num

Page 81: Punteros y funciones

Lenguaje C

PUNTEROS NULL y VOID

Como funcionan

El puntero VOID apunta a cualquier valor,pero no puede ser dereferenciado, es decirno se le puede aplicar la indirección a lamisma variable void.

Para poder usar una variable VOID,debemos primero convertir su valor a unpuntero del tipo de dato deseado.

En el ejemplo podemos apreciar como lavariable multi guarda 3 valores distintos, yaplicamos la indirección según sea su tipode dato

Page 82: Punteros y funciones

Lenguaje CPUNTEROS TIPO VOID

Page 83: Punteros y funciones

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 contienenpunteros 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]={«LINUX\0», «WINDOWS\0», «UNIX\0»};

Page 84: Punteros y funciones

zsLenguaje C ARRAYS DE PUNTEROS

Page 85: Punteros y funciones

Lenguaje C ARRAYS DE PUNTEROS

Page 86: Punteros y funciones

• Un puntero puede almacenar una dirección de otro puntero.

• El valor final apuntado puede obtenerse en forma directa.

• “int n, *j, **p”; hacemos “n=4562”; “j=&n”; “p=&j”;

• Supongamos que:

• &n 0x3021

• &j 0x4310 Entonces:

• &p 0x4F02

• Interpretación:

– Con el valor de p obtiene la dirección de j: *p &j

– Con el valor de j obtiene la dirección de n: *j &n

– Con el tipo de p interpreta el valor de n.

– Esta es la secuencia de **p

Punteros de Punteros

p 0x4310

*p j 0x3021

**p *j 4562

*(*(p)) 4562

*( j ) 4562

n 4562

Page 87: Punteros y funciones

Lenguaje C

PUNTEROS A PUNTEROS

Un puntero a puntero funciona de forma similar que cualquier puntero. Nada más queapunta a otras variables de tipo puntero. Se usa mucho para apuntar a un array depunteros a char. Debido a que su sintaxis es un poco intimidante los programadores suelenevitarla. Sin embargo solo se necesita seguir la misma lógica de un puntero normal pero de2do nivel.

osptr

‘L’ ‘I’ ‘N’ ‘U’ ‘X’ ‘\0’

‘W’ ‘I’ ‘N’ ‘D’ ‘O’ ‘W’ ‘S’ ‘\0’

‘U’ ‘N’ ‘I’ ‘X’ ‘\0’

0

1

2

char* osptr[3]={«LINUX\0», «WINDOWS\0», «UNIX\0»};char** ptrptr = osptr;

ptrptr

Page 88: Punteros y funciones

Lenguaje C

PUNTEROS CONSTANTES

¿Constante?

El lenguaje C nos permite trabajar convariables constantes. Es decir, variables cuyovalor una vez seteados no pueden seralterados bajo ninguna condición

Para ilustrarlo mejor, vemos el ejemplodonde la variable uid es una constante detipo int. Si intentamos cambiar su valor en eltranscurso del programa obtendremos unerror

Usualmente vemos errores en tiempo decompilación si hacemos el cambio en elmismo código fuente

Page 89: Punteros y funciones

Lenguaje C

PUNTEROS CONSTANTES

¿Constante?

Hay situaciones en las que deseamos queun puntero sea constante, es decir que suvalor (la dirección de memoria que guarda)no se pueda alterar. Para conseguir estodebemos usar la siguiente sintaxis:

const <tipo>* variable

Ejemplo:const int* ptr;

Nótese en el ejemplo que la variableapuntada (uid) puede ser alterada (ya quees una variable int y no const int)

Page 90: Punteros y funciones
Page 91: Punteros y funciones
Page 92: Punteros y funciones
Page 93: Punteros y funciones
Page 94: Punteros y funciones

El hecho de que las declaraciones en C incluyan modificadores prefijos y postfijossimultáneamente puede conducir a confusión y error. He aquí algunas forma dedeclarar estructuras de datos con punteros

1. int a[10]; En el primer caso tenemos un vector de diez enteros2. int **b; Un puntero a un puntero a entero;3. int *c[10]; Un vector de diez punteros a entero;4. int (*d)[10]; Un puntero a un vector de diez enteros;5. int *e[10][20]; Un vector de diez punteros a vector de veinte enteros;6. int (*f)[10][20]; Un vector de 10×20 enteros.

DECLARACIONES COMPLEJAS

Page 95: Punteros y funciones

Lenguaje C

FUNCIONES EN C

¿Funciones?????

Sí. Los punteros que usaras estarán en su gran mayoría relacionados con el uso de funciones. Repasaremos brevemente para que sirven las funciones

Las funciones en C nos permiten dividir porciones de código que resuelven un problema determinado. La ventaja es que una vez que hemos creado una función, podemos reutilizarla las veces que necesitemos sin duplicar código. Incluso podemos tener cientos de funciones agrupadas en librerías y poder utilizarlas en otros programas.

Las funciones tienen las siguientes partes

• Prototipo• Declaración• Nombre• Parámetros

• Código Fuente• Ambito• Tipo de Dato• Valor de Retorno (opcional)

Page 96: Punteros y funciones

Lenguaje C

FUNCIONES EN C

PARTES DE UNA FUNCION

El prototipo es una copia de la declaración de la función que debe ir antes de la función main.

El código es como cualquier otro código C dentro del ámbito de su función.

Podemos realizar la llamada indicando el nombre de la función y el envío de sus argumentos

Page 97: Punteros y funciones

Lenguaje C

FUNCIONES EN C

int get_uid(int userid){

userid = userid + 500; return userid;

}

Código fuente de la función

ParámetrosNombre

Valor de Retorno

Tipo de dato del valor de Retorno

Declaración / Prototipo

Por Valor

Por Referencia

Delimitadoresde Ambito de

la Función

Page 98: Punteros y funciones

Lenguaje C

PASO DE PUNTEROS A FUNCIONES

¿Y los punteros?

Las funciones en C por diseño tienen un detalle que se pasa inadvertido cuando se programa. Ese detalle es su manejo de los parámetros.

Ya sean enviados por valor o por referencia, todas las variables que se ‘reciben’ en una función, en realidad son creadas in-situ es decir, son copias de dichas variables con sus propias direcciones de memoria.

Es decir, en el lenguaje C, técnicamente no existe el envío de variables a una función

int get_uid(int userid){

userid = userid + 500; return userid;

}

Page 99: Punteros y funciones

Lenguaje C

PASO DE PUNTEROS A FUNCIONES

¿Y cual es el problema con que técnicamente no se puedan enviar variables a funciones?

Muy simple, al no poder enviarlas, no se pueden manipular sus valores dentro de las funciones

Pero existe un mecanismo que si nos permitirá hacerlo. Ese mecanismo es el uso de punteros !

En teoría, si envío un puntero a una función, la función creara una copia del puntero y luego dentro de su código al manipular la copia del puntero, en realidad estará modificando nuestra variable que originalmente enviamos

void get_uid(int* userid){

*userid += 500;}

Page 100: Punteros y funciones

Lenguaje C

PASO DE PUNTEROS A FUNCIONES

DEMOSTRADO !

Los parámetros de una función son variables nuevas con su propia dirección de memoria.

Mediante el paso de punteros a funciones, se puede alterar las variables ‘enviadas’ sin necesidad de que la función tenga un valor de retorno. Este tipo de función se denomina Procedure (Procedimiento)

Page 101: Punteros y funciones

Lenguaje C

PASO DE PUNTEROS A FUNCIONES

¿Cómo pasamos punteros a una función?

Existen 2 formas

Una es mediante punteros, y otra es mediante la referencia (&) de cualquier variable. De una u otra manera, lo que nos interesa es enviar direcciones de memoria.

Siguiendo el ejemplo, podemos ver que la llamada a la función get_uid se le pasa el puntero ptr. Nótese que el puntero ptr es un puntero de tipo int que hace referencia a la variable uid.

Asegúrese de enviar punteros que referencien a una variable, sino habrán problemas

int uid = 1;int* ptr = &uid;get_uid(ptr);

void get_uid(int* userid){

*userid += 500;}

Page 102: Punteros y funciones

Lenguaje C

PASO DE PUNTEROS A FUNCIONES

¿Cómo pasamos punteros a una función?

La otra forma es no usar punteros !

¿Qué cosa?

Así es, como lo leyó. Solo basta cualquier variable común y silvestre para enviarla como si fuera un puntero. Solo hace falta enviar su referencia como parte del argumento de la función

En el ejemplo, podemos apreciar que no necesitamos crear un puntero y apuntarlo a la variable uid. Únicamente enviamos la referencia de la variable

int uid = 1;get_uid(&uid);…

void get_uid(int* userid){

*userid += 500;}

Page 103: Punteros y funciones

Lenguaje C

ARRAYS DE PUNTEROS

Paso de array de punteros a funciones

Al igual que el paso de arrays a unafunción se puede realizar de 2 formas. Elenvío de un array de punteros tambiéntiene 2 modalidades

La primera es mediante la siguientesintaxis en el envío de parámetro de lafunción:

<tipo>* variable[ ]

Por ejemplo:

void join(char* lista[ ], int ne)

Page 104: Punteros y funciones

Lenguaje C

ARRAYS DE PUNTEROS

Paso de array de punteros a funciones

La 2da forma resulta en un quebraderode cabeza para muchos programadoresya que se trata del uso de puntero apuntero

Esto se consigue con la siguiente sintaxis

<tipo>** variable

Por ejemplo:

void join(char** lista, int ne)

Page 105: Punteros y funciones

Lenguaje C

PUNTEROS Y ARRAYS

Envío de Arrays a Funciones

Es muy común enviar arrays completos auna función. Sin embargo resulta unpoco confuso hacerlo debido a queexisten 2 formas de hacerlo

La primera es declarando el array en elprototipo de la función de la siguientemanera:

<tipo> variable[ ]

Por ejemplo:

int suma(int lista[ ], int ne)

Page 106: Punteros y funciones

Lenguaje C

PUNTEROS Y ARRAYS

Envío de Arrays a Funciones

La segunda forma es declarando el arrayen el prototipo de la función medianteun puntero normal:

Por ejemplo:

int suma(int* lista, int ne)

En cualquiera de las 2 formas, debemostener presente algo muy importante: Elnro de elementos del array enviado sedebe conocer. Es usual enviar el nro deelementos como parte de la función

Page 107: Punteros y funciones

Lenguaje C

PUNTEROS A FUNCIONES

Como funcionan

En el ejemplo, podemos apreciar el puntero f que apunta a la función suma. Nóteseque tiene el mismo número de parámetros y el tipo de datos de retorno.Así mismo, solo basta una asignación simple para apuntar a dicha función

f

int (*f)(short, short);

f = suma;…int suma(short a, short b){

return (int) a+b;}

SI ya se dieron cuenta, e lenguaje Cpermite apuntar a casi todo ser vivo. Lasfunciones por lo tanto también puedenser apuntadas.

Solo debemos declarar el puntero deforma similar al prototipo de la funciónque queremos apuntar:

tipo (*variable)(argumentos,…)

Page 108: Punteros y funciones

Lenguaje C

PUNTEROS A FUNCIONES

Como se usan

Bien, ya sabemos declarar y asignar unpuntero a una función, ahora veremoscomo utilizarlos

Simplemente debemos llamarlos de lasiguiente manera:

(*variable)(argumentos,…)

Ejemplo:

(*f)(1,2);

Es un poco raro pero funciona !

Page 109: Punteros y funciones

Lenguaje C

CALLBACKS

Que son

Una callback es un mecanismo deprogramación por la cual se ejecuta unafunción X dentro de otra función Y con laparticularidad de reemplazar la función Xpor cualquier otra en tiempo de ejecución

Esto se consigue enviando a una función Yun argumento de tipo puntero a función

Este mecanismo es muy utilizado enfunciones avanzadas del sistema operativopara permitir una gran flexibilidad almomento de programar.

Page 110: Punteros y funciones

Lenguaje C

BONUS TRACK - RECOMENDACIONES

Todo con disciplina

Aquí algunas recomendaciones que pueden servir para mejorar nuestro uso de punteros

• Utiliza nombres con prefijos (como ptr) para indicar que se trata de un puntero• Escoge un modo de declarar y asignar punteros y no lo cambies• Usa el signo & solo para asignaciones de punteros• Inicializa cada puntero una vez que lo has declarado• Asegúrate siempre de validar si un puntero es nulo• Inicializa toda cadena que usarás a nulo (vía memset por ejemplo)• Reserva siempre 1 carácter más para el signo ‘\0’ y hazlo visible (p.e. char aux[4+1])• Toda cadena constante, que uses, termínala con el signo ‘\0’• Usa las funciones seguras de cadenas (las que piden el nro de elementos)• No pierdas de vista el número de elementos de un puntero a un array• Valida siempre los límites de un array• Piensa 4 veces cada indirección que programes

Page 111: Punteros y funciones

Lenguaje C

Anexos¿Qué necesito para programar en C bajo Linux?

gcc, gdb, vim

¿Cómo compilar un programa C en Linux?

gcc mi-programa.c -g -o mi-programa.exe

¿Cómo depurar un programa C en Linux?

gdb mi-programa.exe

¿Qué necesito para programar en C bajo Windows?

Visual C++ ó Borland C ó C Builder, etc

Nota: La extensión .exe es solo para referencia sencilla de que se trata de un ejecutable, no es necesario por lo tanto agregarle dicha extensión en realidad

Nota: Si se desea programar con el estándar C11 se deberá obtener una copia del compilador gcc 4.8.1.

Page 112: Punteros y funciones

Lenguaje C

BibliografiaThe C Programming Language, 2nd Edition, B. Kernighan, Dennis Ritchie.

The Art and Science of C, Eric S. Roberts.

Programming in C, 3rd Edition, Stephen G. Kochan

Programación en C, Metodología, algoritmos y estructura de datos. Luis Joyanes Aguilar

C Programming A Modern Approach. Second Edition. K.K.King

Pointers and Memory. Standford CS Education Library. Nick Parlante