2003 prentice hall, inc. all rights reserved. 1 capítulo 5. punteros y cadenas de caracteres...

38
2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización de Variables Punteros 5.3 Operadores de Punteros 5.4 Llamada a Funciones por Referencia 5.5 Uso de const con Punteros 5.6 Operador unario sizeof 5.7 Expresiones y Aritmética de Punteros 5.8 Relación entre Punteros y Arrays 5.9 Arrays de Punteros 5.10 Procesado de Caracteres y Cadenas - Fundamentos de Caracteres y Cadenas - Funciones de la Biblioteca de Manipulación de Cadenas

Upload: federico-carrera

Post on 22-Jan-2016

218 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

1

Capítulo 5. Punteros y Cadenas de Caracteres

Índice del Capítulo5.1 Introducción5.2 Declaración e Inicialización de Variables Punteros5.3 Operadores de Punteros5.4 Llamada a Funciones por Referencia5.5 Uso de const con Punteros5.6 Operador unario sizeof5.7 Expresiones y Aritmética de Punteros5.8 Relación entre Punteros y Arrays5.9 Arrays de Punteros5.10 Procesado de Caracteres y Cadenas

- Fundamentos de Caracteres y Cadenas- Funciones de la Biblioteca de Manipulación de

Cadenas

Page 2: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

2

5.1 Introducción

• Punteros – Muy potentes, pero difíciles de manejar

– Simulan el paso-por-referencia

– Permiten manipular estructuras de datos dinámicas (pueden crecer y decrecer dinámicamente)

– Estrecha relación con arrays y cadenas de caracteres

Page 3: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

3

5.2 Declaración e Inicialización de Punteros

• Variables puntero– Contienen direcciones de memoria como valores

– Normalmente, una variable contiene un valor específico (referencia directa)

– Los punteros contienen direcciones de variables que tienen un valor específico (referencia indirecta)

• Indirección– Referenciar un valor a través de un puntero

cont

7

contPtr

 

cont

7

Page 4: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

4

5.2 Declaración e Inicialización de Punteros

• Declaración de punteros– * indica que la variable es un puntero

int *miPtr;

declara un puntero a int– Varios punteros requieren varios asteriscos

int *miPtr1, *miPtr2;

– Se pueden declarar punteros a cualquier tipo de dato

• Inicialización de punteros– Inicializados a 0, NULL, o a una dirección de memoria

• 0 o NULL no apuntan a nada• NULL: constante simbólica definida en el archivo de

encabezado <iostream>

Page 5: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

5

5.3 Operadores de Punteros

• & (operador de dirección)– Operador unario que devuelve la dirección de memoria de su

operando

– Ejemplo: int y = 5;int *yPtr;yPtr = &y; // yPtr toma la dirección de y

• yPtr “apunta a” y, referencia indirectamente al valor de y

yPtr

y5

yptr

500000 600000

y

600000 5

La dirección de y es el valor de yptr

Page 6: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

6

5.3 Operadores de Puntero

• * (Operador de indirección/desreferenciación)– Devuelve un sinónimo del objeto al que apunta su puntero operando– *yPtr devuelve el valor de y (porque yPtr apunta a y).

– El puntero desreferenciado se puede usar en la parte izquierda de una asignación

*yptr = 9; // asigna 9 a y

cin >> *yptr; //lee un valor; lo asigna a y

• * y & son operadores inversos entre sí

Page 7: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc.All rights reserved.

Outline7

1 // Fig. 5.4: fig05_04.cpp2 // Uso de los operadores & y *.3 #include <iostream>4 5 using std::cout;6 using std::endl;7 8 int main()9 {10 int a; // a es un entero11 int *aPtr; // aPtr es un puntero a un entero12 13 a = 7;14 aPtr = &a; // a aPtr se le asigna la dirección de a15 16 cout << "La dirección de a es " << &a << endl;17 cout << "El valor de aPtr es " << aPtr << endl << endl;18 19 cout << "El valor de a es " << a << endl;20 cout << "El valor de *aPtr es " << *aPtr << endl << endl;21 22 cout << "Mostramos que * y & son operadores inversos entre sí" << endl;23 cout << "&*aPtr = " << &*aPtr << endl;24 cout << "*&aPtr = " << *&aPtr << endl;25 26 return 0;27 28 }

