SlideShare una empresa de Scribd logo
1 de 79
Lenguaje C
Para Administradores de
Red
Script II - Punteros
Fernando I. Díaz Sánchez
Lenguaje C
¿Por qué punteros ahora?
De todos los libros de C que existen, creo que ninguno de ellos se atreve a enseñar el
tema de punteros al segundo capítulo. Sin embargo no conocer sobre punteros lo antes
posible creo que fue para muchos la razón por la que abandonaron el lenguaje C y le
temieron desde el principio.
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 ( y administrador de red) 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
>>Fids
Lenguaje C

MAXIMA: «Sin punteros
no hay paraíso…»
Lenguaje C

SCRIPT II

Punteros en C
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

int

Como ya sabemos, las variables en el
lenguaje C tienen 5 elementos que
debemos tener presente:
32 bits
Nombre de la Variable
Tipo de Dato
Tamaño
Valor
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

0xf0113b1

edad
Lenguaje C

REPASANDO LAS VARIABLES

int

Para empezar a utilizar punteros en C,
debemos prestar especial atención a las
direcciones de memoria.
32 bits
¿Oiga, no me estará engañando verdad?
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.
Y la culpa no la tienen ellos…

10

0xf0113b1

edad
Lenguaje C

USANDO VARIABLES

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

int
edad

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

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
32 bits

¿Cómo saber el tamaño de una variable?

edad
Lenguaje C

USANDO VARIABLES

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

int
32 bits

10

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

edad
Lenguaje C

USANDO VARIABLES

Para saber la dirección de memoria de cualquier
variable debemos usar el signo ampersand (&)

int
32 bits

¿Cómo saber la dirección de memoria de una
variable?

edad

10
0x7fff2960d0ac
ATENCION !
Las direcciones de memoria
cambian con cada ejecución
Lenguaje C

Los operadores & y *&

&
*
&

int

10

edad

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 *&
int
10

edad

0x7f5f0ac

&edad 0x7f5f0ac
&edad 10
*0x7f5f0ac 10
*

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
Lenguaje C

Los operadores & y *&
int
10

edad

0x7f5f0ac

&edad 0x7f5f0ac
&edad 10
*0x7f5f0ac 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)
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 *&
int
10

edad

0x7f5f0ac
VALGAN VERDADES

&edad
*

*

0x7f5f0ac

10

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;
*&edad = 10;
*0x7f5f0ac = 10;

// Este modo es el mas cuerdo
// A quien se le ocurriría usar esto por Dios !
// 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

int*
0x7f5f0ac

0x503fb43

int

ptr

10
0x7f5f0ac

edad
Lenguaje C

QUE ES UN PUNTERO
Examinando un Puntero

int*
64 bits

0x7f5f0ac

0x503fb43

ptr

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
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*
64 bits

0x7f5f0ac

0x503fb43

ptr

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
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*
64 bits

0x7f5f0ac

0x503fb43

ptr

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

int*
64 bits

0x7f5f0ac

0x503fb43

ptr
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

char*
int*
float*
double*
void*

¿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)
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.

int*
64 bits

0x7f5f0ac

0x503fb43

ptr
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

int*
64 bits

0x7f5f0ac

0x503fb43

ptr
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;
*ptr2 = 19;

// No requiere &

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 &
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)
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
Lenguaje C

FUNCIONES EN C
Nombre

Tipo de dato del
valor de Retorno

Delimitadores
de Ambito de
la Función

Parámetros

Por Valor
Por Referencia

int get_uid(int userid)
{
userid = userid + 500;
return userid;
}
Valor de
Retorno

Declaración /
Prototipo

Código fuente de
la función
Lenguaje C

PASO DE PUNTEROS A FUNCIONES
¿Y los punteros?
Paciencia !

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;
}
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;
}
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)
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;
}
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;
}
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[0]

char*
0x503f5

0x765d3

ptr

a

a[1]

a[2]

a[3]

a[4]

‘H’

‘O’

‘L’

‘A’

‘0’

0x503f5 0x503f6 0x503f7 0x503f8 0x503f9
Lenguaje C

PUNTEROS Y ARRAYS
Operación con Punteros

Equivalente en Array

char a[4+1] = «HOLA0»;
char* ptr = &a[0];
*ptr = ‘F’;

char a[4+1] = «HOLA0»;
a[0] = ‘F’;

a[0]

char*
0x503f5

0x765d3

ptr

a

a[1]

a[2]

a[3]

a[4]

‘F’

‘O’

‘L’

‘A’

‘0’

0x503f5 0x503f6 0x503f7 0x503f8 0x503f9
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’;

char a[4+1] = «HOLA0»;
a[0] = ‘F’;
a[2] = ‘C’;

a[0]

char*
0x503f7

0x765d3

ptr

a

a[1]

a[2]

a[3]

a[4]

‘F’

‘O’

‘C’

‘A’

‘0’

0x503f5 0x503f6 0x503f7 0x503f8 0x503f9
Lenguaje C

PUNTEROS Y ARRAYS
Aritmética de Punteros

a[0]

char*
0x503f5

0x765d3

ptr

a

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 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[0]

char*
0x503f5

0x765d3

ptr

a[1]

a[2]

a[3]

a[4]

‘H’

‘O’

‘L’

‘A’

‘0’

a

0x503f5 0x503f6 0x503f7 0x503f8 0x503f9

ptr+1
Operaciones Aritmeticas no permitidas:
• Sumar, Multiplicar o Dividir 2 punteros

ptr+2 *(ptr+3) ptr+4
Lenguaje C

PUNTEROS Y ARRAYS
*(a+0) *(a+1) *(a+2) *(a+3)

Diferencias?

a[0]

char*
0x503f5

0x765d3

ptr

a

a[1]

a[2]

a[3]

‘H’

‘O’

‘L’

‘A’

*(a+4)

a[4]

‘0’

0x503f5 0x503f6 0x503f7 0x503f8 0x503f9

ptr+1

ptr+2 *(ptr+3) ptr+4

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
Lenguaje C

PUNTEROS Y ARRAYS
*(a+0) *(a+1) *(a+2) *(a+3)

Diferencias?

a[0]

char*
0x503f5

ptr

0x765d3

Esto quiere decir que la sentencia
ptr = a es equivalente a ptr = &a[0]

a

a[1]

a[2]

a[3]

‘H’

‘O’

‘L’

‘A’

*(a+4)

a[4]

‘0’

0x503f5 0x503f6 0x503f7 0x503f8 0x503f9

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
Lenguaje C

PUNTEROS Y ARRAYS
Diferencias

a[0]

char*
0x503f5

