Diseño de algoritmos “Punteros”

33
Diseño de algoritmos “Punteros” Claudio Gutiérrez-Soto.

description

Diseño de algoritmos “Punteros”. Claudio Gutiérrez-Soto. Punteros. Un puntero es una variable que hace referencia a una dirección de memoria Sintaxis: Tipo_Dato *nombre_variable_puntero; Ejemplo: int *p; Asignación de Dirección nombre_puntero=&variable;. Punteros. - PowerPoint PPT Presentation

Transcript of Diseño de algoritmos “Punteros”

Page 1: Diseño de algoritmos “Punteros”

Diseño de algoritmos“Punteros”

Claudio Gutiérrez-Soto.

Page 2: Diseño de algoritmos “Punteros”

Punteros

Un puntero es una variable que hace referencia a una dirección de memoria

Sintaxis:

Tipo_Dato *nombre_variable_puntero;

Ejemplo:

int *p;

Asignación de Dirección

nombre_puntero=&variable;

Page 3: Diseño de algoritmos “Punteros”

Punteros

El carácter & delante de una variable indica que lo se está accediendo es a la dirección de memoria de dicha variable.

Ejemplo: int *p; p=0; /* p posee la dirección NULL ó 0*/ p=NULL; /* p posee la dirección NULL ó 0*/ p=&i; /*p apunta hacia i ó conteniendo la

dirección de i */ p=(int )1501; /*dirección absoluta de memoria */

Page 4: Diseño de algoritmos “Punteros”

Punteros

" Si p es un puntero, entonces *p es el valor de la variable a la que apunta .“

Ejemplo:

double x,y,*p;

p=&x;

y=*p;

Lo anterior es equivalente a :

y=*&x;

y=x;

Page 5: Diseño de algoritmos “Punteros”

Punteros

Inicialización

Sintaxis:

tipo_dato *nombre_puntero=&variable;

Ejemplo:

int i=7,*p=&i;

Page 6: Diseño de algoritmos “Punteros”

Punteros

Construcciones a las que no se debe apuntar.*No apuntar a constantes. &3 /* ilicito*/*No apuntar a arreglos, el nombre de un arreglo es una

constante int a[77]; &a;*No apuntar a expresiones ordinarias &(k+99)

Page 7: Diseño de algoritmos “Punteros”

Punteros

*No apuntar a variables de tipo register.

register v;

&v;

*Si a es un arreglo, expresiones como:

&a[0] y a[i+j+3] adquieren sentido

Page 8: Diseño de algoritmos “Punteros”

Punteros

int i=3, j=5, k,*p=&i, q=&5,r;

double x=11.5;

Page 9: Diseño de algoritmos “Punteros”

Punteros

Page 10: Diseño de algoritmos “Punteros”

Punteros

Llamada por valorMáx(a,b)Int a,b;{

return((a>b)?a:b);}Llamado por referenciaMáx(a,b,m_ptr)Int a, b,*m_ptr;{

*m_ptr=(a>b)?a:b;}

Page 11: Diseño de algoritmos “Punteros”

Punteros

Relación entre punteros y arreglos.

Un puntero es una variable cuyos valores son direcciones. El nombre de un arreglo es una dirección o puntero fijo. Cuando se declara un arreglo, el compilador debe asignar una dirección base y la cantidad de almacenamiento suficiente como para alojar a todos los elementos del arreglo.

Page 12: Diseño de algoritmos “Punteros”

Punteros

#define TAM 100

int a[TAM], *p;

y el sistema hece que los bytes numerados 300, 304, 309,......696 sean las direcciones

de a[0], a[1], a[2],...,a[99].

p=a; = p=&a[0];

Page 13: Diseño de algoritmos “Punteros”

Punteros

Aritmética de punteros

La aritmética de puntero proporciona una opción para la indización de arreglos, las proposiciones

p=a+1; = p=&a[1];

Sumar un arreglo:

suma=0;

for(p=a; p<&a[TAM];++p)

suma+=*p;

Page 14: Diseño de algoritmos “Punteros”

Punteros

suma=0;

for(i=0;i<TAM;++i)

suma+=*(a+i);

Debido a que a es un puntero constante, las expresiones como:

a=p; ++a; a+=2;

Son ilícitas, no se puede cambiar la dirección de a.

Expresiones apuntadoras como p+1, ++p y p+=i son válidas.

Double a[ ]; = double*a;

Page 15: Diseño de algoritmos “Punteros”

Punteros

Cadenas

Las cadenas son arreglos unidimensionales de tipo char, Por convención, una cadena en C se termina con centinela de fin de cadena ó carácter nulo \0.

char s[ ]="ABC"

char *p="a es por anon o pastel alfabeto"

void main()

{

char *q="del cual todos tienen parte";

printf("\n%s,%s\n %s",s,p,q);

ABC: a es por anon o pastel alfabeto del cual todos tienen parte.

For(p=q;*q!='\0';++q)

*q+=1

printf("\n %s\n\n",p);

}

Page 16: Diseño de algoritmos “Punteros”

Punteros

Arreglos multidimensionales

Expresiones equivalentes ab[i][i]

*(b[i]+j)

(*(b+i))[j]

*((*(b+i))+J)

(&b[0][0]+5i+j)

Al definir la función, en el encabezamiento, la declaración:

Int (*v)[5]; = int v[ ][5];

Int c[7][9][2];

C[i][j][k] = (&c[0][0][0]+9*2+i+2*j+k)

Page 17: Diseño de algoritmos “Punteros”

Asignación dinámica de memoria

