[C con Clase] Ejercicio 12.1 curso web
Steven Davidson
srd4121 en njit.edu
Jue Sep 16 18:43:52 CEST 2010
Hola Alejandro,
On 9/16/2010 7:05 AM, Alejandro Alcalde wrote:
> Hola,Me gustaria dejarles el ejercicio para que me digan si es
> correcto, ya que hubo cosas que no entendi, como 'En main probar con
> distintos tipos de cadenas: arrays y punteros.'
>
Te hacemos saber que puedes enviar los ejercicios del curso de C++ a
nuestro apartado de correo-e: "ejercicioscpp en conclase.net" (sin las
comillas). Esto es para dejar a los demás seguidores del curso presentar
sus propios ejercicios sin tentaciones de copiarse de las
implementaciones de otras personas.
En cuanto al enunciado, queríamos que invocaras la función, que debes
crear, con cadenas de caracteres implementadas como arrays y como
punteros. Por ejemplo,
const char szCadena[] = "hola mundo";
int n = lenCad( szCadena );
lenCad( szCadena+5 );
lenCad( szCadena + n/2 );
lenCad( szCadena + n-3 );
const char *pszCadena = &szCadena[3];
lenCad( ++pszCadena );
const char *pszCadena2 = "adios mundo";
lenCad( ++pszCadena );
y cualquier otra invocación que se te ocurra.
Veamos el código fuente.
> #include<iostream>
>
> using std::cout;
> using std::cin;
> using std::endl;
>
> int lenCad(char*);
>
> int main(int argc, char **argv)
> {
> char cad[] = {"Hola que tal"}, *punteroC=cad;
La inicialización no es correcta. Al usar las comillas, ya estamos
usando un conjunto (array) de caracteres. Por lo tanto, no uses las
llaves para esta inicialización.
También deberías cambiar el tipo de la cadena para que sean caracteres
constantes. Esto es,
const char cad[] = "Hola que tal";
>
> int resul = lenCad(cad);
> cout<< "La cadena tiene" << resul<< " caracteres" << endl;
>
> return 0;
> }
> //-------------------------------
> int lenCad(char* cad){
Deberías indicar que el tipo apuntado sea 'const char', ya que no
tenemos intención alguna de modificar el contenido de la cadena.
> char* copia = cad;
>
> int i=0;
> while(*copia++) i++;
>
> return i;
> }
>
El enunciado del ejercicio dice que debes usar aritmética de punteros.
Además, aquí usas un número entero para contar los caracteres, pero
también usas una copia del puntero 'cad' que también avanzas. Ambas
variables no son necesarias simultáneamente; o bien usas 'i' o bien usas
'copia'.
Lo que pretendíamos es que se calcule la cantidad de caracteres usando
solamente punteros. Te dejo que implementes este tipo de solución.
>
> Una ultima duda, me lio mucho con los punteros, y nose porque, si en
> el while pongo copia++ en vez de *copia++ entra en un bucle
> infinito.
>
> Creo que es porque con *copia++ estoy diciendo 'avanza uno en el
> contenido de copia, osea copia[1]', y con copia++, no avanzaria
> sizeof(char)??, osea, el siguente elemento del array?? :), siento
> rebuscar tanto la pregunta, pero es que estuve un tiempo sin ensayar
> con punteros, y ahora me cuesta volver a entenderlos.
>
En el caso de '*copia++' estás aplicando dos operaciones. En orden,
hacemos el incremento póstumo (++) al puntero. Esto implica que
agregamos 1 al contenido del puntero el cual es una dirección de
memoria. Seguidamente, aplicamos el operador de acceso a memoria (*).
Con esta operación conseguimos el carácter apuntado. En tu programa,
este carácter se usa en una expresión condicional para el bucle 'while'.
Si el código ASCII no es cero, entonces seguimos iterando. Esto indica
que no hemos llegado al final de la cadena, ya que 0 representa el
carácter nulo. Podemos reescribir el código manteniendo la secuencia de
las operaciones para que lo veas con mayor claridad:
copia++;
while( *copia )
{
i++;
copia++;
}
En el otro caso de 'copia++', sólo estás incrementando el puntero, pero
no accedes al carácter. Por lo tanto, para llegar a la dirección de
memoria 0 (cero), seguramente tenemos que esperar muchísimas
iteraciones, hasta que se dé la vuelta al número entero que es la
dirección de memoria. Si se trata de una dirección de memoria de 32
bits, entonces tenemos que esperar hasta llegar al máximo entero (sin
signo) que sería 4294967295. Al sumar uno a este número, pasaríamos a 0,
porque 4294967296 requiere 33 bits, pero como tenemos 32, obtendremos 32
ceros al final con un uno en el 33º bit, el cual se desvanece, quedando
32 ceros. Claro está todo esto es posible si el sistema operativo nos
deja acceder a todas estas direcciones de memoria, que seguramente no
será el caso.
Como puedes ver, en este último caso, no accedes al carácter, sino que
simplemente incrementas el puntero. La secuencia de operaciones es la
siguiente:
copia++;
while( copia )
{
i++;
copia++;
}
Espero haber aclarado las dudas.
Steven
Más información sobre la lista de distribución Cconclase