0x765d3

ptr

a

a[1]

a[2]

a[3]

‘H’

‘O’

‘L’

‘A’

a[4]

‘0’

0x503f5 0x503f6 0x503f7 0x503f8 0x503f9

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
Lenguaje C

PUNTEROS Y ARRAYS

Demostrado !
Lenguaje C

PUNTEROS Y ARRAYS
Envío de Arrays a Funciones
Es muy común enviar arrays completos a
una función. Sin embargo resulta un
poco confuso hacerlo debido a que
existen 2 formas de hacerlo
La primera es declarando el array en el
prototipo de la función de la siguiente
manera:
<tipo> variable[ ]
Por ejemplo:
int suma(int lista[ ], int ne)
Lenguaje C

PUNTEROS Y ARRAYS
Envío de Arrays a Funciones
La segunda forma es declarando el array
en el prototipo de la función mediante
un puntero normal:

Por ejemplo:
int suma(int* lista, int ne)
En cualquiera de las 2 formas, debemos
tener presente algo muy importante: El
nro de elementos del array enviado se
debe conocer. Es usual enviar el nro de
elementos como parte de la función
Lenguaje C

PUNTEROS Y CADENAS
¿Que es una cadena?
char os[4+1] = «UNIX0»;
os[0]

char*
0x503f5

0x765d3

ptr

os

os[1]

os[2]

os[3]

‘U’

‘N’

‘I’

‘X’

os[4]

‘0’

0x503f5 0x503f6 0x503f7 0x503f8 0x503f9

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.
Lenguaje C

PUNTEROS Y CADENAS
¿Que es una cadena?
char os[4+1] = «UNIX0»;
os[0]

char*
0x503f5

0x765d3

ptr

os

os[1]

os[2]

os[3]

‘U’

‘N’

‘I’

‘X’

os[4]

‘0’

0x503f5 0x503f6 0x503f7 0x503f8 0x503f9

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 !
Lenguaje C

PUNTEROS Y CADENAS
Marcando el final
char os[4+1] = «UNIX0»;
os[0]

char*
0x503f5

0x765d3

ptr

os

os[1]

os[2]

os[3]

‘U’

‘N’

‘I’

‘X’

os[4]

‘0’

0x503f5 0x503f6 0x503f7 0x503f8 0x503f9

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’
Lenguaje C

PUNTEROS Y CADENAS
El origen de todos los males

char os[4+1];
strcpy(os,
«WINDOWS7»);
printf(«%s»,os);

os[0]

os[1]

‘W’

‘I’

os[2]

‘N’

os[3]

‘D’

os[4]

‘O’

memoria no reservada

‘W’

‘S’

‘ 7’

0x503f5 0x503f6 0x503f7 0x503f8 0x503f9 0x503fa 0x503fb 0x503fc

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.
Lenguaje C

PUNTEROS Y CADENAS
Operaciones comunes / Copiado

os

‘¡’

‘?’

‘$’

‘0’

‘?’

aux

‘U’

‘N’

char* strcpy(os, aux)
os

‘U’

‘N’

‘I’

‘X’

‘I’

‘X’

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

‘0’

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

os

‘U’

‘N’

‘I’

‘X’ ‘0’

aux

‘W’

‘I’

char* strncpy(os, aux,3)
os

‘W’

‘I’

‘N’

‘X’

‘N’

‘D’

‘O’

‘W’ ‘0’

CODIGO
char os[4+1]=«UNIX0»;
char aux[7] = «WINDOWS»;
strncpy(os,aux,3);

‘0’

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
Lenguaje C

PUNTEROS Y CADENAS
Operaciones comunes / Concatenar

os

‘W’

‘I’

‘N’

‘0’

‘8’

‘Z’

aux

‘X’

‘P’

char* strcat(os, aux)
os

‘W’

‘I’

‘N’

‘X’

‘P’

‘0’

CODIGO
char os[5+1]=«WIN08Z»;
char aux[2] = «XP»;
strcat(os,aux);

‘0’

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’
Lenguaje C

PUNTEROS Y CADENAS
Operaciones comunes / Concatenar

os

‘U’ ‘0’

‘I’

‘X’ ‘0’

aux

‘W’

‘I’

char* strncat(os, aux,3)
os

‘U’

‘W’

‘I’

‘N’

‘N’

‘D’

‘O’

‘W’ ‘0’

CODIGO
char os[4+1]=«U0IX0»;
char aux[7] = «WINDOW0»;
strncat(os,aux,3);

‘0’

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.
Lenguaje C

PUNTEROS Y CADENAS
Operaciones comunes / Comparar

os

‘U’

‘N’

‘I’

‘X’ ‘0’

aux

‘U’

int strcmp(os, aux)
r

‘N’

‘I’

‘X’ ‘0’

CODIGO
char os[5]=«UNIX0»;
char aux[5] = «UNIX0»;
int r = strcmp(os,aux);

0

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)
Lenguaje C

PUNTEROS Y CADENAS
Operaciones comunes / Comparar

os

‘U’

‘N’

‘I’

‘X’ ‘0’

aux

‘I’

int strcmp(os, aux)
r

‘O’

‘S’

‘4’

‘0’

CODIGO
char os[5]=«UNIX0»;
char aux[5] = «WIN70»;
int r = strcmp(os,aux);

12

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
Lenguaje C

PUNTEROS Y CADENAS
Operaciones comunes / Comparar

lang

‘P’

‘E’

‘R’

‘L’

‘0’

aux

‘P’

‘H’

int strcmp(lang, aux)
r

‘P’

‘5’

‘0’

CODIGO
char lang[5]=«PERL0»;
char aux[5] = «PHP50»;
int r = strcmp(lang,aux);

-3

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
Lenguaje C

PUNTEROS Y CADENAS
Operaciones comunes / Comparar

lang

‘P’

‘H’

‘P’

‘4’

‘0’

aux

‘P’

‘H’

int strncmp(lang, aux,3)
r

‘P’

‘5’

‘0’

CODIGO
char lang[5]=«PHP40»;
char aux[5] = «PHP50»;
int r = strncmp(lang,aux,3);

0

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
Lenguaje C

PUNTEROS Y CADENAS
Operaciones comunes / Búsqueda

lang

‘P’

‘H’

‘P’

‘4’

‘0’

aux

‘H’

char* strchr(lang, aux)
ptr

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
Lenguaje C

PUNTEROS Y CADENAS
Operaciones comunes / Búsqueda

lang

‘P’

‘H’

‘P’

‘4’

‘0’

aux

‘P’

char* strrchr(lang, aux)
ptr

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.
Lenguaje C

