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
 2003 Prentice Hall, Inc. All rights reserved.
1
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
 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
cont
– Normalmente, una variable contiene un valor específico 7
(referencia directa)
– Los punteros contienen direcciones de variables que tienen
cont
un valor específico (referencia indirecta) contPtr
• Indirección
– Referenciar un valor a través de un puntero
 2003 Prentice Hall, Inc. All rights reserved.
7
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>
 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
y
5
yptr
500000
600000
y
600000
La dirección
de y es el
valor de yptr
 2003 Prentice Hall, Inc. All rights reserved.
5
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;
cin >> *yptr;
// asigna 9 a y
//lee un valor; lo asigna a y
• * y & son operadores inversos entre sí
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
7
// Fig. 5.4: fig05_04.cpp
// Uso de los operadores & y *.
#include <iostream>
Outline
using std::cout;
using std::endl;
int main()
{
int a;
int *aPtr;
a = 7;
aPtr = &a;
// a es un entero
// aPtr es un puntero a un entero
// a aPtr se le asigna la dirección de a
cout << "La dirección de a es " << &a << endl;
cout << "El valor de aPtr es " << aPtr << endl << endl;
cout << "El valor de a es " << a << endl;
cout << "El valor de *aPtr es " << *aPtr << endl << endl;
cout << "Mostramos que * y & son operadores inversos entre sí" << endl;
cout << "&*aPtr = " << &*aPtr << endl;
* y & son operadores
cout << "*&aPtr = " << *&aPtr << endl;
inversos entre sí
return 0;
}
 2003 Prentice Hall, Inc.
All rights reserved.
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
8
Dependiendo de la máquina, la
dirección se imprime como
entero hexadecimal o decimal.
Mostramos que * y & son operadores inversos entre sí.
&*aPtr = 0012FED4
*&aPtr = 0012FED4
* y & son inversos; cuando
Outline
se
aplican ambos a aPtr se
produce el mismo resultado.
 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
 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
 2003 Prentice Hall, Inc. All rights reserved.
1
// Cubo de una variable usando paso-por-valor.
2
#include <iostream>
3
using std::cout;
4
using std::endl;
5
6
int cuboPorValor( int );
// prototipo
7
8
int main()
9 {
10
int numero = 5;
11
12
cout << "El valor original de numero es " << numero;
Paso numero por valor; resultado
13
// paso numero por valor a cuboPorValor
devuelto por cuboPorValor
14
numero = cuboPorValor( numero );
15
cout << "\nEl nuevo valor de numero es " << numero << endl;
16
17
return 0;
18 }
cuboPorValor recibe un
19 // calcula y devuelve el cubo de un argumento entero
parámetro pasado-por-valor
20 int cuboPorValor( int n )
21 {
22
return n * n * n; // cubo de variable local n y devuelve resultado
23 } // fin de función cuboPorValor
Outline
El valor original de numero es 5
El nuevo valor de numero es 125
Eleva al cubo y devuelve la
variable local n
 2003 Prentice Hall, Inc.
All rights reserved.
11
12
1
// Cubo de una variable usando paso-por-referencia con un argumento puntero
2
#include <iostream>
3
using std::cout;
El prototipo indica que el
4
using std::endl;
parámetro es un puntero a int
5
6
void cuboPorReferencia( int * );
// prototipo
7
8 int main()
9 {
Aplica el operador dirección & para
10
int numero = 5;
pasar la dirección de numero a
11
12
cout << "El valor original de numero es " << numero; cuboPorReferencia
13
// paso dirección de numero a cuboPorReferencia
cuboPorReferencia
14
cuboPorReferencia( &numero );
15
cout << "\nEl nuevo valor de numero es " << numero << endl;
modificó variable numero
16
17
return 0;
18 }
cuboPorReferencia recibe la
19 // calcula cubo de *nPtr; modifica variable numero en main
dirección de una variable int, es
20 void cuboPorReferencia( int *nPtr )
decir, un puntero a int
21 {
22
*nPtr = *nPtr * *nPtr * *nPtr; // cubo de *nPtr
23 } // fin de función cuboPorReferencia
Outline
El valor original de numero es 5
El nuevo valor de numero es 125
Modifica y accede a la
variable int usando el
operador de indirecció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
 2003 Prentice Hall, Inc. All rights reserved.