* y & son operadores inversos entre sí

Page 8: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc.All rights reserved.

Outline8

La dirección de a es 0012FED4

El valor de aPtr es 0012FED4

 

El valor de a es 7

El valor de *aPtr es 7

 

Mostramos que * y & son operadores inversos entre sí.

&*aPtr = 0012FED4

*&aPtr = 0012FED4 * y & son inversos; cuando se aplican ambos a aPtr se produce el mismo resultado.

Dependiendo de la máquina, la dirección se imprime como entero hexadecimal o decimal.

Page 9: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

9

5.4 Llamada a Funciones por Referencia

• 3 formas de pasar argumentos a una función– Paso-por-valor

– Paso-por-referencia con argumentos referencia

– Paso-por-referencia con argumentos puntero

• Paso-por-valor:– return puede devolver un único valor desde una función

• Paso-por referencia con argumentos referencia:– Modifican los valores originales de los argumentos

– “Devuelven” más de un valor

Page 10: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

10

5.4 Llamada a Funciones por Referencia

• Paso-por-referencia con argumentos puntero– Simulan el paso-por referencia mediante el uso de punteros y

operador de indirección (*)

– Pasa la dirección del argumento usando el operador &– Los arrays no se pasan usando & porque el nombre del array

ya es un puntero• miarray => &miarray[0]

– Operador * usado para formar un sinónimo para el nombre de la variable dentro de la función

Page 11: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc.All rights reserved.

Outline11

1 // Cubo de una variable usando paso-por-valor.2 #include <iostream>3 using std::cout;4 using std::endl;56 int cuboPorValor( int ); // prototipo7 8 int main()9 {10 int numero = 5;11 12 cout << "El valor original de numero es " << numero;13 // paso numero por valor a cuboPorValor14 numero = cuboPorValor( numero );15 cout << "\nEl nuevo valor de numero es " << numero << endl;16 17 return 0;18 }19 // calcula y devuelve el cubo de un argumento entero20 int cuboPorValor( int n ) 21 { 22 return n * n * n; // cubo de variable local n y devuelve resultado23 } // fin de función cuboPorValor

Paso numero por valor; resultado devuelto por cuboPorValor

El valor original de numero es 5

El nuevo valor de numero es 125

cuboPorValor recibe un parámetro pasado-por-valor

Eleva al cubo y devuelve la variable local n

Page 12: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc.All rights reserved.

Outline12

El valor original de numero es 5

El nuevo valor de numero es 125

1 // Cubo de una variable usando paso-por-referencia con un argumento puntero2 #include <iostream>3 using std::cout;4 using std::endl;5 6 void cuboPorReferencia( int * ); // prototipo7 8 int main()9 {10 int numero = 5;11 12 cout << "El valor original de numero es " << numero;13 // paso dirección de numero a cuboPorReferencia14 cuboPorReferencia( &numero );15 cout << "\nEl nuevo valor de numero es " << numero << endl;16 17 return 0;18 }19 // calcula cubo de *nPtr; modifica variable numero en main20 void cuboPorReferencia( int *nPtr )21 { 22 *nPtr = *nPtr * *nPtr * *nPtr; // cubo de *nPtr23 } // fin de función cuboPorReferencia

Aplica el operador dirección & para pasar la dirección de numero a cuboPorReferencia

cuboPorReferencia modificó variable numero

El prototipo indica que el parámetro es un puntero a int

cuboPorReferencia recibe la dirección de una variable int, es decir, un puntero a int

Modifica y accede a la variable int usando el operador de indirección *