ARRAYS DE PUNTEROS
Como funcionan
char* osptr[3]={«LINUX0», «WINDOWS0», «UNIX0»};
osptr 0

‘L’

‘I’

‘N’

‘U’

‘X’

‘0’

1

‘W’

‘I’

‘N’

‘D’

‘O’

‘W’

2

‘U’

‘N’

‘I’

‘X’

‘0’

‘S’

‘0’

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.
Lenguaje C

ARRAYS DE PUNTEROS
Paso de array de punteros a funciones
Al igual que el paso de arrays a una
función se puede realizar de 2 formas. El
envío de un array de punteros también
tiene 2 modalidades
La primera es mediante la siguiente
sintaxis en el envío de parámetro de la
función:
<tipo>* variable[ ]
Por ejemplo:
void join(char* lista[ ], int ne)
Lenguaje C

ARRAYS DE PUNTEROS
Paso de array de punteros a funciones
La 2da forma resulta en un quebradero
de cabeza para muchos programadores
ya que se trata del uso de puntero a
puntero
Esto se consigue con la siguiente sintaxis
<tipo>** variable
Por ejemplo:
void join(char** lista, int ne)
Lenguaje C

PUNTEROS A PUNTEROS
char* osptr[3]={«LINUX0», «WINDOWS0», «UNIX0»};
char** ptrptr = osptr;

osptr
ptrptr

0

‘L’

‘I’

‘N’

‘U’

‘X’

‘0’

1

‘W’

‘I’

‘N’

‘D’

‘O’

‘W’

2

‘U’

‘N’

‘I’

‘X’

‘0’

‘S’

‘0’

Un puntero a puntero funciona de forma similar que cualquier puntero. Nada más que
apunta a otras variables de tipo puntero. Se usa mucho para apuntar a un array de
punteros a char. Debido a que su sintaxis es un poco intimidante los programadores suelen
evitarla. Sin embargo solo se necesita seguir la misma lógica de un puntero normal pero de
2do nivel.
Lenguaje C

PUNTEROS NULL y VOID
Como funcionan
void* multi[3];
char os[5+1]=«LINUX0»;
int num=19;
multi[0] = os;
multi[1] = &num;
multi[2] = NULL;

multi
0

os

‘L’

1

num

19

2

‘I’

‘N’

‘U’

‘X’

‘0’

NULL

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

PUNTEROS NULL y VOID
Como funcionan
El puntero VOID apunta a cualquier valor,
pero no puede ser dereferenciado, es decir
no se le puede aplicar la indirección a la
misma variable void.
Para poder usar una variable VOID,
debemos primero convertir su valor a un
puntero del tipo de dato deseado.
En el ejemplo podemos apreciar como la
variable multi guarda 3 valores distintos, y
aplicamos la indirección según sea su tipo
de dato
Lenguaje C

PUNTEROS CONSTANTES
¿Constante?
El lenguaje C nos permite trabajar con
variables constantes. Es decir, variables cuyo
valor una vez seteados no pueden ser
alterados bajo ninguna condición
Para ilustrarlo mejor, vemos el ejemplo
donde la variable uid es una constante de
tipo int. Si intentamos cambiar su valor en el
transcurso del programa obtendremos un
error
Usualmente vemos errores en tiempo de
compilación si hacemos el cambio en el
mismo código fuente
Lenguaje C

PUNTEROS CONSTANTES
¿Constante?
Hay situaciones en las que deseamos que
un puntero sea constante, es decir que su
valor (la dirección de memoria que guarda)
no se pueda alterar. Para conseguir esto
debemos usar la siguiente sintaxis:
const <tipo>* variable
Ejemplo:
const int* ptr;
Nótese en el ejemplo que la variable
apuntada (uid) puede ser alterada (ya que
es una variable int y no const int)
Lenguaje C

PUNTEROS A FUNCIONES
Como funcionan
SI ya se dieron cuenta, e lenguaje C
permite apuntar a casi todo ser vivo. Las
funciones por lo tanto también pueden
ser apuntadas.
Solo debemos declarar el puntero de
forma similar al prototipo de la función
que queremos apuntar:
tipo (*variable)(argumentos,…)

int (*f)(short, short);
f

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

En el ejemplo, podemos apreciar el puntero f que apunta a la función suma. Nótese
que 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
Lenguaje C

PUNTEROS A FUNCIONES
Como se usan
Bien, ya sabemos declarar y asignar un
puntero a una función, ahora veremos
como utilizarlos

Simplemente debemos llamarlos de la
siguiente manera:
(*variable)(argumentos,…)
Ejemplo:
(*f)(1,2);
Es un poco raro pero funciona !
Lenguaje C

CALLBACKS
Que son
Una callback es un mecanismo de
programación por la cual se ejecuta una
función X dentro de otra función Y con la
particularidad de reemplazar la función X
por cualquier otra en tiempo de ejecución
Esto se consigue enviando a una función Y
un argumento de tipo puntero a función
Este mecanismo es muy utilizado en
funciones avanzadas del sistema operativo
para permitir una gran flexibilidad al
momento de programar.
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
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.
Lenguaje C

Bibliografia
The 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

Más contenido relacionado

La actualidad más candente

02 - Conceptos fundamentales sobre tipos de datos en lenguaje C
02 - Conceptos fundamentales sobre tipos de datos en lenguaje C02 - Conceptos fundamentales sobre tipos de datos en lenguaje C
02 - Conceptos fundamentales sobre tipos de datos en lenguaje CDiego Andrés Alvarez Marín
 
Arreglo de punteros
Arreglo de punterosArreglo de punteros
Arreglo de punterospedreror1
 
07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...
07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...
07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...Diego Andrés Alvarez Marín
 
01 - Introducción al lenguaje de programación Python 3
01 - Introducción al lenguaje de programación Python 301 - Introducción al lenguaje de programación Python 3
01 - Introducción al lenguaje de programación Python 3Diego Andrés Alvarez Marín
 
Clase 11- fundamentos de la programacion
Clase 11- fundamentos de la programacionClase 11- fundamentos de la programacion
Clase 11- fundamentos de la programaciondiego MC
 
Apuntes generación de codigo intermedio
Apuntes generación de codigo intermedioApuntes generación de codigo intermedio
Apuntes generación de codigo intermedioHumano Terricola
 
Algoritmos y lenjuage de programacion
Algoritmos y  lenjuage de programacionAlgoritmos y  lenjuage de programacion
Algoritmos y lenjuage de programacionYsaac Ruiz
 
Gestión Dinámica de la Memoria
Gestión Dinámica de la MemoriaGestión Dinámica de la Memoria
Gestión Dinámica de la MemoriaMago Julio Cesar
 
