Está en la página 1de 48

Algortmica I

Tema 4: Punteros:
Gestin Dinmica de Memoria
Profesor John Ledgard Trujillo Trejo

Ingeniera de Sistemas e Informtica Departamento de Ciencias de la Computacin Curso 2013-I

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.
Los punteros estn almacenados en algn lugar de la memoria y tienen su propia direccin. Se dice que un puntero apunta a una variable si su contenido es la direccin de esa variable. Un puntero ocupa de ordinario 4 bytes de memoria.

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

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

...

...

...

...

La direccin de la variable x es 1502


El contenido de la variable x es 25
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

Qu es un PUNTERO?

Las direcciones de memoria dependen de la arquitectura del ordenador y de la gestin que el sistema operativo haga de ella.
En lenguaje ensamblador se debe indicar numricamente la posicin fsica de memoria en que queremos almacenar un dato. De ah que este lenguaje dependa tanto de la mquina en la que se aplique. En C no debemos, ni podemos, indicar numricamente la direccin de memoria, si no que utilizamos una etiqueta que conocemos como variable. Lo que nos interesa es almacenar un dato, y no la localizacin exacta de ese dato en memoria.
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

Qu es un PUNTERO?

Los punteros se utilizan comnmente para: Manipular strings (cadenas de caracteres). Pasar argumentos en la lnea de comandos a un programa durante su ejecucin. Devolver ms de un valor en una funcin. Acceder a las variables que de otra manera no estaran visibles dentro de una funcin. Manipular los elementos de un array (tabla de datos) movindose a travs de ellos sin necesidad de utilizar el ndice. Acceder a la direccin de un rea de memoria que la aplicacin instala durante el tiempo de ejecucin. Pasar la direccin de una funcin a otra funcin.
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

Qu es un PUNTERO?
El ordenador mantiene una tabla de direcciones que relaciona el nombre de cada variable con su direccin en la memoria y el nmero de bytes de memoria que ocupe el tipo de datos de la variable. Gracias a los nombres de las variables (identificadores), de ordinario no hace falta que el programador se preocupe de la direccin de memoria donde estn almacenados sus datos.

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

DEFINICION DE PUNTEROS
Un puntero se define junto con el resto de datos, a la cabeza del algoritmo / funcin o procedimiento. El formato para definir un puntero es la siguiente: puntero a tipo_de_dato <identificador> // Lenguaje Algoritmico
En C/C++:

<tipo_dato_a_la_cual_se_apuntar>*<identificador_apuntador>;

Ejemplos de definicin de punteros: puntero a entero ApuntadorEntero; // apuntador para un valor entero int *ApuntadorEntero puntero a caracter ApuntadorCaracter // apuntador para un valor carcter char *ApuntadorCaracter; puntero a real ApuntadorFlotante; // apuntador para un valor flotante float *ApuntadorFlotante;
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

DEFINICION DE PUNTEROS
Al anteponer un * al identificador del apuntador se le indica al compilador que se est definiendo una variable de tipo puntero y no una variable comn. Hay tantos tipos de punteros como tipos de datos, aunque tambin pueden declararse punteros a estructuras ms complejas (funciones, struct, ficheros...) e incluso punteros vacos (void ) y punteros nulos (NULL). int *punt; Es una variable puntero que apunta a variable que contiene un dato de tipo entero llamada punt. char *car: Es un puntero a variable de tipo carcter. long float *num; float *mat[5]; // . . .
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

DEFINICION DE PUNTEROS
La direccin de una variable es un nmero y puede ser tratado como cualquier otro nmero en C/C++. Si se sabe la direccin de una variable, se puede crear una segunda variable donde se guarde la direccin de la primera. Ejemplo: se define la variable p_tasa y se reserva espacio de almacenamiento para p_tasa, pero su valor se encuentra indeterminado. Se guarda la direccin de la variable tasa en la variable p_tasa, entonces p_tasa apunta a la direccin de la variable tasa.

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

OPERADORES DE PUNTEROS: * Y &


a) Operador de direccin (&): Representa la direccin de memoria de la variable que le sigue: &Identificador_apuntador Permite obtener la direccin de memoria en la que se almacena una variable, generalmente para asignrsela a un puntero. Ejemplo: int a; int*b; a = 700; b = &a; //El puntero 'b' apunta a la direccin de memoria de a.

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

OPERADORES DE PUNTEROS: * Y &


b) Operador de contenido o indireccin (*): El operador * aplicado al nombre de un puntero indica el valor de la variable apuntada. *Identificador_apuntador
El contenido del lugar en la memoria identificador_apuntador. int i, j, *p; // p es un puntero a entero p = &i; *p = 10; p = &j; *p = -2;
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

