28
Fundam entos de Program ación 1 Tema 6:Punteros Fundam entos de Program ación 1 Tem a 6:Punteros 6.1 Los punteros son direcciones de m em oria 6.2 Declaración de punteros 6.3 Operadores de dirección 6.4 Inicialización de punteros 6.5 Reserva de m em oria 6.6 Punteros y arrays 6.7 Punteros y arrays m ultidim ensionales 6.8 Paso de punteros com o parám etros de funciones EJEMPLOS

Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

  • Upload
    others

  • View
    32

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 1Tem a 6: Punteros Fundam entos de Program ación 1

Tem a 6: Punteros

6.1 Los punteros son direcciones de m em oria

6.2 Declaración de punteros

6.3 Operadores de dirección

6.4 Inicialización de punteros

6.5 Reserva de m em oria

6.6 Punteros y arrays

6.7 Punteros y arrays m ultidim ensionales

6.8 Paso de punteros com o parám etros de funciones

EJEM PLOS

Page 2: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 2Tem a 6: Punteros Fundam entos de Program ación 2

6.1 Los punteros son direcciones de m em oria

Puntero: es una variable que alm acena una dirección de m em oria.

Es un objeto que apunta a otro objeto.

LOS ERRORES CON PUNTEROS SON DIFICILES DE ENCONTRAR.

Hay que diferenciar entre:

Dirección a la que apunta la variable puntero

Contenido de esa dirección

CON UNA VARIABLE PODEM OS TRABAJAR CON SU CONTENIDO. CONUN PUNTERO PODEM OS M ODIFICAR EL CONTENIDO Y LADIRECCION A LA QUE APUNTA.

Los arrays se desarrollan en base a punteros:

Paso por referencia

Page 3: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 3Tem a 6: Punteros Fundam entos de Program ación 3

6.2 Declaración de punteros

Tipodato *identificador;

Variable que alm acenará la dirección de m em oria donde hay un “Tipodato”.

6.3 Operadores de dirección

* : operador indirección (accede al contenido)

&: operador dirección (obtiene dirección)

int x=1,y=2,z[10];

int *ip; /* ip es un puntero a un entero */

ip=&x; /* ip apunta a x */

y=*ip; /* y es = a 1 */

*ip=0; /* x es = a 0 */

ip=&z[0]; /* ip apunta ahora a z[0] */

(*ip)++ es necesario que lleve los paréntesis ya que sin ellos, la expresiónaum entaría ip en lugar de a lo que apunta, debido a que los operadoresunarios com o * y ++ se asocian de derecha a izquierda.

Page 4: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 4Tem a 6: Punteros Fundam entos de Program ación 4

Ejem plo:void intercam bio (int *px, int *py)

{

int tem p;

tem p=*px;

*px=*py;

*py=tem p;

}px

py

j

i

La llamada a la función será algo como:intercam bio (&i,&j);

Page 5: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 5Tem a 6: Punteros Fundam entos de Program ación 5

Ejem plo: Función por valor y por referencia (puntero).

#include <stdio.h>

void f1(int u, int v), f2(int *pu, int *pv);

m ain()

{ int u=1,v=3;

printf(“\nAntes de llam ar a f1: u=% d v=% d”,u,v);

f1(u,v);

printf(“\nDespués de llam ar a f1: u=% d v=% d”,u,v);

printf(“\n\n Antes de llam ar a f2: u=% d v=% d”,u,v);

f2(&u,&v);

printf(“\n\n Después de llam ar a f2: u=% d v=% d”,u,v);

}

void f1(int u, int v)

{ u=0,v=0;

printf(“\nDentro de f1: u=% d v=% d”,u,v);

return; }

Page 6: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 6Tem a 6: Punteros Fundam entos de Program ación 6

Ejem plo: Continuación

void f2(int *pu, int *pv)

{ *pu=10;

*pv=1;

printf(“\nDentro de f2: *pu=% d *pv=% d”,*pu,*pv);

return; }

Salida esperada:

Antes de llam ar a f1: u=1 v=3

Dentro de f1: u=0 v=0

Después de llam ar a f1: u=1 v=3

Antes de llam ar a f2: u=1 v=3

Dentro de f2: *pu=10 *pv=1

Después de llam ar a f1: u=10 v=1

Page 7: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 7Tem a 6: Punteros Fundam entos de Program ación 7

Ejem plo: Análisis de una línea de texto

#include<stdio.h>

#include<ctype.h>

void analiza(char linea[ ], int *pv, int *pc, int *pd, int *pb, int *po);

m ain()