Librerias en-lenguaje-c
Librerias en-lenguaje-cLibrerias en-lenguaje-c
Librerias en-lenguaje-cKevin2811
 
Lenguajes diapositivas
Lenguajes diapositivasLenguajes diapositivas
Lenguajes diapositivasstarduslex
 
TIPOS DE DATOS PARA C++
TIPOS DE DATOS PARA C++TIPOS DE DATOS PARA C++
TIPOS DE DATOS PARA C++Idalia Tristan
 

La actualidad más candente (20)

02 - Conceptos fundamentales sobre tipos de datos en lenguaje C
02 - Conceptos fundamentales sobre tipos de datos en lenguaje C02 - Conceptos fundamentales sobre tipos de datos en lenguaje C
02 - Conceptos fundamentales sobre tipos de datos en lenguaje C
 
Arreglo de punteros
Arreglo de punterosArreglo de punteros
Arreglo de punteros
 
Punteros y funciones abril agosto 2016
Punteros y funciones abril agosto 2016Punteros y funciones abril agosto 2016
Punteros y funciones abril agosto 2016
 
07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...
07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...
07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...
 
03 - Cadenas en Python 3
03 - Cadenas en Python 303 - Cadenas en Python 3
03 - Cadenas en Python 3
 
01 - Introducción al lenguaje de programación Python 3
01 - Introducción al lenguaje de programación Python 301 - Introducción al lenguaje de programación Python 3
01 - Introducción al lenguaje de programación Python 3
 
06 - Arrays y matrices en lenguaje C
06 - Arrays y matrices en lenguaje C06 - Arrays y matrices en lenguaje C
06 - Arrays y matrices en lenguaje C
 
Clase 11- fundamentos de la programacion
Clase 11- fundamentos de la programacionClase 11- fundamentos de la programacion
Clase 11- fundamentos de la programacion
 
Apuntes generación de codigo intermedio
Apuntes generación de codigo intermedioApuntes generación de codigo intermedio
Apuntes generación de codigo intermedio
 
Tipos de datos en C
Tipos de datos en CTipos de datos en C
Tipos de datos en C
 
Algoritmos y lenjuage de programacion
Algoritmos y  lenjuage de programacionAlgoritmos y  lenjuage de programacion
Algoritmos y lenjuage de programacion
 
Gestión Dinámica de la Memoria
Gestión Dinámica de la MemoriaGestión Dinámica de la Memoria
Gestión Dinámica de la Memoria
 
Librerias en-lenguaje-c
Librerias en-lenguaje-cLibrerias en-lenguaje-c
Librerias en-lenguaje-c
 
Lenguajes diapositivas
Lenguajes diapositivasLenguajes diapositivas
Lenguajes diapositivas
 
C sharp intro0
C sharp intro0C sharp intro0
C sharp intro0
 
Transparencias4
Transparencias4Transparencias4
Transparencias4
 
TIPOS DE DATOS PARA C++
TIPOS DE DATOS PARA C++TIPOS DE DATOS PARA C++
TIPOS DE DATOS PARA C++
 
Tutorial C++
Tutorial C++Tutorial C++
Tutorial C++
 
Ejercicios punteros cadenas-vectores
Ejercicios punteros cadenas-vectoresEjercicios punteros cadenas-vectores
Ejercicios punteros cadenas-vectores
 
Investigacion 1
Investigacion 1Investigacion 1
Investigacion 1
 

Destacado

Introducción a la codificación en lenguaje C
Introducción a la codificación en lenguaje CIntroducción a la codificación en lenguaje C
Introducción a la codificación en lenguaje CCarlos Pes
 
Manual c++
Manual c++Manual c++
Manual c++slent
 
Utp sirn_s1_introduccion ia 2014-2
 Utp sirn_s1_introduccion ia 2014-2 Utp sirn_s1_introduccion ia 2014-2
Utp sirn_s1_introduccion ia 2014-2jcbenitezp
 
Utp lpi_s6y7_funciones y variables 2012-2
 Utp lpi_s6y7_funciones y variables 2012-2 Utp lpi_s6y7_funciones y variables 2012-2
Utp lpi_s6y7_funciones y variables 2012-2jcbenitezp
 
Lenguaje c
Lenguaje cLenguaje c
Lenguaje clocke23
 
Utp 2015-2_sirn_s7_r_competitivas
 Utp 2015-2_sirn_s7_r_competitivas Utp 2015-2_sirn_s7_r_competitivas
Utp 2015-2_sirn_s7_r_competitivasjcbenitezp
 
Utp i_ay_se_sistemas difusos i 2013-3
 Utp i_ay_se_sistemas difusos i 2013-3 Utp i_ay_se_sistemas difusos i 2013-3
Utp i_ay_se_sistemas difusos i 2013-3jcbenitezp
 
Utp sirn_sl8 sistemas difusos i 2013-3
 Utp sirn_sl8 sistemas difusos i 2013-3 Utp sirn_sl8 sistemas difusos i 2013-3
Utp sirn_sl8 sistemas difusos i 2013-3jcbenitezp
 
Presentacion libro Fundamentos del SEO en Pamplona
Presentacion libro Fundamentos del SEO en PamplonaPresentacion libro Fundamentos del SEO en Pamplona
Presentacion libro Fundamentos del SEO en PamplonaCarlos Pes
 
Utp ia_s1_introduccion ia
 Utp ia_s1_introduccion ia Utp ia_s1_introduccion ia
Utp ia_s1_introduccion iajcbenitezp
 
Medios,modelos y estilos de aprendizaje jaime romero
Medios,modelos y estilos de aprendizaje jaime romeroMedios,modelos y estilos de aprendizaje jaime romero
Medios,modelos y estilos de aprendizaje jaime romeroJaime David Romero Olivo
 
Utp 2015-2_sirn_s6_adaline y backpropagation
 Utp 2015-2_sirn_s6_adaline y backpropagation Utp 2015-2_sirn_s6_adaline y backpropagation
Utp 2015-2_sirn_s6_adaline y backpropagationjcbenitezp
 

Destacado (20)

Lenguaje c avanzado
Lenguaje c avanzadoLenguaje c avanzado
Lenguaje c avanzado
 
Aprendiendo Lenguaje C
Aprendiendo Lenguaje CAprendiendo Lenguaje C
Aprendiendo Lenguaje C
 
Introducción a la codificación en lenguaje C
Introducción a la codificación en lenguaje CIntroducción a la codificación en lenguaje C
Introducción a la codificación en lenguaje C
 
