PI-ITBA / 2024_02

Consultas 2C 2024
4 stars 0 forks source link

Consultas punteros #96

Open ssommerr opened 1 month ago

ssommerr commented 1 month ago

Hola! Cómo están? Queria hacer algunas consultas de punteros y ejercicios relacionados de la guía porque me están costando y no estaría pudiendo entenerlos al 100; Son varios ejercicios, aviso por las dudas , el primero es el siguiente: Sea char aMayusculas( char s) { char t; for ( t = s; t = toupper(*t); t++) ;

return s;

}

{ char p[] = "Hola mundo";

printf ("%s\n", aMayusculas(p) + 2);
printf ("%s\n", p);

} esto devuelve LA MUNDO y dsp HOLA MUNDO, lo que hace por detras para el primero es HOLA MUNDO y en la misma linea que lo printea añade 2 direcciones de memoria?

Y depsues con la misma inicializacion esta este ejercicio, que no entiendo porque compila y ejecuta pero no imrpime, no debería romperse en la ejecución o compilación?? { int v[] = {1,2,3,0};

printf( "%s\n", aMayusculas(v + 1)); printf( "%s\n", v); }

Yendo a otro ejercicio, no entiendo el error: char s[] = "esta es una cadena de caracteres"; for ( ; s != '\0'; s++) printf("%c ", s); por que no funciona?

Después etse ej esta inicializado así: static int x[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };

Suponiendo que x[0] esté almacenado en la dirección de memoria $10F0, en qué dirección de memoria se encuentra almacenado x[4] ? Esto seria sizeof(int)cantnums para ver el total? y sizeof(int)4 para responder la preg? Porque me mezcla los casos en los que el vector esta repleto de puntos(que suelen ser strs y cuando no lo son)

Y última consulta, con respecto a este ej: static char *color[6] = { “rojo”, “verde”, “azul”, “blanco”, “negro”, “amarillo” };

Graficar el almacenamiento en memoria del arreglo color (a partir de $2004). En este punto en un sector escribo la memoria que ocupa cada puntero y en otro sector represento por cada byte una letra, osea un char? ¿Qué se referencia con color?refiere a direc inicio rojo pero porq esta primero solo --- entonces es lo msimo que color??? ¿Qué se referencia con (color+2)? refiere a direc inicio azul ¿Qué se referencia con color? refiere a direc rojo ¿Qué se referencia con (color + 2)? direc azul osea de la a ¿En qué se diferencian color[5] y (color + 5)? color 5 ref a direc el segunda a a ¿Qué se referencia con *color? a r ¿Qué se referencia con color[0]? lo mismo ¿Qué se referencia con *color + 2? a j Está bien esto? No entiendo bien las diferencias entre (color+2) y (color+2) no apuntan a lo mismo?

Últ pregunta, en el ejercicio que hay que hacer strcatt con punteros, que se busca? Que los parámetros sean punteros? No estaría entendiendo bien si la idea es devolverlo en el mismo vector o que, dado que si los parámetros están escritos como punteros no se deben poder alterar; no sé si la idea sería que el espacio de memoria desués de la zona de destin apunte al str que oensabamos copiar o si simplemente creo otro vector, no entiendo bien.

Ante todo muchas gracias, perdón por el parrafote!

marcelogarberoglio commented 1 month ago

Vamos por partes

1) esto devuelve LA MUNDO y dsp HOLA MUNDO, lo que hace por detras para el primero es HOLA MUNDO y en la misma linea que lo printea añade 2 direcciones de memoria?

La función aMayuscula convierte un string a mayúsculas y además devuelve la dirección del string, por lo que se puede usar para imprimirlo o pasarlo a otra función. Esta línea printf ("%s\n", aMayusculas(p) + 2); Es equivalente a estas tres aMayusculas(p); char * aux = p +2; // apunta al tercer char printf ("%s\n", aux);

2) Y depsues con la misma inicializacion esta este ejercicio, que no entiendo porque compila y ejecuta pero no imrpime, no debería romperse en la ejecución o compilación?? { int v[] = {1,2,3,0};

printf( "%s\n", aMayusculas(v + 1)); printf( "%s\n", v); }

El primer 1 se guarda en memoria como 01 00 00 00 (por little endian) Al invocar con v+1, le está pasando la dirección del byte que sigue al 01, que es un cero. Lo interpreta como final del string y no hace nada

3) Yendo a otro ejercicio, no entiendo el error: char s[] = "esta es una cadena de caracteres"; for ( ; s != '\0'; s++) printf("%c ", s); por que no funciona?

no funciona porque s es un vector estático, entonces representa un rótulo, una constante, no compila por el s++ del for

4) Después etse ej esta inicializado así: static int x[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };

Suponiendo que x[0] esté almacenado en la dirección de memoria $10F0, en qué dirección de memoria se encuentra almacenado x[4] ? Esto seria sizeof(int)cantnums para ver el total? y sizeof(int)4 para responder la preg? Porque me mezcla los casos en los que el vector esta repleto de puntos(que suelen ser strs y cuando no lo son)