{ char linea[80];

int voca=0, conso=0, digit=0, blanco=0, otro=0;

printf(“\nIntroducir una línea de texto : ==> \n”);

scanf(“% [̂\n]”, linea);

analiza(linea,&voca,&conso,&digit,&blanco,&otro);

printf(“\nEl núm ero de vocales es % d”, voca);

printf(.....

.....

printf(“\nEl núm ero de otros caracteres es % d”, otro);

}

Page 8: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 8Tem a 6: Punteros Fundam entos de Program ación 8

Ejem plo: Análisis de una línea de texto. Cont.

void analiza(char linea[ ],int *pv,int *pc,int *pd, int *pb, int *po)

{ char c; /*carácter en m ayúscula */

int cont=0; /*contador de caracteres */

while ((c= toupper(linea[cont])) != ‘\0’)

{ if (c== ‘A’ || c== ‘E’ || c== ‘I’ || c== ‘O’ || c== ‘U’)

++ *pv;

else if ( c>= ‘A’ && c<= ‘Z’)

++ *pc;

else if (c >= ‘0’ && c <= ‘9’)

++ *pd;

else if ( c== ‘ ‘ || ‘\t’)

++ *pb;

else

++ *po; /*otro carácter*/

++ cont }

return; }

Page 9: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 9Tem a 6: Punteros Fundam entos de Program ación 9

6.4 Inicialización de punteros

float *p=NULL; /*norm alm ente se inicializará a cero*/

NULL 0 (0x0) está definida en stdlib.h es la posición cero de la m em oria.

6.5 Reserva de m em oria

Es necesario reservar el área de m em oria para el puntero.

Los punteros deben apuntar a posiciones “legales”.

Reserva de m em oria:

En T. de com pilación

int i;

float m atriz [3][3];

En T. de ejecución

int *p;

float *pm atriz;

p=(int *)m alloc(sizeof(int));

pm atriz=(float *)m alloc(9*sizeof(float))

Aritmética de direcciones:Si p es un puntero a un elemento de un array, p++ incrementa p para apuntar al siguienteelemento y p+=i apunta i elementos después de donde apuntaba. Hay que tener siemprebien presente el tipo base del puntero.

Page 10: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 10Tem a 6: Punteros Fundam entos de Program ación 10

Ejem plo: Rutinas rudim entarias de m anejo de m em oria.

alloc(n) devuelve un puntero p a n posiciones consecutivas de m em oria.

afree(p) libera la m em oria del puntero p.

Las llam adas a afree deben realizarse en orden inverso a alloc.(alm acenam iento com o una pila LIFO).

m alloc y free son las funciones de la librería estándar (no tienenrestricciones).

Veam os una im plem entación sencilla para que alloc m aneje un array(allocbuf).

allocp será el puntero que direcciona al siguiente elem ento libre.

allocbuf

usado libre

allocp

Page 11: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 11Tem a 6: Punteros Fundam entos de Program ación 11

#define ALLOCSIZE 10000;static char allocbuf[ALLOCSIZE];static char *allocp=allocbuf; /*siguiente posición libre */

char * alloc (int n){ if (allocbuf+ALLOCSIZE-allocp>=n) { /* sí cabe */ allocp+=n; return allocp-n; } else rerturn 0;}

void afree (char *p){if (p>=allocbuf && p<allocbuf+ALLOCSIZE) allocp=p;return;}

Page 12: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 12Tem a 6: Punteros Fundam entos de Program ación 12

6.6 Punteros y arrays

Si definim os

char *pcadena;

entonces

pcadena=“Estoy helado” asigna pcadena a un puntero de un array decaracteres.

Existe una diferencia entre

char acadena[ ]="el contenido";

char *pcadena="el contenido";

acadena es un array que contiene la cadena de caracteres, m ientras quepcadena es un puntero que apunta a una cadena de caracteres.

El contenido \0

El contenido \0acadena

pcadena

Page 13: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 13Tem a 6: Punteros Fundam entos de Program ación 13

void strcpy(char *s,char *t){ int i;

i=0; while ((s[i]=t[i])!='\0') i++;}

void strcpy(char *s,char *t){ while ((*s=*t)!='\0') { s++; t++; }}

void strcpy(char *s,char *t){ while ((*s++=*t++)!='\0') ;}

void strcpy(char *s,char *t){ while (*s++=*t++) ;}

Copia de cadenas con punteros:

En <string.h> strcpydevuelve la cadena destinocom o valor de la función.

Page 14: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 14Tem a 6: Punteros Fundam entos de Program ación 14

Com paración de cadenas con punteros:

int strcm p (char *s, char *t){ int i;

for (i=0;s[i]==t[i];i++) if (s[i]=='\0') return 0; return s[i]-t[i];}

En otra form a:

int strcm p (char *s, char *t){ for (;*s==*t;s++,t++) if (*s=='\0') return 0; return *s-*t;}

Devuelve <0 si *s<*t,

0 si *s=*t,

>0 si *s>*t

Page 15: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 15Tem a 6: Punteros Fundam entos de Program ación 15

Com paración de m étodos:

Con arrays

char cad[ ]=”Pepe Pérez";

void recorre_cad(char c[ ]){int i;for (i=0; c[i]; i++) putchar(c[i]);return;}

Con punteros:

char *cad=”Pepe Pérez";

void recorre_cad(char *pc){while (*pc) putchar(*pc++);return;}

Ejercicio: Escribir la versión strcat con punteros.

Expresiones estándar para m eter (push) y sacar (pop) valores de una pila LIFO:

*p++ = valor /*m ete valor en la pila */

valor = *--p; /*saca el tope de la pila y lo pone en valor */

Page 16: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 16Tem a 6: Punteros Fundam entos de Program ación 16

Punteros de punteros:

Los punteros se pueden alm acenar en un array de punteros: Un vector

que alm acena direcciones a otras variables o estructuras.

Declaración de un array de punteros:

char *vectorpt[2] ={“uno”, “cuatro”}; char vectorcad[2][6]={“uno”,”cuatro”};

..... .....

puts(vectorpt[1]); puts(vectorcad[1]);

Em pleo, por ejem plo: Dos líneas se com paran con strcm p. si están

desordenadas,se intercam bian los punteros en el array de punteros, no las

líneas de texto.Esto elim ina todo el procesam iento para m over toda la línea.

6.7 Punteros y arrays m ultidim ensionales

Page 17: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 21Tem a 6: Punteros Fundam entos de Program ación 21

m nñop

abcdef

xyz

m nñop

abcdef

xyz

Page 18: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 22Tem a 6: Punteros Fundam entos de Program ación 22

6.7 Punteros y arrays m ultidim ensionales. Cont.

Si se dispone de un array de dos dim ensiones es equivalente para acceder

a un determ inado elem ento hacer:

tabla[3][5] == *(*(tabla+3)+5) /*No recom endable, engorrosa y abstracta*/

Veam os un ejem plo utilizando un doble puntero a entero

m ain()

{ int i, **a;

a= (int**)m alloc(num filas*sizeof(int));

for(i=0; i<num filas; i++)

a[i] = (int*)m alloc(num colum nas*sizeof(int));

a[0] [0] = 1; /*Se accede con la notación de indices */

a[0] [1] = 6; /*que es m ás cóm oda y se puede seguir */

..... /*em pleando */

a[1][0] = 2;

... }

Se ha reservado espacio de m em oria para el array bidim ensional con lanotación de punteros en tiem po de ejecución, que es la gran m ejora.

Page 19: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 23Tem a 6: Punteros Fundam entos de Program ación 23

6.7 Punteros y arrays m ultidim ensionales. Cont.

Véase en el siguiente ejem plo gráfico el funcionam iento de los arrays depunteros:

filas

colum nasa

*(a+2)

*(*(a+2)+4) == a[2][4]

: : : : : : : : : : : : : : : :

:

:

Page 20: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 24Tem a 6: Punteros Fundam entos de Program ación 24

Char dias_m es[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31}};

