You are on page 1of 26

Un puntero es una variable que contiene la

direccin de otra variable


Cuando una variable puntero es definida, el
nombre de la variable debe ir precedido de un
asterisco (*). Este identifica que la variable es
un puntero.
Tipo * identificador;
Operadores.
*: Acceso al contenido
&: Obtencin de la direccin
Punteros: Reglas de uso
El smbolo * se usa para DEFINIR un tipo puntero
El smbolo & se usa para indicar la direccin de una variable
El smbolo * se usa para ACCEDER al valor que guarda un
puntero
El smbolo & se usa en las invocaciones de funciones, de
forma que se pone delante de los parmetros de E/S
Cuando un parmetro es de E/S en el prototipo y cabecera
se indica con un tipo puntero, esto es, poniendo un *
delante del nombre.
En el cuerpo de la funcin los argumentos que son
funciones se USAN con un * delante
Los & slo se usan en el programa principal
Los * se usan en las funciones
Los punteros son importantes porque:
Son tiles para crear aplicaciones
Se pueden usar para pasar argumentosa funciones por
referencia.
Son tiles para acceder a elementos individuales de
estructuras de datos tales como arreglos, estructuras y
tipos de datos definidos por el usuario.
Se pueden usar para realizar asignacin dinmica de
memoria, es decir, reservar tanta memoria como lo requiera
la estructura de datos, en vez de estar limitado por arreglos
de dimensiones y tamao fijos.
001 002 003 004
005 006 007 008
009 010 011 012
Int numero
013 014 015 016
Memoria
Cada casilla en memoria posee un
identificador (ID.) Formalmente se
maneja como un nmero
hexadecimal
#include <stdio.h>
Int main(){
int numero;
Return EXIT_SUCCESS;
}
001 002 003 004
005 006 007 008
009 010 011 012
Int numero
013 014 015 016
Memoria
#include <stdio.h>
Int main(){
int numero;
Return EXIT_SUCCESS;
}
Al momento de definir una
variable , la misma DEBE ocupar
un espacio en memoria (una
casilla disponible)
001 002 003 004
005 006 007 008
009 010 011 012
Int numero =
3
013 014 015 016
Memoria
#include <stdio.h>
Int main(){
int numero;
numero = 3;
Return EXIT_SUCCESS;
}
Al momento de la asignacin, la variable en
memoria asume el valor
Por tanto, es posible hablar en trminos de la
variable numero tiene el valor 3 o la variable
de la casilla 012 de memoria tiene el valor 3. ES
LO MISMO
001 002 003 004
005 006 007 008
009 010 011 012
Int numero
= 3
013 014 015 016
Memoria
1) Partiendo de la variable numero es posible
obtener la direccin de memoria de la variable
(012)
&numero
2) Partiendo de la direccin de memoria (012) es
posible obtener el valor que se encuentra en esa
casilla (3).
*012
El operador & (AMPERSAND) aplica sobre una
variable. Quiere decir Cul es la DIRECCION de
memoria de la variable numero ? -> 012
El operador * (ASTERISCO) aplica sobre una
direccin. Quiere decir Cul es el VALOR de la
direccin de memoria (012)?->3
001 002 003 004
005 006
int *apuntadorINT
007 008
009 010 011 012
Int numero =
3
013 014 015 016
Memoria
#include <stdio.h>
Int main(){
int numero;
int *apuntadorINT;
numero = 3;
Return EXIT_SUCCESS;
}
En C podemos definir apuntadores. Un
apuntador es una variable que en lugar de
contener un tipo de dato (int, float, char),
contiene una direccin de memoria a otra
variable
El * SLO se usa en C para indicar que la
variable que se esta definiendo es un
apuntador. NADA MS
001 002 003 004
005 006
int *apuntadorINT
= 012
007 008
009 010 011 012
Int numero =
3
013 014 015 016
Memoria
#include <stdio.h>
Int main(){
int numero;
int *apuntadorINT;
numero = 3;
apuntadorINT=&numero;
Return EXIT_SUCCESS;
}
Qu quiere decir esto?. apuntadorINT, que es
un apuntador a un entero, es igual a la direccin
de memoria de la variable numero. Por tanto,
apuntadorINT=012.
001 002 003 004
005 006
int *apuntadorINT
= 012
007 008
009 010 011 012
Int numero =
3
013 014
otraVariable=3
015 016
Memoria
#include <stdio.h>
Int main(){
int numero;
int *apuntadorINT;
int otraVariable;
numero = 3;
apuntadorINT=&numero;
otraVariable=*apuntadorINT;
Return EXIT_SUCCESS;
}
Qu quiere decir esto?. otraVariable, que es un
entero, es igual al valor del contenido de la
direccin de memoria apuntadorINT(006). Por
tanto, otraVariable = 3.
ARITMETICA DE PUNTEROS
Los operadores + y
Se pueden usar con punteros
Pero el significado de la operacin cambia un poco
Si un entero ocupa 4 bytes, tomemos este ejemplo
int x;
int *p;
p = &x;
Si la direccin de x es un valor 100 y decimos
p = p+2;
Que direccin almacena pi?
10
2
10
8
10
4
La suma indica que p se mueva 2
enteros mas adelante
Cada entero equivale a 4 bytes
100 + 2*4 = 108
OPERACIONES CON PUNTERO
Los arreglos en C implcitamente usan aritmtica de direcciones
para acceder a sus elementos.
A continuacin se presenta la declaracin de un arreglo de enteros
que se usar:
Int arreglos[10]={10,20,30,40,50,60,70,80,90,100};
Int *ptr = arreglo;
Elemento
10
20
30
40
50
60
70
80
90
100
Direccin de
Memoria de la
Posicin
1028
1030
1032
1034
1036
1038
1040
1042
1044
1046
Arreglo
ptr
Como acceder a los elementos
del arreglo:
Arreglo[i]
*(arreglo+i)
Ptr[i]
*(ptr+i)
PASO DE PARAMETROS
Las funciones son porciones de cdigo
Ejecutan una tarea especifica
Usualmente toman datos de entrada->parmetros
Y retornan un valor
Los parmetros se pueden enviar de dos formas:
Por valor
Por referencia
PASO POR VALOR
La funcin no recibe la variable enviada
Recibe una copia
Similar a cuando va a hacer algn tramite y le piden la cdula
No entrega la cdula verdadera
Entrega una copia
La verdadera estar segura, aunque quemen y destruyan
la copia
Ejemplo:
x = 5
printf(%d\n,x);
funct(x);
printf(%d\n,x);
void funct(int y){
y = y+1;
printf(%d\n,y);
}
PASO POR REFERENCIA
Aqu si la funcin recibe exactamente la variable enviada
No hay copias
Si algo se le hace al parmetro, se le esta haciendo a la variable
Para esto, se usan punteros
La funcin trabaja con un puntero a la variable enviada
Sabe todo sobre esa variable y se pude acceder a travs de *
Ejemplo:
x = 5
printf(%d\n,x);
funct(&x);
printf(%d\n,x);
void funct(int *py){
*py = *py+1;
printf(%d\n,*py);
}
Se imprime 6, el valor de
x cambi dentro de la
funcin
EJEMPLOS DE FUNCIONES
Pase por Valor Pase por Referencia
#include <stdio.h>
int CuboporValor(int );
int main(){
int numero=5;
printf("El Valor original del Numero es:
%d\n",numero);
numero=CuboporValor(numero);
printf("El nuevo valor del numero es:
%d\n",numero);
return 0;
}
int CuboporValor(int n){
return n*n*n;
system("pause");
}
#include <stdio.h>
void CuboporReferencia(int* );
int main(){
int numero=5;
printf("El Valor original del Numero es:
%d\n",numero);
CuboporReferencia(&numero);
printf("El nuevo valor del numero es:
%d\n",numero);
system("pause");
return 0;
}
void CuboporReferencia(int *nPtr){
*nPtr= *nPtr * *nPtr * *nPtr;
}
RESERVA DE MEMORIA DINAMICA
La declaracin de una variable
Siempre reserva memoria
Aunque la variable no se use, ya se reservo memoria para ella:
ESTATICA
Si deseamos reservar memoria, pero no en la declaracin
Si no, a voluntad dentro del programa
La reserva seria dinmica
En C se usan
Punteros y
Las funciones de librera
#include <stdlib.h>
void *malloc(size_t size);
int *a; //No se reserva nada
..
/*Cuando se desee, se reserva*/
a = malloc(sizeof(int));
//La variable normalmente
*a = 3;
a no apunta a otra
variable, tiene
memoria propia,
solo para el
EJEMPLO DE MEMORIA DINAMICA USANDO MALLOC
1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <time.h>
4.
5. int main( void )
6. {
7. int *numPtr, i;
8. size_t tamanyo=0;
9. srand(time(NULL));
10. printf( "Introduzca el tamao de la lista: " );
11. scanf( "%d", &tamanyo );
12. numPtr = (int *)malloc( tamanyo*sizeof(int) );
13.
14. int vector[tamanyo];
15. for(i=0;i<tamanyo;i++){
16. vector[i]=rand() % 100;
17. printf("%d\n",vector[i]);
18. }
19.
20. return 0;
21. }
#include <stdlib.h>
void *malloc(size_t size);
DEMO
PUNTEROS Y ARRAYS
Sea el array de una dimensin:
int mat[ ] = {2, 16, -4, 29, 234, 12, 0, 3};
en el que cada elemento, por ser tipo int, ocupa dos
bytes de memoria.
Suponemos que la direccin de memoria del primer
elemento, es 1500:
&mat[0] es 1500
&mat[1] ser 1502
&mat[7] ser 1514
PUNTEROS Y ARRAYS
int mat[ ] = {2, 16, -4, 29, 234, 12, 0, 3};
En total los 8 elementos ocupan 16 bytes.
Podemos representar las direcciones de memoria que ocupan los
elementos del array, los datos que contiene y las posiciones del
array en la forma:
Direccin 1502 1504 1506 1508 1510 1512 1514
2 16 -4 29 234 12 0 3
Elemento mat[1] mat[2] mat[3] mat[4] mat[5] mat[6] mat[7]
ARREGLOS DINAMICOS
En ocasiones deseamos usar arreglos
Donde no hayamos predefinido cuantos
elementos max. tendremos
Queremos usar arreglos dinmicos
Se declara el arreglo potencial:
int *arreglo;
Dentro del programa, se pide memoria
cuando se necesite:
arreglo = malloc(sizeof(int)*20);
Para indicar el nuevo
tamao se puede usar una
constante o una variable, o
cualquier expresin
main(){
int *arreglo, n;
printf(Ingrese el tamao del arreglo:);
scanf(%d,&n);
arreglo = malloc(sizeof(int)*n);
printf(Ahora tiene %d elementos para trabajar\n,n);
...
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
main(){
srand(time(NULL));
int *arreglo, n;
printf("Ingrese el tamao del
arreglo:");
scanf("%d",&n);
arreglo = malloc(sizeof(int)*n);
printf("Ahora tiene %d elementos para
trabajar\n",n);
int i;
for(i=0;i<n;i++){
arreglo[i]=rand() % 100;
printf("%d\n",*(arreglo+i));
}
}
Y LIBERA..
Al pedir memoria dinmicamente
Se debe liberar dentro del programa
En C se libera usando la funcin free
int *a;
a = malloc...;

free(a);
Cuando se
libera para
una
variable
PASO DE ARREGLOS A FUNCIONES
Al pasar un arreglo a una funcin debe tomarse en cuenta
Necesitare tambin el tamao del arreglo?
Si es as, tambin debe incluirse como parmetro
En prototipos y cabecera
float CalcPromedio(float A[], int size);
float funct(float B[]);
En el cuerpo de la funcin
float CalcPromedio(float A[], int size){
..
A[i] = 3;
}
Siempre recuerde que
El paso de arreglos, es un paso por referencia