Page 13: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

13

5.5 Uso de const con Punteros

• Calificador const– El valor de la variable no puede ser modificado– const se usa cuando la función no necesita modificar la

variable

• Principio de menor privilegio– Permitir a la función suficiente acceso para realizar la tarea,

pero no más

• Cuatro formas de pasar un puntero a una función– Puntero no constante a datos no constantes

• Mayor privilegio de acceso

– Puntero no constante a datos constantes– Puntero constante a datos no constantes– Puntero constante a datos constantes

• Menor privilegio de acceso

Page 14: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc.All rights reserved.

Outline14

1 // PUNTERO NO CONSTANTE A DATOS NO CONSTANTES: Conversión de minúsculas a mayúsculas2 #include <iostream>3 using std::cout;4 using std::endl;5 #include <cctype> // prototipos para islower y toupper6 7 void convertirAMayusculas( char * );8 9 int main()10 {11 char frase[] = "caracteres y 32.98$";12 13 cout << "La frase antes de la conversión es: " << frase;14 convertirAMayusculas( frase );15 cout << "\nLa frase después de la conversión es: " << frase << endl;16 17 return 0;18 }19 // convierte cadena a mayúsculas20 void convertirAMayusculas( char *cPtr ) 21 { 22 while ( *cPtr != '\0' ) { 23 if ( islower( *cPtr ) )24 *cPtr = toupper( *cPtr ); 25 ++cPtr;26 } // fin de while 27 } // fin de la función convierteAMayusculas

El parámetro es un puntero no constante a datos no constantes

convertirAMayusculas modifica la variable frase

La frase antes de la conversión es: caracteres y 32.98$

La frase después de la conversión es: CARACTERES Y 32.98$

cPtr: puntero no constante a datos no constantes

Función islower devuelve true si carácter en minúsculas

Function toupper devuelve carácter en mayúsculas si estaba en minúsculas; sino lo deja como estaba

Cuando se aplica el operador ++ a un puntero que apunta a un array, la dirección de memoria almacenada en el puntero se modifica para apuntar al siguiente elemento del array.

Page 15: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc.All rights reserved.

Outline15

1 // PUNTERO NO CONSTANTE A DATOS CONSTANTES: Impresión de una cadena carácter a carácter2 #include <iostream>3 using std::cout;4 using std::endl;5 6 void imprimeCaracteres( const char * );7 8 int main()9 {10 char frase[] = "imprime caracteres de una cadena";11 12 cout << "La cadema es:\n";13 imprimeCaracteres( frase );14 cout << endl;15 16 return 0;17 }18 // cPtr no puede modificar el carácter al que apunta19 // es decir, cPtr es un puntero de "sólo-lectura"20 void imprimeCaracteres( const char *cPtr )21 {22 for ( ; *cPtr != '\0'; cPtr++ ) // no inicialización23 cout << *cPtr;24 } // fin de función imprimeCaracteres

El parámetro es un puntero no constane a datos constantes.

Pasa el puntero frase a la función imprimeCaracteres.

La cadena es:

imprime caracteres de una cadena

cPtr es un puntero no constante a datos constantes; no se puede modificar el carácter al que apunta cPtr.

Incrementa cPtr para apuntar al siguiente carácter.

Page 16: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc.All rights reserved.

Outline16

1 // fig05_12.cpp: PUNTERO NO CONSTANTE A DATOS CONSTANTES: Intento de modificación de datos2 3 void f( const int * ); // prototipo4 5 int main()6 {7 int y;8 9 f( &y ); // f intenta una modificación no permitida10 11 return 0;12 }13 14 // xPtr no puede modificar el valor de la variable a la que apunta15 void f( const int *xPtr )16 {17 *xPtr = 100; // error: no se puede modificar un objeto const18 } // fin de función f

fig05_12.cpp: In function 'void f (const int *)':

fig05_12.cpp: 17: assignment of read-only location