x[4] estará en la dirección de x + 4 *sizeof(int) bytes, correcto.

(sigue abajo)

marcelogarberoglio commented 1 month ago

5) ¿Qué se referencia con color?refiere a direc inicio rojo pero porq esta primero solo --- entonces es lo msimo que color??? no, no es lo mismo color que color[0] o color. Color es una constante que tiene la dirección del primer puntero, color[0] es el primer elemento de color, que es la dirección de la r. Te copio el gráfico que muestra python tutor, para que quede más claro image

color es la constante 0x601060 color[0] es 0x400564 (la dirección donde está la 'r'

entonces ¿Qué se referencia con color?refiere a direc inicio rojo pero porq esta primero solo --- entonces es lo msimo que color??? NO ¿Qué se referencia con (color+2)? refiere a direc inicio azul SI ¿Qué se referencia con color? refiere a direc rojo Dirección de la 'r' de "rojo" ¿Qué se referencia con (color + 2)? direc azul osea de la a es lo mismo que color[2], la dirección de la 'a' de "azul" ¿En qué se diferencian color[5] y (color + 5)? color 5 ref a direc el segunda a a Son lo mismo, es la dirección donde comienza "negro" ¿Qué se referencia con color? a r SI ¿Qué se referencia con *color[0]? lo mismo SI ¿Qué se referencia con color + 2? a j NO, es lo mismo que color[0][0] + 2, o sea ('r' + 2) * Está bien esto? No entiendo bien las diferencias entre (color+2) y (color+2) no apuntan a lo mismo? (color+2) es la dirección del tercer elemento (la dirección donde está la dirección del primer char, un char), (color +2) es lo mismo que color[2], es el tercer elemento (la dirección del primer char, un char)

6) Últ pregunta, en el ejercicio que hay que hacer strcatt con punteros, que se busca? Que los parámetros sean punteros? En realidad siempre que recibas un vector recibís un puntero (la dirección del primero). La idea es que lo hagas usando punteros para recorrer, como se hizo en clase la función belongs, que primero la hicimos con índices y después con un puntero que se iba desplazando desde el primero hasta el último. Para strcat tendrías que desplazarte por el primero string con el puntero hasta encontrar el cero final, y a partir de ahí copiar los caracteres del segundo string hasta encontrar el cero final. No hay que crear otro vector, hay que copiar el segundo string a partir del cero final del primer string.

ssommerr commented 1 month ago

Okey perfecto, muchisimas gracias! Hoy seguramente en la clase consulte de uno de estos puntos porque no se porque me sigue sin cerrar, pero todo el resto perfecto! Y una cosa más, el strcat al final si lo hice con punteros... porque no habia visto el mensaje, me quedo de la siguiente forma, estaría mal? Seguro había forma mas fácil de hacerlo, pero bueno; pero la forma de la que planteas hacerlo, como ubico el segundo str detrás del primero? Dado que el pimer str podría no tener espacio suf para almacenar al segundo, y si decido pegarlo en el 0 para adelante pero no es suyo ese espacio de memoria... segmentation fault:/ Así me quedo:

 char * strcatt(char *strdest , char *strorigen)
 {
    char *nuevostr=NULL;
    nuevostr=realloc(nuevostr, sizeof(char)*(strlen(strdest)+strlen(strorigen)+1));
    for (int i=0 ; i<(strlen(strdest)); i++)
    {

           *(nuevostr+i)=*(strdest+i);

    }
    for(int i=0; i<strlen(strorigen); i++)
    {
        *(nuevostr+i+strlen(strdest))=*(strorigen+i);
    }
    *(nuevostr+(strlen(strdest)+strlen(strorigen)))=0;

    return nuevostr;

 }

 int main()
  {
    char *strdest="Sol";
    char *stror="Sommer";
    strcatt(strdest,stror);
    strdest=strcatt(strdest,stror);
    for (int i=0 ; strdest[i]!=0 ; i++)
     printf("%c", strdest[i]);

 }

se que las cuentas de strlen podría haberlas almacenado en variables así es más eficiente() Muchisimas gracias!!!!

marcelogarberoglio commented 1 month ago

strcat no tiene que crear un nuevo string. Es responsabilidad del que invoca asegurarse que el string strdest tenga suficiente espacio al final para poder copiar el segundo string.

Este fragmento de código

 for (int i=0 ; i<(strlen(strdest)); i++)

Es el que pusimos como ejemplo en clase de lo que NO hay que hacer. Se recorre el string cada vez que se invoca a strlen. O sea que se lo recorre tantas veces como caracteres tenga.

image

marcelogarberoglio commented 1 month ago

No había visto el main. Así como está va a abortar porque "Sol" es constante,. dará error cuando pise el cero final (la versión correcta, no la que crea otro string). El main debería ser

 int main()
  {
    char strdest[50]="Sol ";
    char *stror="Sommer";
    strcat(strdest,stror);
    puts (strdest);
 }