Manual c++
Manual c++Manual c++
Manual c++
 
Dev c 1 2011
Dev c  1 2011Dev c  1 2011
Dev c 1 2011
 
Manual C++ 1era Parte
Manual C++ 1era ParteManual C++ 1era Parte
Manual C++ 1era Parte
 
Utp sirn_s1_introduccion ia 2014-2
 Utp sirn_s1_introduccion ia 2014-2 Utp sirn_s1_introduccion ia 2014-2
Utp sirn_s1_introduccion ia 2014-2
 
Curso c
Curso cCurso c
Curso c
 
Utp lpi_s6y7_funciones y variables 2012-2
 Utp lpi_s6y7_funciones y variables 2012-2 Utp lpi_s6y7_funciones y variables 2012-2
Utp lpi_s6y7_funciones y variables 2012-2
 
Lenguaje c
Lenguaje cLenguaje c
Lenguaje c
 
Utp 2015-2_sirn_s7_r_competitivas
 Utp 2015-2_sirn_s7_r_competitivas Utp 2015-2_sirn_s7_r_competitivas
Utp 2015-2_sirn_s7_r_competitivas
 
Utp i_ay_se_sistemas difusos i 2013-3
 Utp i_ay_se_sistemas difusos i 2013-3 Utp i_ay_se_sistemas difusos i 2013-3
Utp i_ay_se_sistemas difusos i 2013-3
 
Logica Juridica
Logica JuridicaLogica Juridica
Logica Juridica
 
Utp sirn_sl8 sistemas difusos i 2013-3
 Utp sirn_sl8 sistemas difusos i 2013-3 Utp sirn_sl8 sistemas difusos i 2013-3
Utp sirn_sl8 sistemas difusos i 2013-3
 
Presentacion libro Fundamentos del SEO en Pamplona
Presentacion libro Fundamentos del SEO en PamplonaPresentacion libro Fundamentos del SEO en Pamplona
Presentacion libro Fundamentos del SEO en Pamplona
 
Utp ia_s1_introduccion ia
 Utp ia_s1_introduccion ia Utp ia_s1_introduccion ia
Utp ia_s1_introduccion ia
 
Manual C++ 2da Parte
Manual C++ 2da ParteManual C++ 2da Parte
Manual C++ 2da Parte
 
Medios,modelos y estilos de aprendizaje jaime romero
Medios,modelos y estilos de aprendizaje jaime romeroMedios,modelos y estilos de aprendizaje jaime romero
Medios,modelos y estilos de aprendizaje jaime romero
 
Manual C++ 3ra parte
Manual C++ 3ra parteManual C++ 3ra parte
Manual C++ 3ra parte
 
Utp 2015-2_sirn_s6_adaline y backpropagation
 Utp 2015-2_sirn_s6_adaline y backpropagation Utp 2015-2_sirn_s6_adaline y backpropagation
Utp 2015-2_sirn_s6_adaline y backpropagation
 

Similar a Lenguaje C para Administradores de Red - Script II Punteros

Similar a Lenguaje C para Administradores de Red - Script II Punteros (20)

Punteros en c
Punteros en cPunteros en c
Punteros en c
 
Punteros presentacion
Punteros presentacionPunteros presentacion
Punteros presentacion
 
Punteros y funciones
Punteros y funciones Punteros y funciones
Punteros y funciones
 
Lenguajec diapositivas
Lenguajec diapositivasLenguajec diapositivas
Lenguajec diapositivas
 
Lenguajec 1
Lenguajec 1Lenguajec 1
Lenguajec 1
 
Intro a c sharp
Intro a c sharpIntro a c sharp
Intro a c sharp
 
02 - Tipos de datos escalares en Python 3
02 - Tipos de datos escalares en Python 302 - Tipos de datos escalares en Python 3
02 - Tipos de datos escalares en Python 3
 
Actividades 1 7
Actividades 1 7Actividades 1 7
Actividades 1 7
 
Actividades 1 7
Actividades 1 7Actividades 1 7
Actividades 1 7
 
Actividades 1 7
Actividades 1 7Actividades 1 7
Actividades 1 7
 
Actividades 1-7
Actividades 1-7Actividades 1-7
Actividades 1-7
 
Manual c++01
Manual c++01Manual c++01
Manual c++01
 
C# Diferencias
C# DiferenciasC# Diferencias
C# Diferencias
 
Introduccion al lenguaje de programacion c
Introduccion al lenguaje de programacion cIntroduccion al lenguaje de programacion c
Introduccion al lenguaje de programacion c
 
Varios tema de c++ por (alvaro tejada)
Varios tema de c++ por (alvaro tejada)Varios tema de c++ por (alvaro tejada)
Varios tema de c++ por (alvaro tejada)
 
El arte de programar c++ - versión 3.0
El arte de programar   c++ - versión 3.0El arte de programar   c++ - versión 3.0
El arte de programar c++ - versión 3.0
 
Prueba
PruebaPrueba
Prueba
 
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
 
Csharp
CsharpCsharp
Csharp
 
Fund Java
Fund JavaFund Java
Fund Java
 

Último

PARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdfPARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdfSergioMendoza354770
 
Mapa-conceptual-del-Origen-del-Universo-3.pptx
Mapa-conceptual-del-Origen-del-Universo-3.pptxMapa-conceptual-del-Origen-del-Universo-3.pptx
Mapa-conceptual-del-Origen-del-Universo-3.pptxMidwarHenryLOZAFLORE
 
GonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptxGonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptx241523733
 
El uso de las tic en la vida ,lo importante que son
El uso de las tic en la vida ,lo importante  que sonEl uso de las tic en la vida ,lo importante  que son
El uso de las tic en la vida ,lo importante que son241514984
 
trabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdftrabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdfIsabellaMontaomurill
 
El uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELEl uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELmaryfer27m
 
Presentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidadPresentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidadMiguelAngelVillanuev48
 
R1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en minaR1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en minaarkananubis
 
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6    CREAR UN RECURSO MULTIMEDIAActividad integradora 6    CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA241531640
 
Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024GiovanniJavierHidalg
 
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxMedidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxaylincamaho
 
Arenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptxArenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptxJOSEFERNANDOARENASCA
 
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...FacuMeza2
 
La era de la educación digital y sus desafios
La era de la educación digital y sus desafiosLa era de la educación digital y sus desafios
La era de la educación digital y sus desafiosFundación YOD YOD
 
Plan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxPlan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxpabonheidy28
 
FloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptxFloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptx241522327
 
tics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptxtics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptxazmysanros90
 
dokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptdokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptMiguelAtencio10
 
