Estoy tratando de devolver un valor flotante, pero cuando lo imprimo, obtengo 0.0.
float floating = 4.5; void* function(){ void* test = &floating; return test; } int _tmain(int argc, _TCHAR* argv[]){ printf("%f\n", test()); return 0; }¿Alguna idea de por qué no está imprimiendo 4.5? Lo siento si esta es una pregunta de novato, todavía soy bastante nuevo en esto.
Suponiendo que su function() en realidad se escribe como test() , %f espera un valor float . Está proporcionando un void * . Es un comportamiento incorrecto e indefinido .
Solución: void es un tipo incompleto, no puede desreferenciar un puntero void directamente. Debe convertir el puntero en el tipo requerido antes de eliminar la referencia. Por ejemplo,
printf("%f\n", *( (float *) test() ) );Tratar
printf("%f\n", *( (float*)function() ));Tratando de proporcionar un poco más de detalles sobre eso:
Primero, por cómo formuló su pregunta, debe comprender que los punteros no almacenan valores, almacenan direcciones de objetos. void no es ningún tipo, y un puntero void * puede almacenar la dirección de cualquier cosa (siempre que sean datos, pero no quiero complicar demasiado mi respuesta aquí).
Probablemente es de ahí de donde vienes en primer lugar. Pero luego cometiste dos errores:
El especificador de formato %f de printf() no espera un puntero, espera un valor. Hay una operación llamada desreferenciar un puntero que obtiene el valor al que apunta el puntero. En las expresiones c , tiene el operador de desreferenciación escrito como un asterisco ( * ) delante de su valor para hacer eso.
Entonces, ¿cómo se puede leer un valor sin saber el tipo? ¡No puedes! Es por eso que desreferenciar un puntero void * es ilegal. Significa, incluso si no olvidaste el asterisco y escribiste, por ejemplo printf("%f\n", *(test())); , el código sería incorrecto (y esta vez, su compilador detectaría el error).
Dicho esto, los punteros void * en c se entienden como un puntero genérico y, por lo tanto, se pueden convertir implícitamente hacia y desde cualquier otro tipo de puntero de datos (tenga en cuenta que esto es diferente en c++ ). Entonces, una forma de escribir su programa correctamente sería:
int _tmain(int argc, _TCHAR* argv[]){ float *f = test(); printf("%f\n", *f); return 0; } editar: del hecho de que void * es implícitamente convertible a/desde otros tipos de punteros de datos, su test() podría ser tan simple como eso:
void *test() { return &floating; } edit2: como eres nuevo en los punteros, agrega un consejo que no está directamente relacionado con tu pregunta: en una declaración de variable en c , el asterisco se vincula al identificador (nombre de variable), no al tipo. Esto significa que lees int * foo; no como "foo es una variable de tipo puntero a int " sino como "foo es una variable de puntero de tipo int ". Esto tiene una implicación seria al escribir, por ejemplo int * foo, bar; -- foo será un puntero, bar una variable normal. Por lo tanto, el consejo es: hazlo explícito escribiendo, por ejemplo void *test en lugar de void* test .