1 Diseño de algoritmos “Punteros”Claudio Gutiérrez-Soto.
2 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;
3 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 */
4 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;
5 Punteros Inicialización Sintaxis: tipo_dato *nombre_puntero=&variable;Ejemplo: int i=7,*p=&i;
6 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)
7 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
8 Punteros int i=3, j=5, k,*p=&i, q=&5,r; double x=11.5;
9 Punteros
10 Punteros Llamada por valor Máx(a,b) Int a,b; { return((a>b)?a:b); }Llamado por referencia Máx(a,b,m_ptr) Int a, b,*m_ptr; *m_ptr=(a>b)?a:b;
11 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.
12 Punteros #define TAM 100 int a[TAM], *p;y el sistema hece que los bytes numerados 300, 304, 309, sean las direcciones de a[0], a[1], a[2],...,a[99]. p=a; = p=&a[0];
13 Punteros Aritmética de punterosLa 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;
14 Punteros suma=0; for(i=0;i
15 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); }
16 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)
17 Asignación dinámica de memoriaCuando 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.
18 Asignación dinámica de memoriaPor 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.
19 Asignación dinámica de memoriaAsí 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.
20 Asignación dinámica de memoriaEn general el <
21 Asignación dinámica de memoriaint 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
22 Uso de typedef en estructurasRecordemos 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;
23 Uso de typedef en estructurasPor ello, en términos generales se puede definir. typedef struct{ miembro 1; miembro 2; miembro 3; …. }nuevo-tipo;
24 Uso de typedef en estructurastypedef struct{ int mes; int dia; int anho; }fecha; fecha Aux;
25 Estructuras y punterosPodemos 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;
26 Estructuras y punterosEjemplo: typedef struct{ int no_cuenta; char tipo_cuenta; char nombre[80]; float saldo; }cuenta; cuenta cliente, *pc;
27 Estructuras y punterosEn este ejemplo cliente es una variable estructura de tipo cuenta y pc un puntero que apunta a una variable de tipo cuenta. Por ende pc=&cliente; Así podemos acceder a un miembro individual de una estructura en términos de su correspondiente variable puntero escribiendo Ptvar->miembro Lo que es equivalente a escribir variable.miembro
28 Estructuras y punterosEl 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
29 Estructuras y punterostypedef struct{ int mes; int dia; int anio; }fecha; 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
30 Estructuras y punterostypedef struct{ int mes; int dia; int anio; }fecha; 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
31 Estructuras y punterosstruct 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]
32 Ejemplo 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; cliente.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.99
33 ¿Preguntas?