El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.241514949
 
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptxCrear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptxNombre Apellidos
 

Último (20)

PARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdfPARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
 
Mapa-conceptual-del-Origen-del-Universo-3.pptx
Mapa-conceptual-del-Origen-del-Universo-3.pptxMapa-conceptual-del-Origen-del-Universo-3.pptx
Mapa-conceptual-del-Origen-del-Universo-3.pptx
 
GonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptxGonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptx
 
El uso de las tic en la vida ,lo importante que son
El uso de las tic en la vida ,lo importante  que sonEl uso de las tic en la vida ,lo importante  que son
El uso de las tic en la vida ,lo importante que son
 
trabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdftrabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdf
 
El uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELEl uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFEL
 
Presentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidadPresentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidad
 
R1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en minaR1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en mina
 
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6    CREAR UN RECURSO MULTIMEDIAActividad integradora 6    CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA
 
Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024
 
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxMedidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
 
Arenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptxArenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptx
 
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
 
La era de la educación digital y sus desafios
La era de la educación digital y sus desafiosLa era de la educación digital y sus desafios
La era de la educación digital y sus desafios
 
Plan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxPlan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docx
 
FloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptxFloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptx
 
tics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptxtics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptx
 
dokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptdokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.ppt
 
El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.
 
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptxCrear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
 