El parámetro es un puntero no constante a datos constantes

Pasa la dirección de una variable int y para intentar una modificación no permitida.

Intento modificar el objeto const apuntado por xPtr.

Error producido al intentar compilar.

Page 17: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

17

5.5 Uso de const con Punteros

• Punteros const– Siempre apuntan a la misma localización de memoria

– Calificador por defecto para el nombre de un array

– Deben inicializarse al declararlos

Page 18: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc.All rights reserved.

Outline18

1 // fig05_13.cpp2 // PUNTERO CONSTANTE A DATOS NO CONSTANTES: Intento de modificar el puntero.3 4 int main()5 {6 int x, y;7 8 // ptr es un puntero contante a un entero que puede modificarse a través de ptr9 // pero ptr siempre apunta a la misma localización de memoria10 int * const ptr = &x; 11 12 *ptr = 7; // permitido: *ptr no es constante13 ptr = &y; // error: ptr es const; no puede asignársele una nueva dirección14 15 return 0; 16 }

fig05_13.cpp: In function 'int main()': fig05_13.cpp: 13: Assignment of read-only variable 'ptr'

ptr es un puntero constante a un entero.

Puede modificarse x (apuntado por ptr) pues x no es constante.

No puede modificarse ptr para apuntar a una nueva dirección pues ptr es constante.

La línea 13 genera un error de compilación al intentar asignar una nueva dirección a un puntero constante.

Page 19: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc.All rights reserved.

Outline19

fig05_14.cpp: In function 'int main()': fig05_14.cpp: 18: Assignment of read-only location

fig05_14.cpp: 18: Assignment of read-only variable 'ptr'

1 // fig05_14.cpp2 // PUNTERO CONSTANTE A DATOS CONSTANTES: Intento de modificación de datos y puntero3 #include <iostream>4 using std::cout;5 using std::endl;6 7 int main()8 {9 int x = 5, y;10 11 // ptr es un puntero constante a un entero constante. 12 // ptr siempre apunta a la misma localización;13 // el entero en dicha localización no puede modificarse.14 const int *const ptr = &x; 15 16 cout << *ptr << endl;17 *ptr = 7; // error: *ptr es const; no se le puede asignar un nuevo valor18 ptr = &y; // error: ptr es const; no se le puede asignar una nueva dirección19 20 return 0;21 }

ptr es un puntero constante a un entero constante.

No se puede modificar x (apuntado por ptr) pues *ptr se declara constante.

No se puede modificar ptr para apuntar a una nueva dirección pues ptr es constante.

Page 20: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

20

5.6 Operador unario sizeof• sizeof

– Operador unario (no función) que devuelve tamaño del operando en bytes como un valor de tipo size_t (definido en archivo <cstddef>), que generalmente es un unsigned int• <cstddef> suele estar incluido en otros archivos como <cstdlib> y <cstring>

– Para arrays, sizeof devuelve: ( tamaño de 1 elemento ) * ( número de elementos )

– Si sizeof( int ) es 4, entoncesint miArray[10]; cout << sizeof miArray;

imprimirá 40– *ptr=miArray; cout << sizeof ptr;

imprimirá el tamaño en bytes del puntero (4), no del tamaño del array.– Nº elementos = sizeof miArray / sizeof ( int );

• sizeof puede usarse con:– Nombres de variables– Nombres de tipos (paréntesis obligatorios)– Valores constantes

Page 21: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc.All rights reserved.

Outline21

El número de bytes del array es 160

El número de bytes devuelto por obtieneTamanho es 4

1 // fig05_16.cpp2 // Operador sizeof usado con nombre de array devuelve el nº de bytes del array.3 #include <iostream>4 #include <cstddef>4 using std::cout;5 using std::endl;6 size_t obtieneTamanho( double * ); // prototipo7 8 int main()9 {10 double array[ 20 ];11 cout << "El número de bytes del array es " 12 << sizeof( array );13 cout << "\nEl número de bytes devuelto por obtieneTamanho es "14 << obtieneTamanho( array ) << endl;15 16 return 0;17 }18 // función que devuelve el tamaño de ptr19 size_t obtieneTamanho( double *ptr )20 {21 return sizeof( ptr );22 } // fin de la función obtieneTamanho