14
1
// PUNTERO NO CONSTANTE A DATOS NO CONSTANTES: Conversión de minúsculas a mayúsculas
2
#include <iostream>
3
using std::cout;
4
using std::endl;
5
#include <cctype>
// prototipos para islower y toupper
El parámetro es un puntero no
6
constante a datos no
7 void convertirAMayusculas( char * );
constantes
8
9 int main()
10 {
11
char frase[] = "caracteres y 32.98$";
12
convertirAMayusculas
13
cout << "La frase antes de la conversión es: " << frase;
modifica la variable frase
14
convertirAMayusculas( frase );
15
cout << "\nLa frase después de la conversión es: " << frase << endl;
16
cPtr: puntero no constante a datos no constantes
17
return 0;
18 }
Función islower devuelve true si carácter en
19 // convierte cadena a mayúsculas
minúsculas
20 void convertirAMayusculas( char *cPtr )
21 {
Function toupper devuelve carácter en
22
while ( *cPtr != '\0' ) {
mayúsculas si estaba en minúsculas; sino lo deja
23
if ( islower( *cPtr ) )
como estaba
24
*cPtr = toupper( *cPtr );
25
++cPtr;
Cuando se aplica el operador ++ a un
26
} // fin de while
puntero que apunta a un array, la
27 } // fin de la función convierteAMayusculas
Outline
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$
dirección de memoria almacenada en el
puntero se modifica para apuntar al
2003array.
Prentice Hall, Inc.
siguiente elementodel
All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// PUNTERO NO CONSTANTE A DATOS CONSTANTES: Impresión de una cadena carácter a carácter
#include <iostream>
using std::cout;
El parámetro es un puntero no
using std::endl;
Outline
constane a datos constantes.
void imprimeCaracteres( const char * );
int main()
{
char frase[] = "imprime caracteres de una cadena";
cout << "La cadema es:\n";
imprimeCaracteres( frase );
cout << endl;
Pasa el puntero frase a la
función imprimeCaracteres.
return 0;
}
// cPtr no puede modificar el carácter al que apunta
cPtr es un puntero no constante a
// es decir, cPtr es un puntero de "sólo-lectura"
datos constantes; no se puede modificar
void imprimeCaracteres( const char *cPtr )
el carácter al que apunta cPtr.
{
for ( ; *cPtr != '\0'; cPtr++ )
// no inicialización
cout << *cPtr;
} // fin de función imprimeCaracteres
Incrementa cPtr para
apuntar al siguiente carácter.
La cadena es:
imprime caracteres de una cadena
 2003 Prentice Hall, Inc.
All rights reserved.
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// fig05_12.cpp: PUNTERO NO CONSTANTE A DATOS CONSTANTES: Intento de modificación de datos
16
Outline
void f( const int * );
// prototipo
El parámetro es un puntero no
constante a datos constantes
int main()
{
int y;
f( &y );
Pasa la dirección de una variable int y
para intentar una modificación no
permitida.
// f intenta una modificación no permitida
return 0;
}
// xPtr no puede modificar el valor de la variable a la que apunta
void f( const int *xPtr )
{
*xPtr = 100; // error: no se puede modificar un objeto const
} // fin de función f
Intento modificar el objeto
const apuntado por xPtr.
Error producido al intentar compilar.
fig05_12.cpp: In function 'void f (const int *)':
fig05_12.cpp: 17: assignment of read-only location
 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
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// fig05_13.cpp
// PUNTERO CONSTANTE A DATOS NO CONSTANTES: Intento de modificar el puntero.
18
Outline
int main()
{
int x, y;
// ptr es un puntero contante a un entero que puede modificarse a través de ptr
// pero ptr siempre apunta a la misma localización de memoria
int * const ptr = &x;
ptr es un puntero constante a un entero.
}
*ptr = 7;
ptr = &y;
// permitido: *ptr no es constante
// error: ptr es const; no puede asignársele una nueva dirección
return 0;
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.
fig05_13.cpp: In function 'int main()':
fig05_13.cpp: 13: Assignment of read-only variable 'ptr'
La línea 13 genera un error de compilación al
intentar asignar una nueva dirección a un puntero
constante.
 2003 Prentice Hall, Inc.
