Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Punt Eros
Punt Eros
Qu es un PUNTERO?:
Un puntero es un objeto que apunta a otro objeto. Es decir,
una variable cuyo valor es la direccin de memoria de otra
variable.
Las direcciones de memoria dependen de la arquitectura
del ordenador y de la gestin que el sistema operativo haga
de ella.
Ismael Camarero
Qu es un PUNTERO?:
No hay que confundir una direccin de memoria con el
contenido de esa direccin de memoria.
int x = 25;
Direccin
...
...
1502
1504
1506
1508
25
...
...
...
...
Ismael Camarero
int *punt;
punt Es una variable puntero a una variable de tipo entero.
char *car;
Un puntero
car Es un puntero a variable de tipo carcter.
tiene su
propia
long float *num;
direccin de
float *mat[5]; // . . .
memoria:
&punt
Ismael Camarero
&car
char *punt;
flotat *x;
Operadores de Punteros
Existen dos operadores :
Operador de direccin: & Representa la
direccin de memoria de la variable que le sigue:
&fnum representa la direccin de fnum.
Operador de contenido o indireccin: * Permite
acceder a la variable situada en la direccin de
memoria que se especifica en el operando.
*punt es el contenido del la direccion de punt
Ismael Camarero
Operadores de Punteros
Ejemplo de operadores:
float altura = 26.92, *apunta;
apunta = &altura; //inicializacin del puntero
printf(\n%f, altura);
//salida 26.92
printf(\n%f, *apunta); //salida 26.92
No se debe confundir el operador
del puntero:
int
Con el operador
.
*p;
* en la declaracin
* en las instrucciones:
*p = 27;
Operadores de Punteros
Veamos con un ejemplo en C la diferencia entre
todos estos conceptos
Veamos el archivo
- punt0.cpp , punt1.cpp, sumpun.cpp
Es decir:
Operadores de Punteros
Veamos con otro ejemplo en C la diferencia entre
todos estos conceptos
void main(void) {
int a, b, c, *p1, *p2;
void *p;
p1 = &a;
*p1 = 1;
p2 = &b;
*p2 = 2;
p1 = p2;
*p1 = 0;
// Paso 6. b = 0
Operadores de Punteros
p2 = &c;
*p2 = 3;
// Paso 8. c = 3
// Paso 9. Qu se imprime?
p = &p1;
*p = p2;
*p1 = 1;
// Paso 12. c = 1
}
Ismael Camarero
10
Inicializacin de punteros(I):
< Almacenamiento > < Tipo >
11
Inicializacin de punteros(II):
2) El nombre de un array de almacenamiento static o
extern se transforma segn la expresin:
a) float mat[12];
float *punt = mat;
b) float mat[12];
float *punt = &mat[0];
3) Un cast puntero a puntero:
int *punt = (int *) 123.456;
Inicializa el puntero con el entero.
Ismael Camarero
12
Inicializacin de punteros(III):
4) Un puntero a carcter puede inicializarse en la forma:
char *cadena = Esto es una cadena;
5) Se pueden sumar o restar valores enteros a las
direcciones de memoria en la forma: (aritmtica de
punteros)
static int x;
int *punt = &x+2, *p = &x-1;
6) Equivalencia: Dos tipos definidos como punteros a
objeto P y puntero a objeto Q son equivalentes slo si
P y Q son del mismo tipo. Aplicado a matrices:
nombre_puntero = nombre_matriz;
13
PUNTEROS Y ARRAYS
Sea el array de una dimensin:
int mat[ ] = {2, 16, -4, 29, 234, 12, 0, 3};
en el que cada elemento, por ser tipo int, ocupa dos bytes
de memoria.
Suponemos que la direccin de memoria del primer
elemento, es 1500:
&mat[0] es 1500
&mat[1] ser 1502
&mat[7] ser 1514
Ismael Camarero
14
PUNTEROS Y ARRAYS
PUNTEROS Y ARRAYS
int mat[ ] = {2, 16, -4, 29, 234, 12, 0, 3};
En total los 8 elementos ocupan 16 bytes.
Podemos representar las direcciones de memoria que
ocupan los elementos del array , los datos que contiene y
las posiciones del array en la forma:
Direccin 1502
16
1504
1506
1508
1510
1512
1514
-4
29
234
12
15
PUNTEROS Y ARRAYS
Direccin
1502
1504
1506
1508
1510
1512
16
-4
29
234
12
1514
Ismael Camarero
16
PUNTEROS Y ARRAYS
#include <stdio.h>
#include <conio.h>
int mat[5]={2, 16, -4, 29, 234, 12, 0, 3}, i; //declaradas como globales
void main() {
printf("\n%d", &mat[0]);
printf("\n%p", mat);
i++;
//i=1
printf("\n%p", mat+i);
printf("\n%d", *(mat+i));
getch();
Ismael Camarero
17
PUNTEROS Y ARRAYS
Comprobamos con un ejemplo: dirmen.cpp
ejemplo
16
-4
29
234
Ismael Camarero
12
3
18
Direccin del
octavo elemento
16
-4
29
mat
mat+1
mat+2
mat+3
Puntero a la
direccin del
elemento 0
234
12
mat+4 mat+5
Incremento en una
Ismael Camarero
mat+6
mat+7
mat++
19
PUNTEROS Y ARRAYS
20
PUNTEROS Y ARRAYS
Ismael Camarero
21
Aritmtica de punteros
-A una variable puntero se le puede asignar la direccin de
cualquier objeto.
-A una variable puntero se le puede asignar la direccin de
otra variable puntero (siempre que las dos sealen el mismo
objeto)
-A un puntero se le puede inicializar con el valor NULL
-Una variable puntero puede ser restada o comparada con
otra si ambas apuntan a elementos de un mismo array.
Ismael Camarero
22
Aritmtica de punteros
Ejemplo:
int *punt = NULL, var = 14;
punt = &var;
Hay que tener cuidado con las direcciones apuntadas:
printf(%d, %d, *(punt+1), var+1);
*(punt + 1) repesenta el valor contenida en la direccin
de memoria aumentada en una posicin (int=2bytes), que
ser un valor no deseado. Sin embargo var+1 representa
el valor 15.
punt + 1 representa lo mismo que &var + 1 (avance en la
direccin de memoria de var).
23
Aritmtica de punteros
- Se puede sumar o restar valores enteros : p++, pv+3,
teniendo en cuenta que el desplazamiento (offset) depende
del tipo de dato apuntado:
p++;
//apunta a 0004
Ismael Camarero
24
Aritmtica de punteros
double*q;
void*r;//punterogenrico
p=&34;//lasconstantesno
tienendireccin
p=&(i+1);//lasexpresionesno
tienendireccin
&i=p;//lasdireccionesnose
puedencambiar
Ismael Camarero
p=q;//ilegal
25
PUNTEROS Y ARRAYS
2
*mat
mat[1]
mat[2]
mat[3]
mat[4]
mat[5]
mat[6]
mat[7]
16
-4
29
234
12
*(mat+1) *(mat+2)
*mat = 2
*(mat+4)
*(mat+3)
*(mat+5)
*(mat+6)
*(mat+7) = 3
PUNTEROS Y ARRAYS
Y... cmo se aplica la aritmtica de punteros para
desplazarnos en un array bidimensional?:
float mat[2][4];
//declaracin del array
Col 0
Col 1
Col 2
Col 3
Fila 0
Fila 1
1.45
20
-23.5
2.95
-14,08
0.082
17.3
6.023
27
PUNTEROS Y ARRAYS
Existe, por tanto una equivalencia:
Con subndices
Con punteros
Valor
mat[0[[0]
*(*(mat+0)+0)
1.45
mat[0[[1]
*(*(mat+0)+1)
-23.5
mat[0[[2]
*(*(mat+0)+2)
-14.08
mat[0[[3]
*(*(mat+0)+3)
17.3
mat[1[[0]
*(*(mat+1)+0)
20
mat[1[[2]
*(*(mat+1)+1)
2.95
mat[1[[3]
*(*(mat+1)+2)
0.082
mat[1[[4]
*(*(mat+1)+3)
6.023
PUNTEROS Y ARRAYS
*mat representa un puntero a la primera fila.
*(mat+1)+j para las direcciones de elementos
*(*(mat+1)+j) para los contenidos.
Ismael Camarero
29
PUNTEROS Y ARRAYS
Si en
x[10][20] quiero acceder al elemento de la fila 3 y
la columna 6, lo hago escribiendo x[2][5]. Con notacin de
punteros, es equivalente a
* ( * ( x + 2 ) +5)
ya que x + 2 es un puntero a la fila 3. Por tanto. El
contenido de dicho puntero, *(x+2), es la fila 3. Si me
desplazo 5 posiciones en esa fila llego a la posicin
*(x+2)+5, cuyo contenido es *(*(x+2)+5).
Ismael Camarero
30
PUNTEROS Y ARRAYS
Si en
x[10][20] quiero acceder al elemento de la fila 3 y
la columna 6, lo hago escribiendo x[2][5]. Con notacin de
punteros, lo que hacemos es considerar que es un array
formado por 10 arrays unidimensionales (vectores) de 20
elementos cada uno, de modo que accedo a x[2][5] mediante
la expresin:
* ( * ( x + 2 ) +5)
Ver: ardepunt.cpp.
pmatcon.cpp
x[0][0] ;
x[0][1];
*(*(x+1))
x[1][0]
**(x+1)
x[1][0]
31
PUNTEROS Y ARRAYS
Si en
int array[filas][columnas];
array[1][1]
de memoria:
fila 0
fila 1
129
*(*(array+5)+1)
*(*array + 6)
PUNTEROS Y ARRAYS
Un array multidimensional es, en realidad, una coleccin de
vectores. Segn esto, podemos definir un array
bidimensional como un puntero a un grupo contiguo de arrays
unidimensionales. Las declaraciones siguientes son
equivalentes:
int dat[fil][col]
int (*dat)[col]
En general:
tipo_dato nombre[dim1][dim2]. . . . .[dimp]; equivale a:
tipo_dato (*nombre)[dim2][dim3]. . . . .[dimp];
Puntero a un grupo de arrays
Ismael Camarero
Ver pmatcon.cpp
33
PUNTEROS Y ARRAYS
El array:
int valor[x][y][z];
Ver: ardepun.cpp
(*valor)[1][2]
(*(valor+1))[y][z]
(*(valor+1)[1][1]
PUNTEROS Y ARRAYS
O como un ARRAY DE PUNTEROS:
int *valor[x][y];
sin parntesis
En su nueva declaracin desaparece
la ltima de sus dimensiones.
Array de 200
punteros,
cada uno de
los cuales
apunta a un
array de 30
elementos
int *x[10];
float p[10][20][30];
int *p[10][20];
Ismael Camarero
Ver
ejemp11.cpp
ejemp12.cpp
35
Punteros a CADENAS
Una cadena de caracteres es un array de caracteres. La
forma de definir un puntero a una cadena de caracteres:
char *cadena;
El identificador del array es la direccin de comienzo del
array. Para saber dnde termina la cadena, el compilador
aade el carcter \0 (ASCII 0, NULL):
char *nombre = PEPE PEREZ;
nombre
direccin de memoria
P E P E
*(nombre+2)
P E R E Z \0
contenido
36
Punteros a CADENAS
nombre
P E P E
P E R E Z \0
*(nombre+2)
Ver: pcad.cpp
arraycad.cpp
do
printf(%c, *(nombre+i);
Condicin de
salida
37
...
H O L
cad
cad+1
...
A \0
cad[4]
A D I
...
Ismael Camarero
O S
\0
...
38
39
reserva
... ...
...
... ...
Ismael Camarero
40
PUNTEROS A FUNCIONES:
Un puntero a funcin es una variable cuyos posibles
valores son direcciones en las que se encuentran
funciones.
La sintaxis de su definicin es la siguiente:
estilo nuevo:
tipo (*nombre)(tipo,... ,tipo)
estilo antiguo:
tipo (*nombre)(
);
Ismael Camarero
41
PUNTEROS A FUNCIONES:
La direccin de una funcin se obtiene con el nombre de la
funcin sin parntesis ni argumentos (no hace falta el operador
&): pf = nombre_funcin;
Si el puntero no apunta a ninguna funcin se inicializa a NULL:
pf = NULL;
42
44
PUNTEROS A PUNTEROS:
Ver ejemp4.cpp, ejemp11.cpp y ejemp12.cpp
int **puntero; //puntero a puntero a un objeto int.
El tipo de objeto apuntado despus de una doble indireccin
puede ser de cualquier clase.
Permite manejar arrays de mltiples dimensiones con
notaciones del tipo ***mat, de mltiple indireccin que
pueden generar problemas si el tratamiento no es el
adecuado.
Ismael Camarero
45
46
DECLARACIONES COMPLEJAS:
Uno de los ms importantes defectos del lenguaje es la
dificultad de la comprensin de las declaraciones donde
intervienen simultneamente punteros, funciones y arrays
La regla general para interpretar una declaracin
compleja compuesta por funciones y punteros se basa en
la precedencia de los operadores *, () y [].
() y [] mayor precedencia, asociatividad ID
*
menor precedencia, asociatividad DI
Ismael Camarero
47
DECLARACIONES COMPLEJAS
Para interpretar declaraciones complejas podemos seguir el
orden:
1) Empezar con el identificador y ver si hacia la derecha hay
corchetes o parntesis.
2) Interpretar esos corchetes o parntesis y ver si hacia la
izquierda hay asteriscos.
3) Dentro de cada nivel de parntesis, de ms internos a ms
externos, aplicar puntos 1 y 2.
Veamos un ejemplo:
48
6 4 2 1
La interpretacin es:
1. La variable var es declarada como
2. un puntero a
3. una funcin que devuelve
4. un puntero a
5
Para declaraciones
de mayor
complejidad, ver el
archivo
declarpunt.doc
49
DECLARACIONES COMPLEJAS
Para ver declaraciones de mayor complejidad, y su
significado, ver el documento de word:
declarpunt.doc
Ismael Camarero
50
Febrero-2001
Todos los ejemplos estn editados en el compilador
Borland C++ 3.1
Comentarios, erratas... icamarero98@hotmail.com
Deseo que te haya sido til
51