1. Prácticas con punteros, vectores y cadenas. Por Salvador Fernández
1. Declara una cadena de caracteres de nombre palindromo y asígnale la constante literal
“AEREA” en la misma línea de declaración. Hazlo de dos maneras diferentes.
char palíndromo*+=”AEREA”;
char *palíndromo=”AEREA”;
2. Suponiendo que tienes dos cadenas de caracteres, cad1 y cad2 tales que
strlen(cad1)==10 y strlen(cad2)==5, indica cómo se declara una tercera cadena cad3 y
se le asigna memoria dinámica (en el heap o montón) , teniendo en cuenta que cad3
va a contener la concatenación de cad1 y cad2 sin que sobre ninguna posición de
memoria.
NOTA: strlen(x) devuelve el número de caracteres de la cadena sin contar el carácter
de fin de cadena (‘0’);
char *cad1=”abcdefghij”;
char *cad2=”opqrs”;
// En total necesito reservar espacio para 16 caracteres (10 de cad1, 5 cad 2 y el
// carácter de fin de cadena ‘0’
char *cad3=new char[strlen(cad1)+strlen(cad2)+1];
strcpy(cad3,””);
strcat(cad3,cad1);
strcat(cad3,cad2);
delete [] cad3;
3. Si tienes declarada e inicializada una cadena de caracteres cad, indica dos maneras de
leer o acceder al carácter de la primera posición.
*cad
cad[0]
4. Si en un programa que funciona adecuadamente aparece la sentencia delete s;
podemos adivinar que s es un puntero a
a. Un char, un int, o cualquier otra variable de tipo simple
b. Una cadena de elementos char, int, o de cualquier otro tipo simple
c. Es imposible que s sea un puntero.
5. ¿Cómo puedes averiguar lo que ocupa un puntero a un char en tu computadora y
usando tu compilador de C++?
sizeof (char *)
2. Prácticas con punteros, vectores y cadenas. Por Salvador Fernández
0 1
v
(int)&v[1] - (int)&v[0]= 0xff08 - 0xff04 = 4 bytes
char *v[2];
cout<<”Tamaño del puntero: “<<(int)&v[1]-(int)&v[0]<<” bytes”<<endl;
6. Si ptrLetra es un puntero a un char, ¿qué hace la instrucción *ptrLetra++=3;? ¿y la
instrucción (*ptrLetra)++=3;? ¿son iguales?
*ptrLetra=3;
*ptrLetra++=3
ptrLetra++;
Esta instrucción le asigna el código ASCII 3 al carácter al que apunta el puntero ptrLetra
y a continuación avanzan el puntero una posición a la derecha.
(*ptrLetra)++=3 no compila, es semánticamente incorrecta. En C++ no es posible una
instrucción del tipo x++=3, siendo x una variable.
CONCLUSIÓN: evitar en la medida de lo posible hacer combinaciones de operadores
cuyo orden de evaluación sea imprevisible.
7. Si quiero incrementar en una unidad el contenido de la variable a la que apunta un
puntero p, indica cuáles de las siguientes instrucciones serían válidas:
*p = *p + 1;
*p += 1;
++*p;
*p++; // Sí compila pero es semánticamente incorrecta(no incrementa el valor
de la variable a la que apunta).
char * char *
Dir 0xff04 Dir 0xff08
‘H’ ‘C’
‘0’ ‘U’
‘L’ ‘R’
‘A’ ‘S’
‘0’ ‘O’
‘0’
3. Prácticas con punteros, vectores y cadenas. Por Salvador Fernández
8. Utilizando la notación de vectores puedes acceder a la quinta posición (posición 4, ya
que los índices empiezan en 0) de un vector v mediante la expresión v[4]. ¿Cómo
harías referencia a dicha posición usando notación y aritmética de punteros?
*(v+4) // == v[4]
9. Dadas las siguiente declaraciones:
char *p;
char c;
Indica de dos maneras diferentes cómo expresar en C++ cada una de las siguientes
comprobaciones, donde carácter nulo se refiere a la marca de fin de cadena:
Si c es el carácter nulo…
if (!c)
if (c==’0’)
Si p apunta a un carácter nulo…
if (!*p)
if (*p==’0’) // no es lo mismo que if (*p==’0’)
Si p es un puntero nulo…
if (p==NULL)
if (!p)
4. Prácticas con punteros, vectores y cadenas. Por Salvador Fernández
10.
Indica los valores de las siguientes expresiones atendiendo a la disposición del vector
de enteros lista que se representa en la figura:
lista[2] == 64
*(lista+3) == 33
&lista[1] == 1502
Lista == 1500
lista+2 == 1504
lista+1<&lista[1] == 1502<1502 == false
11. Crea una función para intercambiar dos números enteros usando punteros equivalente
al paso mediante referencias de C++ que se indica. Para ello debes sustituir los
parámetros de entrada por punteros a enteros y cambiar el código para adaptarlo a la
lógica de los mismos. Asimismo, indica cómo sería la llamada a la función para dos
variables enteras x e y.
int x=3, y=4;
intercambiar(x,y);
void intercambiar(int &a, int &b)
{
int temp=a;
a=b;
b=temp;
}
5. Prácticas con punteros, vectores y cadenas. Por Salvador Fernández
intercambiar(&x, &y)
void intercambiar(int *ptr_a, int *ptr_b)
{
int temp=*ptr_a;
*ptr_a=*ptr_b;
*ptr_b=temp;
}
12. ¿Puedes averiguar qué hace el siguiente código? ¿Qué contendrán letra1 y letra2 tras
la ejecución del código?
char letra1 = 'A';
char letra2 = 'B';
char* puntero = &letra1; /* puntero se declara como un puntero de tipo char, por lo
tanto, almacenará la dirección de una variable de ese tipo. De hecho, en la propia
declaración se le asigna la dirección de memoria de la variable tipo char letra1. En
otras palabras puntero apunta a letra1 */
letra1 = 'C';
letra2 = *puntero; /* como puntero apuntaba a letra1 y en la instrucción anterior
hemos cambiado el valor de letra1 por ‘C’, entonces al dereferencia el puntero
mediante el operador * estamos asignándole ese valor ‘C’ a letra 2 */
Al final del programa letra1==’C’ y letra2==’C’
13. Teniendo el código.
char letra = 'A';
char* puntero = &letra;
Indicar cuáles de las siguientes asignaciones son incorrectas y podrían producir
errores:
letra = *puntero;
letra = &letra;
letra = &puntero;
puntero = *puntero;
puntero = *(&puntero);
puntero = *letra;
*puntero = letra;
&puntero = letra;
14. ¿Contenidos de letra1 y letra2 al final del código? ¿A quién apuntan los punteros al
final?
6. Prácticas con punteros, vectores y cadenas. Por Salvador Fernández
char letra1 = 'A';
char letra2 = 'B';
char* puntero1 = &letra1; //el puntero1 apunta a letra1
char* puntero2 = &letra2; //el puntero2 apunta a letra2
puntero1 = puntero2; /* puntero1 apunta ahora a la misma
variable a la que apunta puntero2, es decir, apunta a letra2 */
letra1 = 'C';
letra2 = 'D';
letra1 = *puntero1; /* puntero1 apunta a letra2; letra2 lo
hemos cambiado en la instrucción anterior al valor „D‟; por lo
tanto le estoy asignado dicho valor a letra1. */
Al final, el valor de letra1==’D’ y también el valor de letra2==’D’
15. Indica los valores que tendrán al final de la ejecución del siguiente código las variables
letra1, letra2 y letra3 en cada caso.
a.
char* cadena = "Hola";
char letra0 = *cadena; // Asignando „H‟ a letra0
char letra1 = *(cadena+1); // Asignando „o‟ a letra1
char letra2 = *(cadena+2); // Asignando „l‟ a letra2
char letra3 = *(cadena+3); // Asignando „a‟ a letra3
El nombre del vector, cadena, es un puntero al
primer elemento, por lo tanto almacenda la dirección de
memoria que ocupa dicho elemento. Sumando a la dirección del
primer carácter la posición a la que quiero acceder me
desplazo a dicha posición. Sólo queda derefenciar la nueva
dirección mediante el operador de indirección *
b.
char* cadena = "Hola";
char letra0 = *cadena; // Asignando „H‟ a letra0
char letra1 = *cadena+1; // Asignando „I‟ („H‟+1) a letra1
char letra2 = *cadena+2; // Asignando „J‟ („H‟+2) a letra2
char letra3 = *cadena+3; // Asignando „K‟ („H‟+3) a letra3
Al omitir los paréntesis el operador de indirección afecta
todo el rato al nombre del vector, por lo tanto, recupera
el carácter almacenado en la primera posición. Al sumar un
valor positivo a dicho carácter estamos modificando su
código ASCII, de tal modo que vamos asignando letras
sucesivas a la primera letra del vector.
7. Prácticas con punteros, vectores y cadenas. Por Salvador Fernández
16. Reescribe el siguiente programa para calcular la media aritmética de un vector de N
valores reales mediante notación y aritmética de punteros:
float media (float datos[], int N)
{
int i;
float suma = 0;
for (i=0; i<N; i++)
suma = suma + datos[i];
return suma/N;
}
float media (float datos[], int N)
{
int *ptri;
float suma=0;
for (ptri=datos; ptri<datos+N; ptri++)
suma = suma + *ptri;
return suma/N;
}
17. Representa mediante instrucciones lo que se representa en las figuras del estado de
memoria teniendo en cuenta las siguientes declaraciones de partida que se
corresponden con la primera instantánea. Todas los cambios de valor de las variables y
y z deben realizarse mediante punteros, siempre que se pueda. Si para un mismo
estado se te ocurren varias posibilidades indícalas como otras alternativas:
8. Prácticas con punteros, vectores y cadenas. Por Salvador Fernández
int y = 5;
int z = 3;
int *nptr;
int *mptr;
nptr=&y;
z=*nptr;
*nptr=*nptr+2;
a) mptr=nptr;
b) mptr=&y;
mptr=&z;
a) z=*nptr;
b) *mptr=*nptr;
c) *mptr+=2;
*nptr++;
a) ++*nptr;
b) *nptr=*nptr+1;
c) *nptr+=1;
9. Prácticas con punteros, vectores y cadenas. Por Salvador Fernández
18. Aquí tienes algunos códigos que presentan errores. Trata de identificarlos y explica el
motivo del error:
int a = 10;
int *ptri = NULL;
double x = 5.0;
double *ptrf = NULL;
...
ptri = &a; //ptri apunta a la variable entera a
ptrf = &x; //ptrf apunta a la variable double x
ptrf = ptri; // la asignación de punteros sólo es posible
// entre punteros que apunten al mismo tipo base.
char *ptr;
*ptr = „a‟; // ptr está apuntando a un sitio desconocido de
//la memoria porque no lo inicialicé. Sería un puntero
//“salvaje”, sin control
int n;
int *ptr = &n;
ptr = 9; /* estoy asignándole la dirección 9 de memoria al
puntero, algo que no puedo hacer porque no sé qué hay en
la dirección 9; ni siquiera sé si el sistema operativo me
da acceso a esa dirección. En realidad, lo que se supone
que se quería hacer era *ptr=9, es decir, asignarle 9 a n
a través del puntero ptr */
int *ptr = NULL;
*ptr = 9; /* el puntero está inicializado a NULL y no a
punta a ninguna variable concreta de la memoria. No se
puede dereferenciar un puntero nulo */
19. ¿Qué valor tendrá la variable a tras la ejecución de este programa?
main ()
{
int a = 5; // a vale 5
int *p; int **q;
p = &a; // p apunta a la variable a
q = &p; // q apunta a p
a = *p*2+**q;
// a = 5*2+5=15
}
El valor final de a es 15
20. Se pretende desarrollar tres fragmentos de código que sumen los elementos de un
vector de enteros v de diferentes maneras. Completa dicho código siguiendo las
instrucciones de los comentarios:
int i, suma;
10. Prácticas con punteros, vectores y cadenas. Por Salvador Fernández
int *ptr, *ptrfin;
/* Alternativa 1 */
suma = 0;
for (i=0 ; i<N ; i++)
suma = suma + v[i]; //Utilizando notación de vectores
/* Alternativa 2 */
suma = 0;
for (i=0 ; i<N ; i++)
suma = suma + *(v+i) ; //Utilizando notación de punteros
//pero sin echar mano de ptr ni
//ptrFin
/* Alternativa 3 */
/* Inicializa los punteros si es necesario */
suma = 0;
ptr=v;
ptrfin = ptr + N; //Completa la expression para que
//ptrFin apunte al último elemento
//del vector
for (ptr=v ; ptr<ptrfin ; ptr++) //Completa la condición
suma = suma + *ptr; //del bucle