en

donde i j

apunta p
00fa

// p contiene la direccin de i // i toma el valor 10. // p contiene ahora la direccin de j // j toma el valor -2
-2 10

00fa 01ff 01ff

#include <iostream.h> #include <conio.h> void main() { int a = 12, b = 45; int *p, *q; //Se declaran dos apuntadores a enteros clrscr(); cout<<"\nDireccion de a= "<<&a; cout<<"\nDireccion de b= "<<&b; cout<<"\na = "<<a<<" b = "<<b; cout<<"\nDireccion de p = "<<&p; cout<<"\nDireccion de q = "<<&q; p = &a; //Se asigna a p la direccin de a q = &b; //Se asigna a q la direccin de b cout<<"\nEl puntero p apunta a la direccion de a: "<<p; cout<<"\nY su contenido es: "<<*p; cout<<"\nEl puntero q apunta a la direccion de b: "<<q; cout<<"\nY su contenido es: "<<*q; } getch();
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

Un puntero tiene su propia direccin de memoria: &punt &car

INICIALIZACION DE PUNTEROS
1. Inicializarlo con el valor NULL (definido en un fichero header). De este modo estamos indicando que el puntero no apunta a ninguna memoria concreta. Como todas las variables, los punteros tambin contienen "basura" cuando son declaradas. Es costumbre dar valores iniciales nulos a los punteros que no apuntan a ningn sitio concreto: entero = NULL; caracter = NULL;
NULL es una constante, que est definida como cero en varios ficheros de cabecera, como "stdio.h" o "iostream.h", y normalmente vale 0L. 2. Inicializarlo haciendo que tome como valor la direccin de una variable. int *p, a; p = &a; A partir de estas sentencias, *p y a son alias.
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

#include <conio.h> #include <stdio.h>

void main() { int *punt = NULL, var = 14; punt = &var; printf("Las direcciones de punt y var son: "); printf("%x, %x", punt, &var); //la misma salida: direccin printf("\nLos valores de las variables son: "); printf("%d, %d", *punt, var); //salida: 14, 14 printf("\nLos nuevos valores incrementados en la unidad: "); printf("%d, %d", *(punt+1), var+1); printf(\nLas nuevas posiciones de memoria incrementado en la unidad: ); printf(%x, %x, punt + 1, &var + 1); getch(); }
Hay que tener cuidado con las direcciones apuntadas: printf(%d, %d, *(punt+1), var+1);

INICIALIZACION DE PUNTEROS

*(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. Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica punt + 1 representa lo mismo que &var + 1 (avance en la direccin de memoria de var).

INICIALIZACION DE PUNTEROS

< Almacenamiento > < Tipo >

* < Nombre > = < Expresin >

Si <Almacenamiento> es extern o static, <Expresion> deber ser una expresin constante del tipo <Tipo> expresado. Si <Almacenamiento> es auto, entonces <Expresion> puede ser cualquier expresin del <Tipo> especificado. Ejemplos: 1) La constante entera 0, NULL (cero) proporciona un puntero nulo a cualquier tipo de dato: int *p; p = NULL; //actualizacin
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

INICIALIZACION DE PUNTEROS

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. 4) Un puntero a carcter puede inicializarse en la forma: char *cadena = Esto es una cadena;
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

INICIALIZACION DE PUNTEROS

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;

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

#include <iostream.h> #include <conio.h> void main() { int entero ; // Se declara la variable entero. int *apuntador_entero ; // Se declara el apuntador apuntador_entero, // que apuntar a objetos de tipo int. apuntador_entero = NULL; entero = 100 ; // Se asigna el valor 100 a la variable entero apuntador_entero = &entero ; // Se asigna a apuntador_entero la direccin de entero // apuntador_entero apunta a entero. clrscr(); cout <<"apuntador_entero = "<<apuntador_entero; // muestra la direccin de //memoria de la variable entero cout << "\nentero = " << entero; // muestra 100 cout <<"\n*apuntador_entero = "<<*apuntador_entero; // muestra 100 *apuntador_entero = 200 ; // Se asigna el valor 200 al objeto apuntado por // apuntador_entero. cout <<"\napuntador_entero = "<<apuntador_entero; cout <<"\n*apuntador_entero = "<<*apuntador_entero; // muestra 200 cout <<"\nentero = " << entero; // muestra 200 getch(); }

INICIALIZACION DE PUNTEROS

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