Operador sizeof aplicado a un array devuelve el número total de bytes que ocupa el array.

Función obtieneTamanho devuelve el número de bytes usado para almacenar la dirección array.

Operador sizeof devuelve el número de bytes del puntero.

Page 22: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc.All rights reserved.

Outline22

1 // fig05_17.cpp: Demostración del operador sizeof.2 #include <iostream>3 using std::cout;4 using std::endl;5 int main()6 {7 char c;8 short s;9 int i;10 long l;11 float f;12 double d;13 long double ld;14 int array[ 20 ];15 int *ptr = array;16 cout << "sizeof c = " << sizeof c << "\tsizeof(char) = " << sizeof( char )17 << "\nsizeof s = " << sizeof s << "\tsizeof(short) = " << sizeof( short )18 << "\nsizeof i = " << sizeof i << "\tsizeof(int) = " << sizeof( int )19 << "\nsizeof l = " << sizeof l << "\tsizeof(long) = " << sizeof( long )20 << "\nsizeof f = " << sizeof f << "\tsizeof(float) = " << sizeof( float )21 << "\nsizeof d = " << sizeof d << "\tsizeof(double) = " << sizeof( double )22 << "\nsizeof ld = " << sizeof ld 23 << "\tsizeof(long double) = " << sizeof( long double )24 << "\nsizeof array = " << sizeof array << "\nsizeof ptr = " << sizeof ptr25 << endl;26 return 0;27 }

Operador sizeof puede usarse con nombre de variable.

Operador sizeof puede usarse con nombre de tipo.

Page 23: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc.All rights reserved.

Outline23

sizeof c = 1 sizeof(char) = 1

sizeof s = 2 sizeof(short) = 2

sizeof i = 4 sizeof(int) = 4

sizeof l = 4 sizeof(long) = 4

sizeof f = 4 sizeof(float) = 4

sizeof d = 8 sizeof(double) = 8

sizeof ld = 12 sizeof(long double) = 12

sizeof array = 80

sizeof ptr = 4

Page 24: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

24

5.7 Expresiones y Aritmética de Punteros• Aritmética de punteros

– Incremento/decremento de un puntero (++ o --)

– Suma/resta de un entero a/de un puntero( + o += , - o -=)

– Los punteros se pueden restar entre sí

– Aritmética de punteros sin significado a no ser que se realice sobre un puntero a array

– Ejemplo: Array de 5 elementos int en máquina con tamaño 4 bytes para ints• vPtr apunta al primer elemento v[ 0 ], que es la localización de

memoria 3000,

vPtr=v; vPtr=&v[0];• vPtr += 2; fija vPtr a 3008

vPtr apunta a v[ 2 ]• ++vPtr; --vPtr; puntero a variable vPtr

v[0] v[1] v[2] v[4]v[3]

3000 3004 3008 3012 3016

localización

 

Page 25: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

25

5.7 Expresiones y Aritmética de Punteros

– Resta de punteros• Devuelve el número de elementos entre las dos direcciones

vPtr2 = &v[ 2 ];vPtr = &v[ 0 ];vPtr2 - vPtr == 2

• Asignación de punteros– Un puntero puede asignarse a otro puntero si ambos son del

mismo tipo– Si no son del mismo tipo, se debe usar un operador de molde– Excepción: puntero a void (tipo void *)

• Puntero genérico, representa cualquier tipo• No se necesita molde para convertir puntero a puntero a void

pero sí viceversa.• Punteros a void no pueden desreferenciarse, pues no se sabe

el tipo de datos del puntero no se sabe cuántos bytes ocupa.

