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
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 */
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;
Punteros
Inicialización
Sintaxis:
tipo_dato *nombre_puntero=&variable;
Ejemplo:
int i=7,*p=&i;
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)
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
Punteros
int i=3, j=5, k,*p=&i, q=&5,r;
double x=11.5;
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;}
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.
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];
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;
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;
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);
}
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)
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.
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.
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.
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));
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);}
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;
Uso de typedef en estructuras
Por ello, en términos generales se puede definir.
typedef struct{
miembro 1;
miembro 2;
miembro 3;
….
}nuevo-tipo;
Uso de typedef en estructuras
typedef struct{
int mes;
int dia;
int anho;
}fecha;
fecha Aux;
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;
Estructuras y punteros
Ejemplo:typedef struct{ int no_cuenta; char tipo_cuenta; char nombre[80]; float saldo; }cuenta;cuenta cliente, *pc;
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
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
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;
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;
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]
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;
¿Preguntas?
Top Related