int dia_del_anyo(int anyo,int m es,int dia){ int i, bisiesto; bisiesto=(anyo% 4==0 && (anyo% 100!=0 || anyo% 400==0)); for (i=1;i<m es;i++) dia+=dias_m es[bisiesto][i]; return dia;}

Ejem plo: Cálculo del núm ero del día del año. (em pleando índices)

Page 21: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 25Tem a 6: Punteros Fundam entos de Program ación 25

Ejem plo: Cálculo del día del m es a partir del día del año

void dia_del_m es(int anyo,int dia_anyo,int *pm es, int *pdia){ int i, bisiesto; bisiesto=(anyo% 4==0 && (anyo% 100!=0 || anyo% 400==0)); for (i=1;dia_anyo>dias_m es[bisiesto][i];i++) dia_anyo -=dias_m es[bisiesto][i]; *pm es=i; *pdia=dia_anyo;}

Page 22: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 26Tem a 6: Punteros Fundam entos de Program ación 26

Ejem plo: Nom bre del m es

char *nom bre_m es(int n){char *nom bre[ ]={"m es ilegal","Enero","Febrero","M arzo", "Abril","M ayo","Junio",

"Julio","Agosto","Septiem bre","Octubre","Noviem bre","Diciem bre"};

return (n<1||n>12)?nom bre[0];nom bre[n];}

