elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Arreglado, de nuevo, el registro del warzone (wargame) de EHN


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  otra manera de escribir *envp++
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 [2] Ir Abajo Respuesta Imprimir
Autor Tema: otra manera de escribir *envp++  (Leído 7,050 veces)
MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: otra manera de escribir *envp++
« Respuesta #10 en: 7 Febrero 2017, 21:02 pm »

Sí, así es.


En línea

7emiliosk8

Desconectado Desconectado

Mensajes: 73


Ver Perfil
Re: otra manera de escribir *envp++
« Respuesta #11 en: 7 Febrero 2017, 21:16 pm »

Sí, así es.

Gracias master al fin pude entenderlo :D sos un crack!!!!, la ultima cosita y ahora si termino con esto :B

Me podrias decir que pasa en el compilador si tengo esto

Código
  1. while(*envp)
  2. {
  3. str = *envp;
  4. envp++;
  5. }
  6.  

En esta parte envp++; si yo la pusiera como *envp++; tambien funciona.

si lo analiso en el primer caso envp++; asigna el valor sin problema, pero en el segundo *envp++; como es post incremento primero el compilador toma en cuenta *envp (no se si sean los terminos pero es como que el compilador accede a ese valor y no hace nada mas)  y luego como no hay nada que hacer con *envp , incrementa envp una vez, al final en el 2do caso como que el compilador hace un paso de mas ?

Saludos master.


En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: otra manera de escribir *envp++
« Respuesta #12 en: 7 Febrero 2017, 22:38 pm »

En estos casos, ten en cuenta el orden en que se llaman los operadores: http://es.cppreference.com/w/cpp/language/operator_precedence

Primero, el post-incremento(_++). Luego, la desreferencia(*).

Código
  1. *envp++;
Eso es lo mismo que:
Código
  1. *(envp++);
El post-incremento retorna el valor que tiene actualmente, e incrementa el valor de la variable (el retorno sigue siendo el antiguo).
Así pues, poner ese * ahí no hace nada funcional.

En caso de que te refieras a:
Código
  1. str = *envp++;
Pues hace lo esperado. str tendrá el valor de *envp, y luego se incrementará.
El compilador usualmente optimizará estas cosas, no es un tema realmente preocupante. Es más importante la legibilidad del código y, por supuesto, la funcionalidad.

Si programases C++, sí que podría tener algo más de repercusión al trabajar con objetos. Pero no mucha más.
En línea

7emiliosk8

Desconectado Desconectado

Mensajes: 73


Ver Perfil
Re: otra manera de escribir *envp++
« Respuesta #13 en: 7 Febrero 2017, 22:46 pm »

En estos casos, ten en cuenta el orden en que se llaman los operadores: http://es.cppreference.com/w/cpp/language/operator_precedence

Primero, el post-incremento(_++). Luego, la desreferencia(*).

Código
  1. *envp++;
Eso es lo mismo que:
Código
  1. *(envp++);
El post-incremento retorna el valor que tiene actualmente, e incrementa el valor de la variable (el retorno sigue siendo el antiguo).
Así pues, poner ese * ahí no hace nada funcional.

Hola, gracias por responder, pero no se supone que el post incremento es lo ultimo que se hace ? o sea si tengo *envp++ el compilador no le da preferencia al "*"?  es decir accede al * pero como no hay nada que hacer en el, luego pasa al post incremento... o estoy equivocado ?
En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: otra manera de escribir *envp++
« Respuesta #14 en: 8 Febrero 2017, 16:05 pm »

El _++ incrementa en el mismo momento. La diferencia con respecto al ++_ es que el post-incremento retorna el valor antiguo, y el pre-incremento retorna el nuevo valor.

Código
  1. int n = 0;
  2. int j = n++;
  3. // Cuando se ejecuta el n++, quedaría como:
  4. int j = 0;

Sin embargo:

Código
  1. int n = 0;
  2. int j = ++n;
  3. // Cuando se ejecuta el ++n, quedaría como:
  4. int j = 1;

Con estio quiero decir: ++_ y _++ son exactamente lo mismo, excepto en 2 aspectos: orden de ejecución y valor retornado.

Para comprobar que el _++ efectivamente incrementa el valor, puedes probar así:

Código
  1. #include <stdio.h>
  2.  
  3. int main(){
  4. int n = 1;
  5. printf("%i %i", n++, n);
  6. }
En línea

7emiliosk8

Desconectado Desconectado

Mensajes: 73


Ver Perfil
Re: otra manera de escribir *envp++
« Respuesta #15 en: 8 Febrero 2017, 19:36 pm »

El _++ incrementa en el mismo momento. La diferencia con respecto al ++_ es que el post-incremento retorna el valor antiguo, y el pre-incremento retorna el nuevo valor.

Amigo pero si tu dices que ambos tienen igual importancia, si yo tuviera dos de esos en una operacion, cual se resuelve primero ? es decir si tuviera

a = ++b * b++;

o en este ejemplo que esta mas elaborado, como se resolveria ? (segun el compilador b queda con un valor de 13.)

Citar
int main()
{
  int a=1;
  int b = a++ + ++a * a++;
  printf("%d",b);
}
« Última modificación: 8 Febrero 2017, 19:43 pm por 7emiliosk8 » En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: otra manera de escribir *envp++
« Respuesta #16 en: 8 Febrero 2017, 21:11 pm »

Este tema es un poco complicado ya la verdad. En primer lugar, el comportamiento en estos casos es indefinido. http://es.cppreference.com/w/cpp/language/eval_order#Comportamiento_indefinido