All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// fig05_14.cpp
// PUNTERO CONSTANTE A DATOS CONSTANTES: Intento de modificación de datos y puntero
#include <iostream>
using std::cout;
using std::endl;
Outline
int main()
{
int x = 5, y;
// ptr es un puntero constante a un entero constante.
// ptr siempre apunta a la misma localización;
// el entero en dicha localización no puede modificarse.
const int *const ptr = &x;
ptr es un puntero constante a un entero constante.
cout << *ptr << endl;
*ptr = 7; // error: *ptr es const; no se le puede asignar un nuevo valor
ptr = &y; // error: ptr es const; no se le puede asignar una nueva dirección
return 0;
}
No se puede modificar ptr para
apuntar a una nueva dirección pues
ptr es constante.
No se puede modificar x (apuntado por ptr)
pues *ptr se declara constante.
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'
 2003 Prentice Hall, Inc.
All rights reserved.
19
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, entonces
int 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
 2003 Prentice Hall, Inc. All rights reserved.
21
1
// fig05_16.cpp
2
// 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 * ); // prototipo
7
Operador sizeof aplicado a un
8 int main()
9 {
array devuelve el número total de
10
double array[ 20 ];
bytes que ocupa el array.
11
cout << "El número de bytes del array es "
12
<< sizeof( array );
13
cout << "\nEl número de bytes devuelto por obtieneTamanho Función
es "
obtieneTamanho
14
<< obtieneTamanho( array ) << endl;
devuelve el número de bytes usado
15
para almacenar la dirección array.
16
return 0;
17 }
18 // función que devuelve el tamaño de ptr
Operador sizeof devuelve el
19 size_t obtieneTamanho( double *ptr )
número de bytes del puntero.
20 {
21
return sizeof( ptr );
22 } // fin de la función obtieneTamanho
Outline
El número de bytes del array es 160
El número de bytes devuelto por obtieneTamanho es 4
 2003 Prentice Hall, Inc.
All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// fig05_17.cpp: Demostración del operador sizeof.
#include <iostream>
using std::cout;
using std::endl;
int main()
{
char c;
short s;
Operador sizeof puede usarse
int i;
long l;
con nombre de variable.
float f;
Operador sizeof puede
double d;
usarse con nombre de tipo.
long double ld;
int array[ 20 ];
int *ptr = array;
cout << "sizeof c = " << sizeof c << "\tsizeof(char) = " << sizeof( char )
<< "\nsizeof s = " << sizeof s << "\tsizeof(short) = " << sizeof( short )
<< "\nsizeof i = " << sizeof i << "\tsizeof(int) = " << sizeof( int )
<< "\nsizeof l = " << sizeof l << "\tsizeof(long) = " << sizeof( long )
<< "\nsizeof f = " << sizeof f << "\tsizeof(float) = " << sizeof( float )
<< "\nsizeof d = " << sizeof d << "\tsizeof(double) = " << sizeof( double )
<< "\nsizeof ld = " << sizeof ld
<< "\tsizeof(long double) = " << sizeof( long double )
<< "\nsizeof array = " << sizeof array << "\nsizeof ptr = " << sizeof ptr
<< endl;
return 0;
}
Outline
 2003 Prentice Hall, Inc.
All rights reserved.
22
sizeof
sizeof
sizeof
sizeof
sizeof
sizeof
sizeof
sizeof
sizeof
c = 1
sizeof(char) = 1
s = 2
sizeof(short) = 2
i = 4
sizeof(int) = 4
l = 4
sizeof(long) = 4
f = 4
sizeof(float) = 4
d = 8
sizeof(double) = 8
ld = 12 sizeof(long double) = 12
array = 80
ptr = 4
23
Outline
 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,
localización
3000
3004
3008
3012
3016
vPtr=v; vPtr=&v[0];
• vPtr += 2; fija vPtr a 3008
v[0]
v[1]
v[2]
v[3]
v[4]
vPtr apunta a v[ 2 ]
• ++vPtr; --vPtr;
 2003 Prentice Hall, Inc. All rights reserved.
