Está en la página 1de 33

Diseño de algoritmos

“Punteros”

Ing. Dennis T. Ballena Garcia


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 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;
}
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 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
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
typedef struct{ struct Cuenta{
int mes; int no_cuenta;
int dia; char tipo_cuenta;
int anio; char nombre[80];
}fecha;
float saldo;
fecha ultimopago;
}cliente,*pc=&cliente;
cliente.no_cuenta, pc->no_cuenta,
(*pc).no_cuenta
Estructuras y punteros
typedef struct{ struct Cuenta{
int mes; int no_cuenta;
int dia; char tipo_cuenta;
int anio; char nombre[80];
}fecha; float saldo;
fecha ultimopago;
}cliente,*pc=&cliente;
cliente.ultimopago.mes, pc-
>ultimopago.mes,
(*pc).ultimopago.mes
Estructuras y punteros
typedef struct{ struct Cuenta{
int mes; int no_cuenta;
int dia; char tipo_cuenta;
int anio;
}fecha; char nombre[80];
float saldo;
fecha ultimopago;
}cliente,*pc=&cliente;
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]
Ejemplo
main(){ cliente.no_cuenta=&n;
int n=3333; cliente.tipo_cuenta=&t;
char t=‘A’; cliente.nombre=“Lázaro”;
float b=99.99; cliente.saldo=&b;
typedef struct{
int mes; printf(“%d %c %s
%.2f”,*cliente.no_cuenta,*cliente.tipo_cuenta,
int dia; cliente.nombre,*cliente.saldo);
int anio; printf(“%d %c %s %.2f \n”,*pc->no_cuenta,*pc-
}fecha; >tipo_cuenta, pc->nombre,*pc->saldo);
struct Cuenta{ }
int *no_cuenta;
char *tipo_cuenta; 3333 A Lázaro 99.99
3333 A Lázaro 99.99
char *nombre;
float *saldo;
fecha ultimopago;
}cliente,*pc=&cliente;
¿Preguntas?

También podría gustarte