Lenguaje C para Administradores de Red - Script II Punteros

  • 1. Lenguaje C Para Administradores de Red Script II - Punteros Fernando I. Díaz Sánchez
  • 2. Lenguaje C ¿Por qué punteros ahora? De todos los libros de C que existen, creo que ninguno de ellos se atreve a enseñar el tema de punteros al segundo capítulo. Sin embargo no conocer sobre punteros lo antes posible creo que fue para muchos la razón por la que abandonaron el lenguaje C y le temieron desde el principio. 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 ( y administrador de red) 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 >>Fids
  • 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 int Como ya sabemos, las variables en el lenguaje C tienen 5 elementos que debemos tener presente: 32 bits Nombre de la Variable Tipo de Dato Tamaño Valor 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 0xf0113b1 edad
  • 7. Lenguaje C REPASANDO LAS VARIABLES int Para empezar a utilizar punteros en C, debemos prestar especial atención a las direcciones de memoria. 32 bits ¿Oiga, no me estará engañando verdad? 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. Y la culpa no la tienen ellos… 10 0xf0113b1 edad
  • 8. Lenguaje C USANDO VARIABLES ¿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. int edad 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 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 32 bits ¿Cómo saber el tamaño de una variable? edad
  • 10. Lenguaje C USANDO VARIABLES Es broma ! Simplemente hacemos referencia a ella por su nombre en cualquier asignación o función int 32 bits 10 ¿Cómo ver o alterar el valor de una variable? edad
  • 11. Lenguaje C USANDO VARIABLES Para saber la dirección de memoria de cualquier variable debemos usar el signo ampersand (&) int 32 bits ¿Cómo saber la dirección de memoria de una variable? edad 10 0x7fff2960d0ac ATENCION ! Las direcciones de memoria cambian con cada ejecución
  • 12. Lenguaje C Los operadores & y *& & * & int 10 edad 0x7fff2960d0ac ¿Qué significan estos símbolos? & = Referencia o Dirección de Memoria *& = Dereferencia, Indirección, Valor de dirección de memoria, Valor Apuntado
  • 13. Lenguaje C Los operadores & y *& int 10 edad 0x7f5f0ac &edad 0x7f5f0ac &edad 10 *0x7f5f0ac 10 * 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
  • 14. Lenguaje C Los operadores & y *& int 10 edad 0x7f5f0ac &edad 0x7f5f0ac &edad 10 *0x7f5f0ac 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)
  • 15. 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
  • 16. Lenguaje C Los operadores & y *& int 10 edad 0x7f5f0ac VALGAN VERDADES &edad * * 0x7f5f0ac 10 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; *&edad = 10; *0x7f5f0ac = 10; // Este modo es el mas cuerdo // A quien se le ocurriría usar esto por Dios ! // Definitivamente ya no tiene amigos ¿CUAL USARIAS ?
  • 17. 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 int* 0x7f5f0ac 0x503fb43 int ptr 10 0x7f5f0ac edad
  • 18. Lenguaje C QUE ES UN PUNTERO Examinando un Puntero int* 64 bits 0x7f5f0ac 0x503fb43 ptr 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
  • 19. 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* 64 bits 0x7f5f0ac 0x503fb43 ptr 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
  • 20. 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* 64 bits 0x7f5f0ac 0x503fb43 ptr 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
  • 21. 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()
  • 22. 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 int* 64 bits 0x7f5f0ac 0x503fb43 ptr
  • 23. 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
  • 24. 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.
  • 25. 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
  • 26. 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
  • 27. 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
  • 28. 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.
  • 29. Lenguaje C TIPOS DE DATOS BASICOS PARA PUNTEROS char* int* float* double* void* ¿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)
  • 30. 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. int* 64 bits 0x7f5f0ac 0x503fb43 ptr
  • 31. 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 int* 64 bits 0x7f5f0ac 0x503fb43 ptr
  • 32. 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; *ptr2 = 19; // No requiere & 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 &
  • 33. 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)
  • 34. 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
  • 35. Lenguaje C FUNCIONES EN C Nombre Tipo de dato del valor de Retorno Delimitadores de Ambito de la Función Parámetros Por Valor Por Referencia int get_uid(int userid) { userid = userid + 500; return userid; } Valor de Retorno Declaración / Prototipo Código fuente de la función
  • 36. Lenguaje C PASO DE PUNTEROS A FUNCIONES ¿Y los punteros? Paciencia ! 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; }
  • 37. 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; }
  • 38. 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)
  • 39. 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; }
  • 40. 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; }
  • 41. 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[0] char* 0x503f5 0x765d3 ptr a a[1] a[2] a[3] a[4] ‘H’ ‘O’ ‘L’ ‘A’ ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9
  • 42. Lenguaje C PUNTEROS Y ARRAYS Operación con Punteros Equivalente en Array char a[4+1] = «HOLA0»; char* ptr = &a[0]; *ptr = ‘F’; char a[4+1] = «HOLA0»; a[0] = ‘F’; a[0] char* 0x503f5 0x765d3 ptr a a[1] a[2] a[3] a[4] ‘F’ ‘O’ ‘L’ ‘A’ ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9
  • 43. 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’; char a[4+1] = «HOLA0»; a[0] = ‘F’; a[2] = ‘C’; a[0] char* 0x503f7 0x765d3 ptr a a[1] a[2] a[3] a[4] ‘F’ ‘O’ ‘C’ ‘A’ ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9
  • 44. Lenguaje C PUNTEROS Y ARRAYS Aritmética de Punteros a[0] char* 0x503f5 0x765d3 ptr a 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 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
  • 45. Lenguaje C PUNTEROS Y ARRAYS Aritmética de Punteros a[0] char* 0x503f5 0x765d3 ptr a[1] a[2] a[3] a[4] ‘H’ ‘O’ ‘L’ ‘A’ ‘0’ a 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9 ptr+1 Operaciones Aritmeticas no permitidas: • Sumar, Multiplicar o Dividir 2 punteros ptr+2 *(ptr+3) ptr+4
  • 46. Lenguaje C PUNTEROS Y ARRAYS *(a+0) *(a+1) *(a+2) *(a+3) Diferencias? a[0] char* 0x503f5 0x765d3 ptr a a[1] a[2] a[3] ‘H’ ‘O’ ‘L’ ‘A’ *(a+4) a[4] ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9 ptr+1 ptr+2 *(ptr+3) ptr+4 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
  • 47. Lenguaje C PUNTEROS Y ARRAYS *(a+0) *(a+1) *(a+2) *(a+3) Diferencias? a[0] char* 0x503f5 ptr 0x765d3 Esto quiere decir que la sentencia ptr = a es equivalente a ptr = &a[0] a a[1] a[2] a[3] ‘H’ ‘O’ ‘L’ ‘A’ *(a+4) a[4] ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9 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
  • 48. Lenguaje C PUNTEROS Y ARRAYS Diferencias a[0] char* 0x503f5 0x765d3 ptr a a[1] a[2] a[3] ‘H’ ‘O’ ‘L’ ‘A’ a[4] ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9 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
  • 49. Lenguaje C PUNTEROS Y ARRAYS Demostrado !
  • 50. Lenguaje C PUNTEROS Y ARRAYS Envío de Arrays a Funciones Es muy común enviar arrays completos a una función. Sin embargo resulta un poco confuso hacerlo debido a que existen 2 formas de hacerlo La primera es declarando el array en el prototipo de la función de la siguiente manera: <tipo> variable[ ] Por ejemplo: int suma(int lista[ ], int ne)
  • 51. Lenguaje C PUNTEROS Y ARRAYS Envío de Arrays a Funciones La segunda forma es declarando el array en el prototipo de la función mediante un puntero normal: Por ejemplo: int suma(int* lista, int ne) En cualquiera de las 2 formas, debemos tener presente algo muy importante: El nro de elementos del array enviado se debe conocer. Es usual enviar el nro de elementos como parte de la función
  • 52. Lenguaje C PUNTEROS Y CADENAS ¿Que es una cadena? char os[4+1] = «UNIX0»; os[0] char* 0x503f5 0x765d3 ptr os os[1] os[2] os[3] ‘U’ ‘N’ ‘I’ ‘X’ os[4] ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9 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.
  • 53. Lenguaje C PUNTEROS Y CADENAS ¿Que es una cadena? char os[4+1] = «UNIX0»; os[0] char* 0x503f5 0x765d3 ptr os os[1] os[2] os[3] ‘U’ ‘N’ ‘I’ ‘X’ os[4] ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9 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 !
  • 54. Lenguaje C PUNTEROS Y CADENAS Marcando el final char os[4+1] = «UNIX0»; os[0] char* 0x503f5 0x765d3 ptr os os[1] os[2] os[3] ‘U’ ‘N’ ‘I’ ‘X’ os[4] ‘0’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9 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’
  • 55. Lenguaje C PUNTEROS Y CADENAS El origen de todos los males char os[4+1]; strcpy(os, «WINDOWS7»); printf(«%s»,os); os[0] os[1] ‘W’ ‘I’ os[2] ‘N’ os[3] ‘D’ os[4] ‘O’ memoria no reservada ‘W’ ‘S’ ‘ 7’ 0x503f5 0x503f6 0x503f7 0x503f8 0x503f9 0x503fa 0x503fb 0x503fc 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.
  • 56. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Copiado os ‘¡’ ‘?’ ‘$’ ‘0’ ‘?’ aux ‘U’ ‘N’ char* strcpy(os, aux) os ‘U’ ‘N’ ‘I’ ‘X’ ‘I’ ‘X’ CODIGO char os[4+1]; char aux[4] = «UNIX»; strcpy(os,aux); ‘0’ 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’).
  • 57. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Copiado os ‘U’ ‘N’ ‘I’ ‘X’ ‘0’ aux ‘W’ ‘I’ char* strncpy(os, aux,3) os ‘W’ ‘I’ ‘N’ ‘X’ ‘N’ ‘D’ ‘O’ ‘W’ ‘0’ CODIGO char os[4+1]=«UNIX0»; char aux[7] = «WINDOWS»; strncpy(os,aux,3); ‘0’ 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
  • 58. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Concatenar os ‘W’ ‘I’ ‘N’ ‘0’ ‘8’ ‘Z’ aux ‘X’ ‘P’ char* strcat(os, aux) os ‘W’ ‘I’ ‘N’ ‘X’ ‘P’ ‘0’ CODIGO char os[5+1]=«WIN08Z»; char aux[2] = «XP»; strcat(os,aux); ‘0’ 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’
  • 59. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Concatenar os ‘U’ ‘0’ ‘I’ ‘X’ ‘0’ aux ‘W’ ‘I’ char* strncat(os, aux,3) os ‘U’ ‘W’ ‘I’ ‘N’ ‘N’ ‘D’ ‘O’ ‘W’ ‘0’ CODIGO char os[4+1]=«U0IX0»; char aux[7] = «WINDOW0»; strncat(os,aux,3); ‘0’ 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.
  • 60. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Comparar os ‘U’ ‘N’ ‘I’ ‘X’ ‘0’ aux ‘U’ int strcmp(os, aux) r ‘N’ ‘I’ ‘X’ ‘0’ CODIGO char os[5]=«UNIX0»; char aux[5] = «UNIX0»; int r = strcmp(os,aux); 0 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)
  • 61. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Comparar os ‘U’ ‘N’ ‘I’ ‘X’ ‘0’ aux ‘I’ int strcmp(os, aux) r ‘O’ ‘S’ ‘4’ ‘0’ CODIGO char os[5]=«UNIX0»; char aux[5] = «WIN70»; int r = strcmp(os,aux); 12 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
  • 62. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Comparar lang ‘P’ ‘E’ ‘R’ ‘L’ ‘0’ aux ‘P’ ‘H’ int strcmp(lang, aux) r ‘P’ ‘5’ ‘0’ CODIGO char lang[5]=«PERL0»; char aux[5] = «PHP50»; int r = strcmp(lang,aux); -3 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
  • 63. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Comparar lang ‘P’ ‘H’ ‘P’ ‘4’ ‘0’ aux ‘P’ ‘H’ int strncmp(lang, aux,3) r ‘P’ ‘5’ ‘0’ CODIGO char lang[5]=«PHP40»; char aux[5] = «PHP50»; int r = strncmp(lang,aux,3); 0 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
  • 64. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Búsqueda lang ‘P’ ‘H’ ‘P’ ‘4’ ‘0’ aux ‘H’ char* strchr(lang, aux) ptr 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
  • 65. Lenguaje C PUNTEROS Y CADENAS Operaciones comunes / Búsqueda lang ‘P’ ‘H’ ‘P’ ‘4’ ‘0’ aux ‘P’ char* strrchr(lang, aux) ptr 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.
  • 66. Lenguaje C ARRAYS DE PUNTEROS Como funcionan char* osptr[3]={«LINUX0», «WINDOWS0», «UNIX0»}; osptr 0 ‘L’ ‘I’ ‘N’ ‘U’ ‘X’ ‘0’ 1 ‘W’ ‘I’ ‘N’ ‘D’ ‘O’ ‘W’ 2 ‘U’ ‘N’ ‘I’ ‘X’ ‘0’ ‘S’ ‘0’ 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.
  • 67. Lenguaje C ARRAYS DE PUNTEROS Paso de array de punteros a funciones Al igual que el paso de arrays a una función se puede realizar de 2 formas. El envío de un array de punteros también tiene 2 modalidades La primera es mediante la siguiente sintaxis en el envío de parámetro de la función: <tipo>* variable[ ] Por ejemplo: void join(char* lista[ ], int ne)
  • 68. Lenguaje C ARRAYS DE PUNTEROS Paso de array de punteros a funciones La 2da forma resulta en un quebradero de cabeza para muchos programadores ya que se trata del uso de puntero a puntero Esto se consigue con la siguiente sintaxis <tipo>** variable Por ejemplo: void join(char** lista, int ne)
  • 69. Lenguaje C PUNTEROS A PUNTEROS char* osptr[3]={«LINUX0», «WINDOWS0», «UNIX0»}; char** ptrptr = osptr; osptr ptrptr 0 ‘L’ ‘I’ ‘N’ ‘U’ ‘X’ ‘0’ 1 ‘W’ ‘I’ ‘N’ ‘D’ ‘O’ ‘W’ 2 ‘U’ ‘N’ ‘I’ ‘X’ ‘0’ ‘S’ ‘0’ Un puntero a puntero funciona de forma similar que cualquier puntero. Nada más que apunta a otras variables de tipo puntero. Se usa mucho para apuntar a un array de punteros a char. Debido a que su sintaxis es un poco intimidante los programadores suelen evitarla. Sin embargo solo se necesita seguir la misma lógica de un puntero normal pero de 2do nivel.
  • 70. Lenguaje C PUNTEROS NULL y VOID Como funcionan void* multi[3]; char os[5+1]=«LINUX0»; int num=19; multi[0] = os; multi[1] = &num; multi[2] = NULL; multi 0 os ‘L’ 1 num 19 2 ‘I’ ‘N’ ‘U’ ‘X’ ‘0’ NULL El puntero NULL no apunta a ningún dato válido en memoria, por lo que es muy utilizado para indicar cuando un puntero no contiene valor alguno. Por otro lado un puntero VOID puede apuntar a cualquier dato válido en memoria, sin importar su tipo de dato. La única condición que debemos tener presente es saber bien el tipo de dato que se ha asignado en todo momento.
  • 71. Lenguaje C PUNTEROS NULL y VOID Como funcionan El puntero VOID apunta a cualquier valor, pero no puede ser dereferenciado, es decir no se le puede aplicar la indirección a la misma variable void. Para poder usar una variable VOID, debemos primero convertir su valor a un puntero del tipo de dato deseado. En el ejemplo podemos apreciar como la variable multi guarda 3 valores distintos, y aplicamos la indirección según sea su tipo de dato
  • 72. Lenguaje C PUNTEROS CONSTANTES ¿Constante? El lenguaje C nos permite trabajar con variables constantes. Es decir, variables cuyo valor una vez seteados no pueden ser alterados bajo ninguna condición Para ilustrarlo mejor, vemos el ejemplo donde la variable uid es una constante de tipo int. Si intentamos cambiar su valor en el transcurso del programa obtendremos un error Usualmente vemos errores en tiempo de compilación si hacemos el cambio en el mismo código fuente
  • 73. Lenguaje C PUNTEROS CONSTANTES ¿Constante? Hay situaciones en las que deseamos que un puntero sea constante, es decir que su valor (la dirección de memoria que guarda) no se pueda alterar. Para conseguir esto debemos usar la siguiente sintaxis: const <tipo>* variable Ejemplo: const int* ptr; Nótese en el ejemplo que la variable apuntada (uid) puede ser alterada (ya que es una variable int y no const int)
  • 74. Lenguaje C PUNTEROS A FUNCIONES Como funcionan SI ya se dieron cuenta, e lenguaje C permite apuntar a casi todo ser vivo. Las funciones por lo tanto también pueden ser apuntadas. Solo debemos declarar el puntero de forma similar al prototipo de la función que queremos apuntar: tipo (*variable)(argumentos,…) int (*f)(short, short); f f = suma; … int suma(short a, short b) { return (int) a+b; } En el ejemplo, podemos apreciar el puntero f que apunta a la función suma. Nótese que 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
  • 75. Lenguaje C PUNTEROS A FUNCIONES Como se usan Bien, ya sabemos declarar y asignar un puntero a una función, ahora veremos como utilizarlos Simplemente debemos llamarlos de la siguiente manera: (*variable)(argumentos,…) Ejemplo: (*f)(1,2); Es un poco raro pero funciona !
  • 76. Lenguaje C CALLBACKS Que son Una callback es un mecanismo de programación por la cual se ejecuta una función X dentro de otra función Y con la particularidad de reemplazar la función X por cualquier otra en tiempo de ejecución Esto se consigue enviando a una función Y un argumento de tipo puntero a función Este mecanismo es muy utilizado en funciones avanzadas del sistema operativo para permitir una gran flexibilidad al momento de programar.
  • 77. 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
  • 78. 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.
  • 79. Lenguaje C Bibliografia The 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