Documentos de Académico
Documentos de Profesional
Documentos de Cultura
21/10/2012
21/10/2012
Qu es un puntero?
Un
puntero es una variable que guarda o contiene la direccin de memoria de otra variable. Cuando una variable contiene la direccin de memoria de otra variable; entonces se dice que la primera variable apunta a la segunda variable. Al respecto examine la figura 1.
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
21/10/2012
Figura 1
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
21/10/2012
Operadores de punteros
C y C++ posee dos operadores para trabajar con punteros: Operador &, llamado tambin de referencia Operador *, llamado tambin de desreferencia
21/10/2012
Ejemplo 1: Programa que utiliza una variable entera y una variables puntero a entero. Note el uso de los operadores * y &.
#include <iostream> //mostrar el uso de punteros using namespace std; int main() // punter0.cpp { int x; // variable entera int *ptrX; // puntero a entero x = 150; // asignacion ptrX = &x; // asignacion cout<<"Variables y punteros"<<endl; cout<<"\nValor en x =\t"<<x<<endl; cout<<"valor apuntado por ptrX = "<< *ptrX <<endl; cout<<"Direccion de X =\t"<< &x <<endl; cout<<"Contenido de ptrX =\t"<< ptrX <<endl; cout<<"Direccion de ptrX =\t"<< &ptrX <<endl<<endl; return 0; }
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
21/10/2012
ptrX
0x22ff74 0x22ff70
ptrX
21/10/2012
21/10/2012
//parte 2 j = 500; pj = &j; cout<<"\nParte 2"<<endl; cout<<"Valor en j: "<<j<<"\tDireccion de j: "<<pj<<endl; cout<<"Valor apuntado por pj: "<<*pj<<" Direccion en pj: " <<pj<<endl;; pi = pj; cout<<"Valor apuntado por pi: "<<*pi<<"\tValor apuntado por pj: " <<*pj<<endl;
21/10/2012
//parte 3 *pj = *pi; cout<<"\nParte 3"<<endl; cout<<"Direccion almacenada en pi: "<<pi<<"\tDireccion almacenada en pj: " <<pj<<endl; cout<<"Valor apuntado por pi: "<<*pi<<"\tValor apuntado por pj: " <<*pj<<endl; cout<<"Valor en i: "<<i<<"\t\t\tValor en j: "<<j<<endl; cout<<"Direccion de pi: "<<&pi<<"\tDireccion de pj: "<<&pj<<endl; getche(); return 0; }
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
10
21/10/2012
11
21/10/2012
Parte 2:
j = 500; pj = &j; pi = pj;
pi 0x22ff70 pj 0x22ff70 pi pj j 500 0x22ff70 j 500
12
21/10/2012
Parte 3:
i 220 0x22ff74 j 500 0x22ff70 pi 0x22ff70 0x22ff6c pj 0x22ff70 0x22ff68 pi pj j 500 i 220
*pj = *pi;
13
21/10/2012
Aritmtica de punteros
Las operaciones de suma y resta son las nicas que estn permitidas a nivel de punteros, aunque su significado no es el mismo que en los tipo_dato base. Asuma que ptr1 es un puntero a entero y almacena 0xA100 y que adems, los enteros ocupan una longitud de cuatro bytes. Despus de realizar la expresin ptr1++; Har que ptr1 ahora contenga 0xA104. Esto significa que cada vez que ptr1 se incrementa en 1, apunta al siguiente entero en la memoria. Lo inverso tambin es cierto. Por ejemplo si ptr1 contiene 0xA100, la expresin. ptr1--;
14
21/10/2012
1: Cada vez que se incrementa un puntero, apunta a la posicin de memoria del siguiente elemento de su tipo_dato. 2: Cada vez que se decrementa un puntero apunta a la posicin de memoria del elemento anterior al de su tipo_dato.
Regla
15
21/10/2012
Estas reglas no son exclusivas para los operadores de incremento y disminucin, tambin se aplican a los operadores de suma y resta, por ejemplo se pueden sumar y restar enteros a punteros. De all que si ptrC es una variable que guarda la direccin de memoria 0xA110 y es un puntero a caracter (un caracter se almacena en un byte); entonces la expresin. ptrC = ptrC + 5; hace que ptrC apunte al elemento que se encuentra en la quinta posicin despus de ptrC; es decir, ptrC almacena ahora 0xA115;
Las dems operaciones aritmticas como multiplicar y dividir punteros no estn definidas; tampoco, se pueden aplicar la suma o resta del tipo float o double a los punteros.
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
16
21/10/2012
17
21/10/2012
18
21/10/2012
Comparacin de punteros
Dos punteros pueden compararse en una expresin relacional. Por ejemplo si p y r se han declarado y definido como punteros, la expresin.
if (p < r) cout<<p apunta a menor memoria que r\n; else cout<< p apunta a mayor memoria que r\n;
Es perfectamente vlida y correcta. La comparacin de punteros puede resultar til cuando dos punteros apuntan a un mismo objeto, como puede ser un array o una estructura de datos compuesta.
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
19
21/10/2012
Punteros a arrays
Es posible declarar un puntero a un array de enteros o de cualquier otro tipo de datos y pasarlos como argumentos a una funcin. El programa del ejemplo 4, muestra el paso de un array como un puntero al arreglo. En este caso el identificador del array es un puntero al array. Observe el primer argumento de la funcin pasarArray_3.
20
21/10/2012
21
21/10/2012
//Paso de un array como una referencia o puntero a el void pasarArray_3( int *num, int n ) { cout << "\nElementos en el array: "; int i; for ( i = 0; i <n; i++) cout<<num[i]<<" "; cout << endl; cout << "\nElementos apuntados: "; for ( i = 0; i < n; i++) cout<<*num++<<" "; cout << endl; cout << "\nDirecciones de los elementos: "; for (i = 0; i < n; i++) cout << num++<<" "; cout << endl << endl; }
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
22
21/10/2012
23
21/10/2012
Arrays de punteros
Al igual que cualquier otro tipo de datos, los punteros tambin pueden configurarse como arrays de punteros. La siguiente sentencia.
int *x[4];
declara x como un array de punteros a enteros(int) de tamao 4. Ver figura 8.
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
24
21/10/2012
25
21/10/2012
26
21/10/2012
//como una referencia o puntero void pasarArrayPunteros( int *num[], int n ) { cout<<"Enteros apuntados por el array de punteros:\n\n"; int i; for ( i = 0; i < n; i++) cout<<"num["<<i<<"] -> entero:<<*num[i] <<endl; cout<<endl; }
27
21/10/2012
28
21/10/2012
29
21/10/2012
I ) Indireccin simple
ptrX 0x22ff74 0x22ff70 x 500 0x22ff74
II ) Indireccin mltiple
ptrA 0x22ff70 0x22ff66 ptrB 0x22ff78 0x22ff70 ab 2500 0x22ff78
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
30
21/10/2012
Para que una variable sea un puntero a puntero tiene que ser declarada como tal. Para lograrlo se coloca un * adicional delante del identificador o nombre de la variable. Por ejemplo la declaracin. float **sueldoNuevo;
Indica al compilador que sueldoNuevo es un puntero a un puntero a float y no un simple puntero a float.
31
21/10/2012
32
21/10/2012
33
21/10/2012
Como ya sabemos el ndice de un array comienza en 0. De all que cad [8] *(ptrC + 8) se refieren al noveno elemento del array cad, esto es; para acceder al noveno elemento puede usarse 8 como ndice de cad, o tambin se puede sumar 8 al puntero ptrC; porque en el instante de su asignacin ptrC apunta realmente al primer elemento de cad.
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
34
21/10/2012
Se dice que el identificador de una cadena es un puntero a dicha cadena, de all que las declaraciones
char s[] = AMOR; s A M O R \0
y
char *s = AMOR; s A M O R \0
Se consideran equivalentes.
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
21/10/2012
37
21/10/2012
Devolucin de cadenas
Las cadenas pueden ser devueltas por una funcin siempre que se haga como un puntero a ella. La siguiente declaracin de funcin
char* devolverCadena(char cad1[], char cad2[]);
Indica al compilador que se devolver un puntero a un array de cadena de caracteres. Examine el ejemplo 8.
38
21/10/2012
Ejemplo 8: Devolviendo la cadena que resulta de concatenar dos cadenas recibidas como argumento.
#include <iostream> #include <string.h> #include <stdio.h> char* devolverCadena( char cad1[], char cad2[] ); using namespace std; int main() // cadena25.cpp { char cad1[80], cad2[80]; cout<<"Ingrese una cadena 1: "; gets(cad1); cout<<"Ingrese una cadena 2: "; gets(cad2); cout<<"Resultado: "<<devolverCadena(cad1,cad2)<<endl; return 0; }
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
39
21/10/2012
{ char blanco[] = " "; //adicionando un blanco al final de cad1 strcat(cad1,blanco); return (strcat(cad1,cad2)); }
// Version 2 char* copiacad(char *dest, char *orig) { int tam = strlen(orig); dest = new char[tam+1]; int i = 0; while( dest[i] = orig[i]) i++; return dest; }
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe 41
21/10/2012
42
21/10/2012
Ejemplo 10:Programa que crea un array de punteros a cadenas de caracteres, segn la figura 10.
char 0 1 2 3 4 5 *p[];
G E A D M a s n a e b t a v l i i r r i e L d s s e l u l l c M a a i e \0 a l J a C \0 e n d e z \0 r o a r \0 i \0
NULL
43 #include <iostream> #include <string.h> /* Objetivo: Arrays de punteros a cadenas */ //prototipo de las funciones int buscaNombres(char *p[], char *nomb); void printArrayCadenas(char *p[]); using namespace std;
21/10/2012
int main() // Array_Punteros_Cadenas.cpp { char *nombres[] = {"Gabriel Jara", "Estrella Cori", "Ana Lucia", "David Melendez", "Melissa", NULL}; printArrayCadenas(nombres); cout<<"Buscando en el array de cadenas:"<<endl<<endl; if ( buscaNombres(nombres,"Estrella Cori") != -1) cout<<"Estrella Cori; si esta en lista\n"; else cout<<"Estrella Cori; no esta en lista\n"; if ( buscaNombres(nombres,"Jose Carlos") == -1) cout<<"Jose Carlos; no esta en Lista\n"; else cout<<"Jose Carlos; si esta en lista\n"; return 0; } Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
int buscaNombres(char *p[], char *nomb) { for (int i = 0; p[i] ; ++i) if ( strcmp(p[i], nomb) == 0 ) return i; return -1; //codigo de error: no se encuentra } void printArrayCadenas(char *p[]) { cout << "\nCadenas en el array o vector:\n"<<endl; int i = 0; while (p[i] != NULL) { cout<<p[i]<<endl; i++; } cout<<endl<<endl; }
21/10/2012 Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe 44
Vectores de cadena
Es posible crear un vector de cadenas, por ejemplo la declaracin char vectorCads[4][80]; crea un vector de 4 cadenas cada una de longitud hasta 80 caracteres. Asumiendo que estas cuatro cadenas son: Hola como, estan, todos ustedes, por alli; se mapean en memoria como:
vectorCads Hola como estan todos ustedes por alli
21/10/2012
46
21/10/2012
donde C es la cadena original, nC es el vector de cadenas a generar y car es un carcter alfabtico cualquiera. La funcin genera un vector de cadenas cuyo contenido son las palabras que empiezan con el carcter car y finalmente devuelve la cantidad de elementos que se guardaron en el vector de cadenas. As por ejemplo, si car es el carcter e y la cadena C es:
Electron, tipo de particula elemental de carga negativa que forma parte de la familia de los leptones y que, junto con los protones y los neutrones, forma los atomos y las molculas. Los electrones estan presentes en todos los atomos y cuando son arrancados del atomo se llaman electrones libres". Tomado de Microsoft Encarta 2007. Se han omitido las tildes.
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
47
21/10/2012
#include <iostream> #include <string.h> const int N = 20; const int M = 80; int GeneraVectorCadena( char C[], char nC[N][M], char car); using namespace std; int main() // Matriz_Cadenas_071.cpp { char *C = "Electron, tipo de particula elemental de carga negativa que forma parte de la familia de los leptones y que, junto con los protones y los neutrones, forma los atomos y las molculas. Los electrones estan presentes en todos los atomos y cuando son arrancados del atomo se llaman electrones libres";
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
48
21/10/2012
cout<<"\nLongitud de la cadena C = "<<strlen(C)<<endl; char nC[N][M]; char car = 'e'; cout<<"\nPalabras en el vector de cadenas:"<<endl; int npals = GeneraVectorCadena(C, nC, car); cout<<"\nNumero de palabras almacenadas en el vector = " <<npals<<endl<<endl; return 0; }
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
49
21/10/2012
int GeneraVectorCadena( char C[], char nC[N][M], char car) { int i = 0, j, k = 0, contPal = 0; char palab[20]; while ( C[i] != 0 ) { // sacando cada palabra j = 0; while ( C[i] != ' ' ) { palab[j] = C[i]; j++; i++; } palab[j] = '\0'; // si primer caracter de palabra es igual a car if ( palab[0] == car ) { // se mete en el vector de cadenas strcpy(nC[k], palab); cout<<nC[k]<<endl;//imprime palabra almacenada en el vector k++; contPal++; } i++; } return contPal; }
Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe
50
21/10/2012
Referencias
1.
51
21/10/2012
Deitel H.M. y Deitel P.J. (2003). "C++ Cmo Programar". Mxico. Prentice-Hall Hispanoamericana., 1320 p. 2. Kernighan Brian W. & Ritchie Dennis M. (1991). El lenguaje de Programacin C Mxico. 2da. Edicin. Prentice-Hall Hispanoamericana., 294 p. 3. Ruiz Lizama Edgar (2009). Programacin con C++ Lima, 1ra. Edicin, fondo editorial UNMSM, 434 p. 4. Ruiz Lizama, Edgar (1999). "Curso de Lenguaje C" Lima, UNMSM Facultad de Ingeniera Industrial 150 p. 5. Schildt Herbert (2000). C Manual de Referencia Espaa. 4ta. Edicin, Osborne McGraw-Hill S.A. 709p. 6. Schildt Herbert (1996). C++ Para Programadores Madrid. McGraw Hill/Interamericana de Espaa S.A. 398p. 7. Stroustrup, Bjarne (1993). "El Lenguaje de Programacin C++". U.S.A. Addison Wesley Iberoamericana. 710 p. 8. Stroustrup, Bjarne (2002) "El Lenguaje de Programacin C++ Edicin especial". Espaa. Addison Wesley PEARSON EDUCACION S.A. 1050 p. E.R.L. Mg. Edgar Ruiz Lizama eruizl@industrial.unmsm.pe