Ejercicio: Convertir los anteriores algoritm os em pleando punteros en vez deíndices.

Page 23: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 27Tem a 6: Punteros Fundam entos de Program ación 27

6.8 Paso de punteros com o parám etros de funciones

Def. Función Llam ada Puede Cam biar

Variable ordinaria(por valor) void func(int x) func(g); nada

Var. ord. (por referencia) void func(int*x) func(&g); valor de g

Puntero (paso por valor) void func(int*t) p=&g; valor de g

func(p);

Puntero (por referencia) void func(int**t) p=&g; valor de g y

func(&p); dirección de p

En el últim o caso se puede m odificar tanto el contenido de la m em oriaapuntada por p com o la propia dirección de la variable puntero. Por tantose puede conseguir que el puntero apunte a otro objeto.

En el siguiente ejem plo se pueden com probar estos aspectos ==>

Page 24: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 28Tem a 6: Punteros Fundam entos de Program ación 28

Ejem plo: Paso de parám etros.

#include <stdio.h>

void funcion(int x, int *m , int *n, int **y)

{ x= 7115;

*m = 20;

*n= 300;

**y= 500;

*y= n;

return; }

m ain()

{ int v=1,w=6,t=10,*p,*q;

void funcion(int, int *, int *, int **);

p=&w;

q=&t;

printf(“v=% d w=% d t=% d *p=% d

*q=% d”, v,w,t,*p,*q);

funcion(v,&t,p,&q);

printf(“v=% d w=% d t=% d *p=% d

*q=% d”, v,w,t,*p,*q);

v= 1 w=6 t=10 *p=6 *q=10

v=1 w=300 t=500 *p=300 *q=300

Page 25: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 29Tem a 6: Punteros Fundam entos de Program ación 29

Argum entos en la línea de órdenes

El m ain tiene 2 parám etros:

argc: Núm ero de argum entos (incluyendo el propio nom bre ejecutable)

argv: Puntero a un array de cadenas de carac. (inc. el 1º al ejecutable)

Ejem plo: Program a que escribe los argum entos de entrada en pantalla.

argus.exe hola, Pedro

argvhola,\0

argus.exe\0

Pedro\0

Page 26: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 30Tem a 6: Punteros Fundam entos de Program ación 30

Versión con arrays :

m ain (int argc, char *argv[ ]){ int i; for (i=0;i<argc;i++)

printf ("% s% s", argv[i],(i<argc-1) ?" ": ""); printf("\n"); return 0;}

Versión con punteros:

m ain (int argc, char *argv[ ]){ while (argc-->0)

printf ("% s% s", *argv++,(argc>0) ?" ": ""); printf("\n"); return 0;}

C:\Djgpp> argus UNO dos y CuatroC:/Djgpp/argus.exe UNO dos y Cuatro

“devuelve el path con los argumentos”

Page 27: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 31Tem a 6: Punteros Fundam entos de Program ación 31

Ejem plo de análisis de la función getint de la biblioteca ctype.h:

La función getint realiza una conversión de entrada en form ato libre,

desglosando un flujo de caracteres en valores enteros, uno por llam ada.

La llam ada se haría de la siguiente form a:

int n,array[SIZE], getint (int *i);for (n=0;n<SIZE && getint(&array[n])!=EOF;n++);

Cada llam ada pone en array[n] el siguiente entero que se encuentra eincrem enta n. Se devuelve EOF com o fin de introducción de datos, cero si laintroducción no es un núm ero, y un valor positivo si la entrada contiene unvalor válido.

⇒ Sigue

Page 28: Tema 6: Punteros - Web de Programaciónprogramacionteleco.umh.es/temario/fp_t6.pdf · Tema 6: Punteros Fundamentos de Programación 2 6.1 Los punteros son direcci ones de memoria

Fundam entos de Program ación 32Tem a 6: Punteros Fundam entos de Program ación 32

#include <ctype.h>int getch(void);void ungetch(int);

/*getint: obtiene el siguiente entero ylo asigna a *pn. */int getint(int *pn){ int c,sign; while (isspace(c=getch())); if (!isdigit(c)&&c!=EOF&&c!='+'&&c!='-') { ungetch(c); return 0; }

sign=(c=='-')?-1:1; if (c=='+' || c=='-') c=getch(); for (*pn=0;isdigit(c);c=getch()) *pn=10**pn +(c-'0');*pn=sign;if (c!=EOF) ungetch(c);return c;}

Ejercicio: Im plem entar getfloat, análogo a getint pero con com a flotante.