Page 26: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

26

5.7 Expresiones y Aritmética de Punteros

• Comparación de punteros– Mediante los operadores de igualdad y relacionales

– Comparaciones sin significado a no ser que los punteros apunten a miembros del mismo array

– Comparación de direcciones almacenadas en punteros

– Ejemplo: podríamos mostrar que un puntero apunta a un elemento del array con mayor índice que otro puntero

– Uso común para determinar si un puntero es 0 (no apunta a nada)

Page 27: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

27

5.8 Relación entre Punteros y Arrays

• Arrays y punteros estrechamente relacionados– Nombre de un array similar a puntero constante

– Punteros pueden realizar operaciones de índices de arrays

• Acceso a los elementos de un array con punteros:– Ejemplo: int b[5]; bPtr=&b[0]; o bPtr=b;– Notación de puntero y desplazamiento: Acceso al elemento b[ n ] mediante *(bPtr+n)

– Direcciones:• &b[ 3 ] es lo mismo que bPtr + 3

– El nombre del array puede tratarse como un puntero:• b[ 3 ] es lo mismo que *( b + 3 )

– Notación de puntero y subíndice: los punteros pueden usar índices• bPtr[ 3 ] es lo mismo que b[ 3 ]

– b=puntero constante b+=3; produce error de sintaxis

Page 28: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc.All rights reserved.

Outline28

1 // fig05_20.cpp: Uso de notación de punteros e índices con arrays2 #include <iostream>3 using std::cout;4 using std::endl;5 int main()6 {7 int b[] = { 10, 20, 30, 40 };8 int *bPtr = b; // hago que bPtr apunte al array b9 cout << "Array b impreso con:\n";1011 // imprimo array b usando notación de índices12 cout << "\nNotación de índices de arrays\n";13 for ( int i = 0; i < 4; i++ )14 cout << "b[" << i << "] = " << b[ i ] << endl;1617 // imprimo array b usando nombre de array y notación de puntero y desplazamiento18 cout << "\nNotación puntero/desplazamiento con puntero=nombre de array\n";19 for ( int desplaz1 = 0; desplaz1 < 4; desplaz1++ )20 cout << "*(b + " << desplaz1 << ") = " << *( b + desplaz1 ) << endl;2122 // imprimo array b usando bPtr y notación de índices de arrays23 cout << "\nNotación puntero/subíndice\n";24 for ( int j = 0; j < 4; j++ )25 cout << "bPtr[" << j << "] = " << bPtr[ j ] << endl;2627 // imprimo array b usando bPtr y notación puntero/desplazamiento28 cout << "\nNotación puntero/desplazamiento\n";29 for ( int desplaz2 = 0; desplaz2 < 4; desplaz2++ )30 cout << "*(bPtr + " << desplaz2 << ") = " << *( bPtr + desplaz2 ) << endl;31 return 0;32 }

Usando notación de índices de array.

Usando nombre de array y notación puntero/desplazamiento.

Usando notación de puntero/subíndice.

Usando bPtr y notación puntero/desplazamiento.

Page 29: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc.All rights reserved.

Outline29

Array b impreso con:

 

Notación de índices de arrays

b[0] = 10

b[1] = 20

b[2] = 30

b[3] = 40

 

Notación puntero/desplazamiento con puntero=nombre de array

*(b + 0) = 10

*(b + 1) = 20

*(b + 2) = 30

*(b + 3) = 40

Notación puntero/subíndice

bPtr[0] = 10

bPtr[1] = 20

bPtr[2] = 30

bPtr[3] = 40

 

Notación puntero/desplazamiento

*(bPtr + 0) = 10

*(bPtr + 1) = 20

*(bPtr + 2) = 30

*(bPtr + 3) = 40

Page 30: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc.All rights reserved.

Outline301 // fig05_21.cpp: Copia de una cadena usando notación de arrays y notación de punteros