#include <stdio.h> #include <conio.h> void main() { char caracter='A', *r; int a=12,b=45, c; int *p, *q; clrscr(); printf("Direccion de a = %p\n", &a); printf("Direccion de b = %p\n", &b); printf("a = %d b = %d\n", a, b); printf("Direccion de caracter = %p\n", &caracter); printf("caracter = %c\n", caracter); printf("Valor ASCII de caracter = %d\n", caracter); printf("Direccion de p = %p\n", &p); printf("Direccion de q = %p\n", &q); printf("Direccion de r = %p\n", &r); p = &a; q = &b; r = &caracter; printf("El puntero p apunta a la direccion: %p\n", p); printf("Y su contenido es: %d\n", *p); printf("El puntero q apunta a la direccion: %p\n", q); printf("Y su contenido es: %d\n", *q); printf("El puntero r apunta a la direccion: %p\n", r); printf("Y el contenido de *r es: %d\n", *r); printf("Como caracter ASCII *r contiene: %c\n", *r); getch(); I: John Ledgard Trujillo Trejo } Algortmica Ingeniera de Sistemas e Informtica

INICIALIZACION DE PUNTEROS

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 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 1504 1506 1508 1510 1512 1514 1516

16

-4

29

234

12

mat[0] mat[1] mat[2] mat[3] mat[4] mat[5] mat[6] mat[7]


Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

PUNTEROS Y ARRAYS
Direccin 1502 1504 1506 1508 1510 1512 1514 1516

16

-4

29

234

12

mat[0] mat[1] mat[2] mat[3] mat[4] mat[5] mat[6] mat[7]

El acceso podemos hacerlo mediante el ndice: x = mat[3] + mat[5]; // x = 29 + 12


para sumar los elementos de la cuarta y sexta posiciones. Como hemos dicho que podemos acceder por posicin y por direccin: Es lo mismo &mat[0] y mat? Y &mat[1] = mat++ ? Veamos el cdigo de un ejemplo:

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

#include <iostream.h> #include <conio.h> int mat[8]={2, 16, -4, 29, 234, 12, 0, 3}, i; //declaradas como globales void main() { cout<<"\nDireccion de mat[0] con &mat[0] = "<<&mat[0]; //direccin de mem cout<<"\nDireccion de mat[0] con mat = "<<mat; //direccin de mem cout<<"\nEl valor de mat[0] = "<<mat[0]; //valor de mat[0] for (i = 1; i<8; i++) { cout<<"\nDireccion de mat["<<i<<"] con mat + 1 = "<<mat+i; //direccin de mem //incrementado en 1 cout<<"\nDireccion de mat["<<i<<"] con &mat[i] = "<<&mat[i]; cout<<"\nValor de mat["<<i<<"] = "<<*(mat+i); }; getch();

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

PUNTEROS Y ARRAYS
Analizando las direcciones de memoria del array: Direccin del elemento 0 Direccin del octavo elemento

&mat[0] &mat[1] &mat[2] &mat[3] &mat[4] &mat[5] & mat[6] &mat[7]

2
mat

16
mat+1

-4
mat+2

29
mat+3

234

12

0
mat+6

3
mat+7

mat+4 mat+5

Puntero a la direccin del elemento 0

Incremento en una
unidad int (dos bytes)

mat++

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

PUNTEROS Y ARRAYS

De lo anterior se obtienen varias conclusiones: - Es lo mismo &mat[0] que mat, &mat[2] que mat + 2 - Para pasar de un elemento al siguiente, es lo mismo:
for(i=0; i<8; i++)
printf(&mat [%d] = %p, i, &mat[i]);

que el cdigo:
for(i=0; i<8; i++) printf(mat + %d = %p, i, mat + = i);

A esta forma de desplazarse en memoria se le llama Aritmtica de punteros


Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

PUNTEROS Y ARRAYS

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

ARITMTICA DE PUNTEROS: SUMA Y RESTA


Esta operacin provoca que el puntero avance (al sumar) o retroceda (al restar) en determinado nmero de posiciones de memoria. El valor del desplazamiento depende del tamao del tipo al que apunta un puntero. As, no es lo mismo sumar 1 a un puntero a caracteres que hacerlo con un puntero a nmeros reales. Por ejemplo, suponiendo que un carcter ocupa un byte, un entero dos bytes, y un nmero real cuatro bytes, cuando se le suma 5 a cada uno de ellos entonces cada una se desplazar: 1 x 5 = 5, (caracter) 2 x 5 = 10 y (entero) 4 x 5 = 20 (real)
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

posiciones de memoria. Veamos un ejemplo:

#include <conio.h> #include <iostream.h> void main() { int *puntero_entero, entero; float *puntero_real, real; puntero_entero = &entero; puntero_real = &real; clrscr(); cout<<"\nEl valor de puntero_entero es: "<<puntero_entero; cout<<"\nEl valor de puntero_real es: "<<puntero_real; puntero_entero = puntero_entero - 5; puntero_real = puntero_real - 5; cout<<"\n\nEl valor de puntero_entero - 5 es: "<<puntero_entero; cout<<"\nEl valor de puntero_real - 5 es: "<<puntero_real; puntero_entero = puntero_entero + 5; puntero_real = puntero_real + 5; cout<<"\n\nEl valor de puntero_entero + 5 es: "<<puntero_entero; cout<<"\nEl valor de puntero_real + 5 es: "<<puntero_real; getch();
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

ARITMTICA DE PUNTEROS: SUMA Y RESTA


Observar las siguientes instrucciones: int *p;

double *q;
void *r; p = &34; p = &(i+1); // puntero genrico // las constantes no tienen direccin // las expresiones no tienen direccin

&i = p;
pueden cambiar p = q; p = (int *)q;
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

//
// ilegal // legal

las

direcciones

no

se

ARITMTICA DE PUNTEROS: ARREGLOS


Utilizando la aritmtica de punteros nos desplazamos de unas posiciones de memoria a otras. Pero. cmo acceder a los contenidos de esas posiciones utilizando notacin de punteros?

mat[0] = 2
mat[0] mat[1] mat[2] mat[3] mat[4]

mat[7] = 3
mat[5] mat[6] mat[7]

2
*mat

16

-4

29

234

12

*(mat+1) *(mat+2) *(mat+4) *(mat+6) *(mat+3) *(mat+5) *mat = 2 *(mat+7) = 3

Empleamos el operador *, indireccin que nos da el contenido de la direccin de memoria apuntada.


Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

ARITMTICA DE PUNTEROS: ARREGLOS


Y... cmo se aplica la aritmtica de punteros para desplazarnos en un array bidimensional?: float mat[2][4]; //declaracin del array

Col 0 Fila 0 Fila 1

Col 1

Col 2

Col 3

1.45 20

-23.5 2.95

-14,08 0.082

17.3 6.023

Utilizando punteros, la declaracin ser: float (*mat)[4]; //array bidimensional En donde mat es un puntero a un grupo contiguo de arrays monodimensionales (vectores) de 4 elementos cada uno.

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

ARITMTICA DE PUNTEROS: ARREGLOS


Existe, por tanto una equivalencia:
Con subndices Con punteros Valor

