¿Cuál es la diferencia entre el puntero flotante y la dirección del puntero int?

Traté de ejecutar este código,

int *p; float q; q = 6.6; p = &q; 

Aunque será una advertencia, pero creo que &q y p son del mismo tamaño, por lo que p puede tener una dirección de q . Pero cuando imprimo &q obtengo resultados diferentes. Esta es mi salida

 *p = 6.600000 q = 0.000000, p = 0x40d33333, &q = 0x7fffe2fa3c8c 

¿Qué es lo que me falta? Y p y &q son iguales cuando ambos tipos de puntero y variable son iguales.

Mi codigo completo es

 #include void main() { int *p; float q; q = 6.6; p = &q; printf("*p = %f \nq = %f, p = %p, &q = %p \n",*p,q,p,&q); } 

Tienes que tomar las advertencias del comstackdor más en serio.

C no requiere que los comstackdores rechacen progtwigs no válidos, simplemente requiere “diagnósticos” para las violaciones de reglas. Un diagnóstico puede ser un mensaje de error fatal o una advertencia.

Desafortunadamente, es común que los comstackdores emitan advertencias para asignaciones de tipos de punteros incompatibles.

 void main() 

Esto está mal; debe ser int main(void) . Es posible que su comstackdor le permita salirse con la suya y que no cause ningún problema visible, pero no tiene sentido no escribirlo correctamente. (No es tan simple, pero eso es lo suficientemente cerca).

 int *p; float q; q = 6.6; 

Está bien.

 p = &q; 

p es de tipo int* ; &q es de tipo float* . Asignar uno a otro (sin una conversión) es una violación de restricción . La forma más sencilla de verlo es que es simplemente ilegal.

Si realmente quieres hacer esta tarea, puedes usar un molde:

 p = (int*)&q; /* legal, but ugly */ 

pero rara vez hay una buena razón para hacerlo. p es un puntero a int ; debe apuntar a un objeto int menos que tenga una buena razón para que apunte a otra cosa. En algunas circunstancias, la conversión en sí misma puede tener un comportamiento indefinido.

 printf("*p = %f \nq = %f, p = %p, &q = %p \n",*p,q,p,&q); 

El formato %f requiere un double argumento (un argumento float se promueve para double en este contexto, por lo que float estaría bien). Pero *p es de tipo int . Llamar a printf con un argumento del tipo incorrecto hace que el comportamiento de su progtwig no esté definido.

%p requiere un argumento de tipo void* , no solo de cualquier tipo de puntero. Si desea imprimir un valor de puntero, debe convertirlo en void* :

 printf("&q = %p\n", (void*)&q); 

Es probable que funcione sin el reparto, pero nuevamente, el comportamiento no está definido.

Si recibe alguna advertencia cuando comstack un progtwig, ni siquiera se moleste en ejecutarlo. Arregla las advertencias primero.

En cuanto a la pregunta en su título, los punteros de tipo int* y float* son de diferentes tipos. Un int* debería apuntar a un objeto int ; un float* debe apuntar a un objeto float . Es posible que su comstackdor le permita mezclarlos, pero el resultado de hacerlo es definido por la implementación o no definido. El lenguaje C, y particularmente muchos comstackdores de C, te permitirán salirte con muchas cosas que no tienen mucho sentido.

La razón por la que son tipos distintos es (intenta) prevenir, o al menos detectar, errores en su uso. Si declara un objeto de tipo int* , está diciendo que pretende que apunte a un objeto int (si no es un puntero nulo). Almacenar la dirección de un objeto float en su objeto int* es casi seguramente un error. La aplicación de la seguridad de tipos permite que se detecten tales errores lo antes posible (cuando su comstackdor imprime una advertencia en lugar de cuando su progtwig falla durante una demostración para un cliente importante).

Es probable (pero no está garantizado) que int* y float* sean del mismo tamaño y tengan la misma representación interna. Pero el significado de un objeto int* no es “una colección de 32 (o 64) bits que contienen una dirección virtual”, sino “algo que apunta a un objeto int “.

Obtienes un comportamiento indefinido, porque estás pasando los tipos incorrectos a printf . Cuando le dices que espere un flotador, en realidad espera un double , pero pasas un int .

Como resultado, imprime la información incorrecta, porque printf basa completamente en la cadena de formato para acceder a los argumentos que se le pasan.

Además de lo que dice teppic,

Considerar,

 int a = 5; int *p = &a; 

En este caso, le indicamos al comstackdor que p va a apuntar a un entero. Entonces se sabe que cuando hacemos algo como *p , en tiempo de ejecución, el no. de bytes igual al tamaño de un int sería leído.

Si asigna la dirección de un tipo de datos que ocupa x número de bytes a un puntero del cual se declara que contiene la dirección de los tipos de datos de menos bytes que x , lea el número incorrecto de bytes cuando use el operador de direccionamiento indirecto.