2 #include <iostream>3 using std::cout;4 using std::endl;5 void copia1( char *, const char * ); // prototipo6 void copia2( char *, const char * ); // prototipo7 int main()8 {9 char cadena1[ 10 ];10 char *cadena2 = "Hola";11 char cadena3[ 10 ];12 char cadena4[] = "Hasta luego";13 14 copia1( cadena1, cadena2 );15 cout << "cadena1 = " << cadena1 << endl;16 copia2( cadena3, cadena4 );17 cout << "cadena3 = " << cadena3 << endl;18 return 0;19 }20 // función que copia c2 a c1 usando notación de arrays21 void copia1( char *c1, const char *c2 )22 {23 for ( int i = 0; ( c1[ i ] = c2[ i ] ) != '\0'; i++ )24 ; // no hace nada en el cuerpo del bloque for 25 } // fin de función copia126 // función que copia c2 en c1 usando notación de punteros27 void copia2( char *c1, const char *c2 )28 {29 for ( ; ( *c1 = *c2 ) != '\0'; c1++, c2++ )30 ; // no hace nada en el cuerpo del bloque for 31 } // fin de la función copia2

cadena1 = Holacadena3 = Hasta luego

Usa notación de índices de array para copiar la cadena c2 al array de caracteres c1.

Usa notación de punteros para copiar cadena c2 al array de caracteres c1.

Incrementa ambos punteros para apuntar a los siguientes elementos en sus arrays correspondientes.

Page 31: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

31

5.9 Arrays de Punteros

• Los arrays pueden contener punteros– Comúnmente usados para almacenar arrays de cadenas de

caractereschar * palos[ 4 ] = {"Corazones", "Tréboles", "Picas", "Diamantes" };

– Cada elemento de palos apunta a un char * (una cadena)– El array no almacena cadenas, sólo punteros a cadenas

– El array palos tiene tamaño fijo, pero las cadenas pueden ser de cualquier tamaño

palos[3]

palos[2]

palos[1]

palos[0] ’C’ ’o’ ’r’ ’a’ ’z’ ’o’ ’n’

’T’ ’r’ ’é’ ’b’ ’o’ ’l’ ’e’ ’s’ ’\0’

’P’ ’i’ ’c’ ’a’ ’s’ ’\0’

’D’ ’i’ ’a’ ’m’ ’a’ ’n’ ’t’

’e’ ’s’ ’\0’

’e’ ’s’ ’\0’

Cada elemento es un puntero a char

Array de 4 elementos

Page 32: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

325.10 Procesado de Caracteres y Cadenas 5.10.1 Fundamentos de Caracteres y

Cadenas • Constantes de caracteres

– Valores enteros representados como un carácter entre comillas simples

– 'z' es el valor entero de z (122 en ASCII)

• Cadenas– Serie de caracteres tratados como una unidad

– Puede incluir letras, dígitos, caracteres especiales +, -, * ...

– Constantes de cadena• Encerradas entre comillas dobles, por ejemplo:

"Me gusta programar en C++"

– Array de caracteres, finaliza con carácter nulo '\0'– Una cadena es un puntero constante, es decir, es un puntero

al primer carácter de la cadena (como los arrays)

Page 33: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

335.10 Procesado de Caracteres y Cadenas 5.10.1 Fundamentos de Caracteres y

Cadenas • Asignación de cadenas

– Array de caracteres• char color[] = "azul";