puntero a variable vPtr
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.
 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)
 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
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// fig05_20.cpp: Uso de notación de punteros e índices con arrays
#include <iostream>
using std::cout;
using std::endl;
int main()
{
int b[] = { 10, 20, 30, 40 };
int *bPtr = b;
// hago que bPtr apunte al array b
cout << "Array b impreso con:\n";
28
Outline
Usando notación de índices de array.
// imprimo array b usando notación de índices
cout << "\nNotación de índices de arrays\n";
for ( int i = 0; i < 4; i++ )
cout << "b[" << i << "] = " << b[ i ] << endl;
Usando nombre de array y notación
puntero/desplazamiento.
// imprimo array b usando nombre de array y notación de puntero y desplazamiento
cout << "\nNotación puntero/desplazamiento con puntero=nombre de array\n";
for ( int desplaz1 = 0; desplaz1 < 4; desplaz1++ )
cout << "*(b + " << desplaz1 << ") = " << *( b + desplaz1 ) << endl;
// imprimo array b usando bPtr y notación de índices de arrays
cout << "\nNotación puntero/subíndice\n";
for ( int j = 0; j < 4; j++ )
cout << "bPtr[" << j << "] = " << bPtr[ j ] << endl;
Usando notación de
puntero/subíndice.
Usando bPtr y notación
puntero/desplazamiento.
// imprimo array b usando bPtr y notación puntero/desplazamiento
cout << "\nNotación puntero/desplazamiento\n";
for ( int desplaz2 = 0; desplaz2 < 4; desplaz2++ )
cout << "*(bPtr + " << desplaz2 << ") = " << *( bPtr + desplaz2 ) << endl;
return 0;
}
 2003 Prentice Hall, Inc.
All rights reserved.
Array b impreso con:
29
Outline
Notación de índices de arrays
b[0] = 10
b[1] = 20
b[2] = 30
b[3] = 40
Notación
*(b + 0)
*(b + 1)
*(b + 2)
*(b + 3)
puntero/desplazamiento con puntero=nombre de array
= 10
= 20
= 30
= 40
Notación puntero/subíndice
bPtr[0] = 10
bPtr[1] = 20
bPtr[2] = 30
bPtr[3] = 40
Notación
*(bPtr +
*(bPtr +
*(bPtr +
*(bPtr +
puntero/desplazamiento
0) = 10
1) = 20
2) = 30
3) = 40
 2003 Prentice Hall, Inc.
All rights reserved.
1
// fig05_21.cpp: Copia de una cadena usando notación de arrays y notación de punteros
30
2
#include <iostream>
3
using std::cout;
4
using std::endl;
5
void copia1( char *, const char * ); // prototipo
6
void copia2( char *, const char * ); // prototipo
7
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;
Usa notación de índices de array para copiar
18
return 0;
la cadena c2 al array de caracteres c1.
19 }
20 // función que copia c2 a c1 usando notación de arrays
21 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 copia1
Usa notación de punteros para copiar
26 // función que copia c2 en c1 usando notación de punteros cadena c2 al array de caracteres c1.
27 void copia2( char *c1, const char *c2 )
28 {
Incrementa ambos punteros para
29
for ( ; ( *c1 = *c2 ) != '\0'; c1++, c2++ )
apuntar a los siguientes elementos en
30
;
// no hace nada en el cuerpo del bloque for
31 } // fin de la función copia2
sus arrays correspondientes.
Outline
cadena1 = Hola
cadena3 = Hasta luego
 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
caracteres
Cada elemento es
un puntero a char
char * palos[ 4 ] = {"Corazones", "Tréboles",
"Picas", "Diamantes" };
Array de 4 elementos
– Cada elemento de palos apunta a un char * (una cadena)
– El array no almacena cadenas, sólo punteros a cadenas
palos[0]
’C’
’o’
’r’
’a’
’z’
’o’
’n’
’e’
’s’
palos[1]
’T’
’r’
’é’
’b’
’o’
’l’
’e’
’s’
’\0’
palos[2]
’P’
’i’
’c’
’a’
’s’
’\0’
palos[3]
’D’
’i’
’a’
’m’
’a’
’n’
’t’
’e’
’s’
’\0’
’\0’
– El array palos tiene tamaño fijo, pero las cadenas pueden ser
de cualquier tamaño
 2003 Prentice Hall, Inc. All rights reserved.
5.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)
 2003 Prentice Hall, Inc. All rights reserved.
32
33
5.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
 2003 Prentice Hall, Inc. All rights reserved.
34
5.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')
 2003 Prentice Hall, Inc. All rights reserved.
35
5.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 );
 2003 Prentice Hall, Inc. All rights reserved.
36
5.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).
 2003 Prentice Hall, Inc. All rights reserved.
37
5.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.
 2003 Prentice Hall, Inc. All rights reserved.
38
5.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.
 2003 Prentice Hall, Inc. All rights reserved.
Descargar

Chapter 5 - Pointers and Strings