Red de conocimiento informático - Computadora portátil - Problemas de puntero en lenguaje C

Problemas de puntero en lenguaje C

La respuesta de mio_chat y la respuesta de skyivair son correctas, concisas y claras; White_Mouse es puramente confuso. La convención de llamada de funciones y el orden de evaluación de las expresiones son dos cosas completamente diferentes. Este problema no se especifica explícitamente en el estándar C/C. Se recomienda leer más libros originales extranjeros.

En primer lugar, déjame responder directamente a la pregunta del autor original.

La mejor manera de abordar este problema es utilizar una herramienta de desmontaje para ver cómo se ve el código generado por el compilador y cómo se implementa realmente. En el compilador gcc, utilizando el programa del propietario como código fuente, el exe generado se desmonta de la siguiente manera

Entre ellos, llamar a printf es una declaración de función de llamada, y la declaración anterior es para calcular los parámetros y El proceso de poner parámetros en la pila.

En primer lugar, es importante tener en cuenta que la convención de llamada de función predeterminada en C es cdecl, lo que significa que los parámetros van en la pila de derecha a izquierda. Específicamente, en su programa, esto significa que el compilador procesa *( p) primero y *(p ) segundo, que es exactamente lo opuesto a lo que usted entiende intuitivamente.

La primera lea y la segunda suma indican que p se sumó 1 a sí mismo primero; los siguientes 3 mov indican a[2], que es el número al que p apunta después de sumar 1 a sí mismo, ingresado. en la pila como parámetro. Inmediatamente después de los siguientes 3 movimientos, el puntero p no cambia, a [2] se coloca nuevamente en la pila y luego pasa por lea y agrega 1 al puntero p, después de lo cual se llama a printf para generar.

El resultado específico es similar a lo que dijo White_Mouse, porque primero se calcula que p suma 1 a sí mismo y luego lo genera dos veces consecutivas, por lo que se generan dos 1 y luego p se suma 1 a sí mismo nuevamente. , apuntando a a[3], que es 5.

Pero, pero, pero, pero, es importante tener en cuenta que el orden de apilamiento de los argumentos y el orden de evaluación de las expresiones son completamente diferentes, y el orden de evaluación de la expresión que estás viendo es en realidad no está en C dentro del alcance especificado; en otras palabras, nadie puede responder cuáles serán los resultados exactos de la ejecución hasta que vea los resultados de la ejecución.

La respuesta correcta es que los resultados de salida de estas líneas de código son inciertos y variarán dependiendo del compilador. Además, el lenguaje C/C no especifica el orden en el que se calculan expresiones como i i. El compilador puede tomar decisiones en función de sus propias circunstancias.

Este problema resulta ser una coincidencia entre el orden de cálculo implementado por el compilador y el orden de apilamiento acordado por el lenguaje C, lo que genera malentendidos comunes y la ilusión de que la realidad es consistente con él. también sobre qué lugar está confundido White_Mouse.

mio_chat ha citado al padre del lenguaje C (el inventor del lenguaje C), y ningún libro tiene más autoridad que el suyo. Permítanme citar una frase de Bjarne Stroustrup, el inventor de C, como prueba

¿Cuál es el valor de i? ?i ?

Básicamente, en C y C, si lees una variable dos veces en una expresión y la escribes al mismo tiempo, el resultado no estará definido. Otro ejemplo es: v[i] =? El compilador puede advertir sobre este tipo de ejemplos, que suelen ser errores sutiles (o errores potencialmente sutiles). Me decepciona que, décadas después, la mayoría de los compiladores todavía no emitan advertencias, dejando este trabajo a herramientas especializadas, independientes y menos utilizadas. html#evaluación-orden

Finalmente, rompa el libro que le enseñó a escribir este tipo de código. Por favor, desprecie al maestro que le enseñó a escribir este tipo de código. bajo cualquier circunstancia Esto es con lo que estás luchando. La pregunta no tiene sentido.

Para aprender el lenguaje C, se recomienda leer "El lenguaje de programación C" (¿El lenguaje de programación C? Brian W. Kernighan y Dennis M. Ritchie.