– Crea un array color de 5 elementos char (el último elemento es '\0‘)

– Alternativa:

char color[] = {'a', 'z', 'u', 'l', '\0'};

– Variable de tipo char *• char *colorPtr = "azul";

– Crea puntero colorPtr a letra 'a' en cadena "azul"– "azul" en algún lugar de la memoria

Page 34: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

345.10 Procesado de Caracteres y Cadenas 5.10.1 Fundamentos de Caracteres y

Cadenas • Lectura de cadenas

– Asigna la entrada al array de caracteres palabra[ 20 ]cin >> palabra;

• Lee caracteres hasta que encuentra espacio, tabulación, salto de línea o fin de fichero

• La cadena podría exceder el tamaño del array.

– Solución:

cin >> setw( 20 ) >> palabra;• Lee 19 caracteres (el carácter nº 20 se reserva para '\0')

Page 35: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

355.10 Procesado de Caracteres y Cadenas 5.10.1 Fundamentos de Caracteres y

Cadenas • cin.getline

– Lee una línea de texto– Formato:

• cin.getline( array, tamanho, delimitador );• delimitador no necesario (valor por defecto = '\n')

– Copia entrada en array especificado hasta que se cumple alguna de las condiciones:

• Se alcanza tamanho-1• Se introduce el carácter delimitador• Se alcanza el fin del fichero

– Ejemplo:char frase[ 80 ];cin.getline( frase, 80, '\n' );cin.getline( frase, 80 );

Page 36: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

365.10 Procesado de Caracteres y Cadenas 5.10.2 Funciones de la Biblioteca de

Manipulación de Cadenas

• Biblioteca de manipulación de cadenas <cstring> proporciona funciones para:– Manipular cadenas de datos

– Comparar cadenas

– Búsqueda de caracteres y cadenas dentro de cadenas

– Atomizar cadenas (separación de cadenas en partes lógicas)

– Determinar longitud de cadena

– En algunas de estas funciones:• Tipo de datos size_t: definido en archivo <cstddef>

(incluido en <cstring> y en <cstdlib> como entero sin signo).

Page 37: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

375.10 Procesado de Caracteres y Cadenas 5.10.2 Funciones de la Biblioteca de

Manipulación de Cadenas char *strcpy( char *s1, const char *s2 );

Copia la cadena s2 en el array de caracteres s1. Se devuelve el valor de s1.

char *strncpy( char *s1, const char *s2, size_t n );

Copia un máximo de n caracteres de la cadena s2 en el array de caracteres s1. Se devuelve el valor de s1.

char *strcat( char *s1, const char *s2 );

Añade la cadena s2 a la cadena s1. El primer carácter de s2 sobreescribe el carácter nulo de terminación de s1. Se devuelve el valor de s1.

char *strncat( char *s1, const char *s2, size_t n );

Añade un máximo de n caracteres de la cadena s2 a la cadena s1. El primer carácter de s2 sobreescribe el carácter nulo de terminación de s1. Se devuelve el valor de s1.

int strcmp( const char *s1, const char *s2 );

Compara la cadena s1 con la cadena s2. La función devuelve cero, menor que cero o mayor que cero si s1 es igual, menor o mayor que s2, respectivamente.

Page 38: 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 5. Punteros y Cadenas de Caracteres Índice del Capítulo 5.1 Introducción 5.2 Declaración e Inicialización

2003 Prentice Hall, Inc. All rights reserved.

385.10 Procesado de Caracteres y Cadenas 5.10.2 Funciones de la Biblioteca de

Manipulación de Cadenas int strncmp( const char *s1, const char *s2, size_t n );

Compara un máximo de n caracteres de la cadena s1 con la cadena s2. La función devuelve cero, menor que cero o mayor que cero si s1 es igual, menor o mayor que s2, respectivamente.

char *strtok( char *s1, const char *s2 );

Una secuencia de llamadas a strtok rompe la cadena s1 en “átomos”—partes lógicas como palabras en un texto—delimitadas por caracteres contenidos en la cadena s2. La primera llamada contiene s1 como primer argumento, y las siguientes llamadas que dividen la misma cadena en átomos contienen NULL como primer argumento. Cada llamada devuelve un apuntador al átomo actual. Si no hay más átomos al llamar a la función, se devuelve NULL.

size_t strlen( const char *s ); Determina la longitud de la cadena s. Devuelve el número de caracteres que precede al carácter nulo de terminación.