Cuando definimos un arreglo con un tamaño definido, podemos tener dos posibles casos, uno es un desaprovechamiento de la memoria y otro es la falta de espacio, lo cual en general no sucede.

Page 18: Diseño de algoritmos “Punteros”

Asignación dinámica de memoria

Por ende, podría ser posible definir: int *x;En lugar de int x[10]; No obstante, si no conocemos el tamaño

de manera predeterminada, es posible asignar espacio de manera dinámica.

Page 19: Diseño de algoritmos “Punteros”

Asignación dinámica de memoria

Así para asignar memoria de manera dinámica podemos utilizar la función malloc, como sigue:

x= (int *)malloc(10*sizeof(int)); Esta función reserva un bloque de

memoria cuyo tamaño (en bytes) es equivalente a 10 cantidades enteras.

Page 20: Diseño de algoritmos “Punteros”

Asignación dinámica de memoria

En general el <<cast>> de tipo que procede a malloc debe ser consistente con el tipo de datos de la variable puntero.

Así si quisiéramos pedir en tiempo de ejecución para una variable tipo double sería:

y=(double *)malloc(10*sizeof(double));

Page 21: Diseño de algoritmos “Punteros”

Asignación dinámica de memoria

int i,n,*x;….printf(“Cuántos números serán ingresados\”);scanf(“%d”,&n);/* reserva de memoria para n */x=(int *)malloc(n*sizeof(int));

for(i=0;i<n;i++){printf( “i=%d x=“, i+1);scanf(“%d”,x+i);}

Page 22: Diseño de algoritmos “Punteros”

Uso de typedef en estructuras

Recordemos que la palabra reservada typedef nos permite redefinir un tipo de dato, por ejemplo:

typedef int entero; Es posible definir tipos de datos con la

nueva definición entero a,b,c;

Page 23: Diseño de algoritmos “Punteros”

Uso de typedef en estructuras

Por ello, en términos generales se puede definir.

typedef struct{

miembro 1;

miembro 2;

miembro 3;

….

}nuevo-tipo;

Page 24: Diseño de algoritmos “Punteros”

Uso de typedef en estructuras

typedef struct{

int mes;

int dia;

int anho;

}fecha;

fecha Aux;

Page 25: Diseño de algoritmos “Punteros”

Estructuras y punteros

Podemos acceder a la dirección de una variable estructura de la misma manera que cualquier otra dirección, mediante el uso del operador (&). Así podemos escribir:

tipo *ptvar;

Page 26: Diseño de algoritmos “Punteros”

Estructuras y punteros

Ejemplo:typedef struct{ int no_cuenta; char tipo_cuenta; char nombre[80]; float saldo; }cuenta;cuenta cliente, *pc;

Page 27: Diseño de algoritmos “Punteros”

Estructuras y punteros

En este ejemplo cliente es una variable estructura de tipo cuenta y pc un puntero que apunta a una variable de tipo cuenta.

Por endepc=&cliente;Así podemos acceder a un miembro individual de

una estructura en términos de su correspondiente variable puntero escribiendo

Ptvar->miembroLo que es equivalente a escribirvariable.miembro

Page 28: Diseño de algoritmos “Punteros”

Estructuras y punteros

El operador -> puede combinarse con el operador punto para acceder a un submiembro dentro de una estructura. Por lo tanto, un submiembro puede ser accedido escribiendo

ptvar->miembro.submiembro

Page 29: Diseño de algoritmos “Punteros”

Estructuras y punteros

struct Cuenta{ int no_cuenta; char tipo_cuenta; char nombre[80]; float saldo; fecha ultimopago; }cliente,*pc=&cliente;cliente.no_cuenta, pc->no_cuenta,(*pc).no_cuenta

typedef struct{ int mes; int dia; int anio;}fecha;

Page 30: Diseño de algoritmos “Punteros”

Estructuras y punteros

struct Cuenta{ int no_cuenta; char tipo_cuenta; char nombre[80]; float saldo; fecha ultimopago; }cliente,*pc=&cliente;cliente.ultimopago.mes, pc-

>ultimopago.mes,(*pc).ultimopago.mes

typedef struct{ int mes; int dia; int anio;}fecha;

Page 31: Diseño de algoritmos “Punteros”

Estructuras y punteros

struct Cuenta{ int no_cuenta; char tipo_cuenta; char nombre[80]; float saldo; fecha ultimopago; }cliente,*pc=&cliente;

typedef struct{ int mes; int dia; int anio;}fecha;

Para acceder al tercer carácter del nombre, este puede ser accedido de la siguiente manera:

cliente.nombre[2] pc->nombre[2] (*pc).nombre[2]

Page 32: Diseño de algoritmos “Punteros”

Ejemplocliente.no_cuenta=&n;cliente.tipo_cuenta=&t;cliente.nombre=“Lázaro”;cliente.saldo=&b;

printf(“%d %c %s %.2f”,*cliente.no_cuenta,*cliente.tipo_cuenta, cliente.nombre,*cliente.saldo);

printf(“%d %c %s %.2f \n”,*pc->no_cuenta,*pc->tipo_cuenta, pc->nombre,*pc->saldo);

}

3333 A Lázaro 99.993333 A Lázaro 99.99

main(){ int n=3333; char t=‘A’; float b=99.99;typedef struct{ int mes; int dia; int anio;}fecha;struct Cuenta{

int *no_cuenta;

char *tipo_cuenta;

char *nombre;

float *saldo;

fecha ultimopago;

}cliente,*pc=&cliente;

Page 33: Diseño de algoritmos “Punteros”

¿Preguntas?