mat[0[[0]
mat[0[[1]

*(*(mat+0)+0)
*(*(mat+0)+1)

1.45
-23.5

mat[0[[2]
mat[0[[3] mat[1[[0] mat[1[[2] mat[1[[3] mat[1[[4]

*(*(mat+0)+2)
*(*(mat+0)+3) *(*(mat+1)+0) *(*(mat+1)+1) *(*(mat+1)+2) *(*(mat+1)+3)

-14.08
17.3 20 2.95 0.082 6.023

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

Recordemos que *mat representa un puntero a la primera fila. A la segunda fila nos referimos mediante *(mat+1)+j para las direcciones y con *(*(mat+1)+j) para los contenidos. El segundo subndice actua sobre la columna.

ARITMTICA DE PUNTEROS: ARREGLOS


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). Ver dibujo:

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

ARITMTICA DE PUNTEROS: ARREGLOS


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) 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). Las siguientes expresiones con punteros son vlidas: **x *(*x+1) x[0][0]; x[0][1]; *(*(x+1)) **(x+1) x[1][0] x[1][0]

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

ARITMTICA DE PUNTEROS: ARREGLOS


Si en

int array[filas][columnas];

quiero acceder al elemento array[y][z] para asignarle un valor, lo que el compilador hace es: *(*array + columnas x y + z)) = valor; //asignacin

Si fuera int array[2][5] y quisiera asignar 129 al elemento de la fila 1 y columna 2, pondra: *(array + 5 x 1 + 1)) = 129; es decir, desde el origen del array avanza posiciones de memoria: array[1][1] fila 0 *(*(array+5)+1) fila 1 129 *(*array + 6)
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

ARITMTICA DE PUNTEROS: ARREGLOS


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

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

ARITMTICA DE PUNTEROS: ARREGLOS


El array: int valor[x][y][z]; int (*valor)[y][z]; Puede ser representado en la forma:

Puntero a un grupo de arrays bidimensionales


Sea el array valor[2][2][3]:

(*valor)[y][z]

(*valor)[1][2] (*(valor+1)[1][1]

(*(valor+1))[y][z]
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

ARITMTICA DE PUNTEROS: ARREGLOS


ARRAY DE PUNTEROS: Array de 200 punteros, cada uno de los cuales apunta a un array de 30 elementos

int *valor[x][y];
sin parntesis En su nueva declaracin desaparece la ltima de sus dimensiones.

Veamos ms declaraciones de arrays


de punteros:

int x[10][20];
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

int *x[10];
int *p[10][20];

float p[10][20][30];

PUNTEROS A CADENAS DE CARACTERES


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)
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

P E R E Z \0
contenido

PUNTEROS A CADENAS DE CARACTERES


nombre

P E P E

P E R E Z \0
*(nombre+2)

Si quiero recorrer la cadena con notacin de puntero:


i = 0;

do
printf(%c, *(nombre+i);

while(*(nombre+ i ++)); //postincremento


Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

Condicin de salida

ARRAYS DE PUNTEROS A CADENAS DE CARACTERES

En un array de punteros a cadenas de caracteres cada elemento apunta a un carcter. La declaracin ser: char *cad[10]; //por ejemplo Grficamente podra ser:

... cad

cad[0]

H O L

A \0

...

cad+1

cad[4]

A D I
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

O S

\0

...

ARRAYS DE PUNTEROS A CADENAS DE CARACTERES

La declaracin:
char cad[10][80];

Reserva memoria para 10 cadenas de caracteres de80 caracteres cada una. Pero en la declaracin como array de punteros:
char *cad[10];

el compilador desconoce el tamao de las cadenas: cunta memoria reserva? - si el array es static y se inicializan las cadenas en el propio cdigo, el compilador calcula la dimensin no explicitada (arrays sin dimensin explcita).
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

ARRAYS DE PUNTEROS A CADENAS DE CARACTERES

si las dimensiones no son conocidas, sabremos dnde comienzan las cadenas, pero no dnde terminan. Para ello se efecta la llamada reserva dinmica de memoria (funciones malloc, calloc(), realloc() y free() de stdlib.h alloc.h): char cad[10][80]; Equivale a inicio char **cad reservando 800 bytes

reserva

...

... ...

... ...

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

OTROS TIPOS DE PUNTEROS


Punteros genricos: Son tipo void: void *generico;

Los punteros tipo void pueden apuntar a otro tipo de datos. Es una operacin delicada que depende del tipo de compilador. Es conveniente emplear el casting para la conversin. An as, no todas las conversiones estn permitidas.
Puntero nulo: En C un puntero que apunte a un objeto vlido nunca tendr un valor cero. El valor cero se utiliza para indicar que ha ocurrido algn error (es decir, que alguna operacin no se ha podido realizar) int *p = NULL; //int *p=0;
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

OTROS TIPOS DE PUNTEROS

Punteros constantes: Una declaracin de puntero precedida de const hace que el objeto apuntado sea una constante (aunque no el puntero): const char *p = Valladolid; p[0] = f //error. La cadena apuntada por + es cte. p = Pucela //Ok. p apunta a otra cadena. Si lo que queremos es declarar un puntero constante; char *const p = Medina; p[0] = s; //error: el objeto Medina, es cte. p = Peafiel; //error: el puntero p es constante.
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

OTROS TIPOS DE PUNTEROS

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. Ojo a los punteros locos.
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

OTROS TIPOS DE PUNTEROS


Punteros a datos complejos: Se pueden declara punteros a datos definidos por el usuario (typedef()), a datos struct, a funciones, como argumentos de funciones... Declaraciones complejas: Una declaracin compleja es un identificador con ms de de un operador. Para interpretar estas declaraciones hace falta saber que los corchetes y parntesis (operadores a la derecha del identificador tienen prioridad sobre los asteriscos (operadores a la izquierda del identificador. Los parntesis y corchetes tienen la misma prioridad y se evalan de izquierda a derecha. A la izquierda del todo el tipo de dato.Empleando parntesis se puede cambiar el orden de prioridades. Las expresiones entre parntesis se evalan primero, de ms internas a ms externas.

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

OTROS TIPOS DE PUNTEROS


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: char *(*(*var)( ))[10]
Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica

Aplicando los puntos anteriores, podemos decir que

char *(*(*var)( ))[10]


7 6 4 2 1 3 5
La interpretacin es: 1. La variable var es declarada como 2. un puntero a 3. una funcin que devuelve 4. un puntero a 5. un array de 10 elementos, los cuales son 6. punteros a 7. objetos de tipo char.

Algortmica I: John Ledgard Trujillo Trejo Ingeniera de Sistemas e Informtica