Aun siendo así, la explicación de que de 13 es esta:

Antes de nada, tengamos en cuenta un par de cosas: el post-incremento retorna un nuevo valor, nada extraño. Sin embargo, el pre-incremento retorna una referencia (lvalue) de la variable. Esto significa que ++n no se transforma en "5", por ejemplo. ++n se transforma en n. Con esto en cuenta, resolvámoslo:


Código
  1. int n = 1;
  2.  
  3. n++ + ++n * n++;
  4.  
  5. 1 + ++n * n++;
  6. // n = 2
  7.  
  8. 1 + n * n++; // Nótese que aquí cambiamos ++n por n, no por su valor, porque es una referencia, y el valor siempre estará vinculado a la variable
  9. // n = 3
  10.  
  11. 1 + n * 3;
  12. // n = 4
  13.  
  14. 1 + 4 * 3; // Llegados a este punto, sacamos el valor de esa n
  15.  
  16. 1 + 12
  17.  
  18. 13

Ese ++n puede generar un poco de confusión (a mi me la acaba de enerar, tuve que mirar el ensamblador que genera el compilador xD)

En fin, si bien esto es puramente "académico" y "curioso", pues eso, mejor evitar usar _++ y ++_ en donde puedan generar confusión (como poniendo varios en la misma sentencia).
En línea

7emiliosk8

Desconectado Desconectado

Mensajes: 73


Ver Perfil
Re: otra manera de escribir *envp++
« Respuesta #17 en: 8 Febrero 2017, 21:59 pm »

Vaya XD que enredo, al menos como que lo entendi un poco, amigo, eso del ensamblador que genera el codigo me podrias explicar como usarlo o como tengo que buscar para poder aprender a utilizarlo y yo mismo ir practicando con otras formas de codigo.
aunque ya me quedo claro que no es recomendable utilizar este tipo de notacion jajaj, saludos!
En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: otra manera de escribir *envp++
« Respuesta #18 en: 8 Febrero 2017, 23:14 pm »

Si compilas con GCC, puedes pasar el argumento "-S" para que genere el ensamblador en vez de el binario. Además, pasarle -O0 para que no optimice el código (y así tener el código tal como tú lo generaste).

Por ejemplo, este es el ASM desglosado del programa que probé (suerte que lo recuperé de la papelera de reciclaje) (está en C++, pero ninguna parte importante):

Código
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. int main(){
  6. int n = 1;
  7.  
  8. cout << n++ + ++n * n++;
  9. }
  10.  
  11. /*
  12.  
  13.  
  14. movl    $1, n ; int n = 1
  15.  
  16. movl    n, %edx
  17. leal    1(%edx), %eax
  18. movl    %eax, n ; n++ (first, edx = old value)
  19.  
  20. addl    $1, n ; ++n
  21.  
  22. movl    n, %eax
  23. leal    1(%eax), %ecx
  24. movl    %ecx, n ; n++ (second, eax = old value)
  25.  
  26. imull   n, %eax
  27.  
  28. addl    %edx, %eax
  29.  
  30.  
  31. */

No sé si controlas ensamblador, y no es parte del tema, pero como breve resumen:
movl mueve el valor del primer operando al segundo.
leal es más complejo. pero aquí, en resumen, cuando pone 1(operando), lo que hace es sumarle 1 al operando y guardarlo en el segundo operando
imull multiplica y almacena el resultado en el segundo operando
addl suma y almacena elr esultado en el segundo operando

Separé cada "operador" por un salto de línea. (Inicialmente no ponía "n", ponía -12(%esp), que es donde se almacenan las variables locales. Pero lo cambié a n por legibilidad.

Y bueno, el ensamblador no miente. Primero, mueve un 1 a n.
Luego, hace el primer post-incremento, y almacena el valor antiguo (que es el que se suma realmente), en edx (registro, que serían como las variables de ASM).
Siguiente, hace el pre-incremento. Sin ir más lejos, añade 1. Trivial.
Luego, segundo post-incremento. Incrementa n, y almacena el valor antiguo en eax.

Y ahora las otras operaciones. Empezamos ya con el problema que había. Hace imull n, %eax. eax es el valor del post-incremento, todo correcto, pero, como vimos, n lo ha incrementado ya las 3 veces, así que va a multiplicar por ese valor.

Y finalmente, la suma, trivial también.

God bless you, y recuerda que si tú juegas con el lenguaje, el lenguaje jugará contigo :X
En línea

7emiliosk8

Desconectado Desconectado

Mensajes: 73


Ver Perfil
Re: otra manera de escribir *envp++
« Respuesta #19 en: 9 Febrero 2017, 17:58 pm »

Sos un master, muchas gracias por la explicacion, bless.
En línea

Páginas: 1 [2] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
¿Hay alguna otra manera de saltar a una linea nueva?
PHP
extreme69 1 2,161 Último mensaje 5 Marzo 2012, 13:51 pm
por WHK
Escribir META DESCRIPCION de un sitio de manera cómoda, segun contenido.
Desarrollo Web
Skeletron 7 3,582 Último mensaje 7 Junio 2013, 00:19 am
por Skeletron
Otra manera de ver los navegadores de internet
Noticias
wolfbcn 1 2,749 Último mensaje 29 Agosto 2013, 09:28 am
por do-while
Hay manera de encender el portátil de otra manera? « 1 2 3 »
Windows
BlackMorror5 20 9,384 Último mensaje 13 Abril 2022, 22:33 pm
por stack
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines