Haga una pregunta sobre printf y punteros en lenguaje C
En primer lugar, la base básica: 1. El orden de la pila C es de derecha a izquierda, es decir, la posición de los parámetros anteriores es relativamente baja 2. El lenguaje C estipula que todos; Los parámetros flotantes se convierten al doble durante el proceso de transmisión, probablemente sea una razón histórica. 3. Con respecto a los parámetros variables, el compilador no verifica y no tiene capacidad para verificar. Simplemente apila todos los parámetros y depende del programador hacerlo bien. Nuevamente, C cree que los programadores siempre tienen razón; 4. Por lo tanto, funciones como printf y scanf. No hay forma de saber exactamente qué argumentos se le pasaron, por lo que no hay forma de comprobar si la cadena de formato coincide con los argumentos. Entonces, aunque printf("%f\n ",p) es ilógico, incluso printf("%f% f% f \n ",p) es solo para personas que leen el código. 5. La estructura de pila de GCC es bastante especial. Las funciones GCC dejan suficiente espacio en el marco de la pila directamente en la entrada, por lo que la posición del puntero de la pila permanece sin cambios siempre que el punto de ejecución esté dentro de la función. No es así con el Turbo c. VC nunca lo ha visto. Nunca supe si GCC era una ventaja o una desventaja. 6. Depende de la máquina Shenma. El puntero en la máquina de 32 bits es de 4 bytes, el número de coma flotante doble es de 8 bytes (el doble del puntero), las partes importantes como el índice de símbolos están en el byte alto. el byte bajo es la parte de precisión.
Para decirlo sin rodeos, la característica de este código es que son todas llamadas printf, por lo que cuando se compila en GCC, los parámetros de la llamada posterior se superpondrán y cubrirán la posición de los parámetros de la llamada anterior. . Los parámetros esperados para cada printf son (excepto la cadena de formato anterior) dos dobles***16 bytes, la segunda llamada proporciona 16 bytes, las siguientes tres llamadas en realidad no proporcionan suficientes bytes, por lo que printf usa los 4 bytes superiores del número de punto flotante *p dejado por el anterior y sobrescribe los 4 bytes inferiores, afectando los puntos después del punto decimal. Entonces, la clave es que algunos rastros dejados por la llamada anterior no se han sobrescrito, y cuando a la siguiente llamada se le dan parámetros incorrectos, printf reutiliza estos rastros. LZ puede intentar insertar algunas otras llamadas a funciones con al menos tres parámetros dobles entre las declaraciones printf y podrá ver el efecto.