En una entrevista me enfrenté a una pregunta como esta:
Su amigo le ha dado un archivo de código fuente único que imprime los números de Fibonacci en la consola. Tenga en cuenta que el bloque main () está vacío y no tiene declaraciones en su interior.
Explique cómo es posible (pista: instancia global!)
Realmente quiero saber sobre esto, ¡cómo puede ser posible algo así!
assert
o#pragma message
etc. Esto redirigirá la salida a la consola durante la compilación. Es posible que el programa nunca se compile por completo, pero esta es sin duda una forma divertida de mostrar su pensamiento "original" durante la entrevista. Esto satisface la pregunta citada ya que NO menciona nada sobre la generación de binarios; más bien solo habla de un archivo C que puede mostrar "cosas" en la consola. ;-)Respuestas:
Lo más probable es que se implemente como (o una variante de él):
void print_fibs() { //implementation } int ignore = (print_fibs(), 0); int main() {}
En este código, la variable global
ignore
debe inicializarse antes de entrar enmain()
función. Ahora, para inicializar el global,print_fibs()
debe ejecutarse donde pueda hacer cualquier cosa; en este caso, calcular los números de Fibonacci e imprimirlos. Algo similar que he mostrado en la siguiente pregunta (que había preguntado hace mucho tiempo):Tenga en cuenta que dicho código no es seguro y es mejor evitarlo en general. Por ejemplo, es posible que el
std::cout
objeto no se inicialice cuandoprint_fibs()
se ejecuta, si es así, ¿qué haríastd::cout
en la función? Sin embargo, si en otras circunstancias, no depende de dicho orden de inicialización, entonces es seguro llamar a las funciones de inicialización (que es una práctica común en C y C ++).fuente
std::ios_base::Init
objeto. Y<iostream>
se garantiza que se comportará "como si" contuviera una instancia de unstd::ios_base_Init
objeto en el ámbito del espacio de nombres.(print_fibs(), 0)
seaint
. Aquí está la demostración en línea .bool
, y la variablebool fibsPrinted
. Probablemente sea un poco más limpio si la función solo sirve aquí. (Pero la diferencia probablemente no sea suficiente para preocuparse.)std::cout
está en algún lugar de la biblioteca. Pero como ya he señalado, el estándar requiere que se inicialice antes destd::ios_base::Init
que finalice el primer constructor de un objeto, y requiere que la inclusión se<iostream>
comporte como si unstd::ios_base::Init
objeto estuviera definido en el ámbito del espacio de nombres. Si la unidad de traducción incluye<iostream>
antes de la definición del objeto que se inicializa,std::cout
se garantiza que se construirá.Espero que esto ayude
class cls { public: cls() { // Your code for fibonacci series } } objCls; int main() { }
Entonces, tan pronto como se declara una variable global de la clase, se llama al constructor y allí agrega la lógica para imprimir la serie de Fibonacci.
fuente
Sí, es posible. Necesita declarar una instancia global de un objeto que calcula los números de Fibonacci en el constructor del objeto.
fuente
Conozco algunos ejemplos como ese que cuentas. Una forma de conseguirlo es utilizando la plantilla de metaprogramación. Utilizándolo, puede mover algún proceso de cálculo a la compilación.
Aquí puede obtener un ejemplo con los números de Fibonacci
Si lo usa en un constructor de clase estática y puede escribir los números sin necesidad de escribir ningún código en la función principal.
Espero que te ayude.
fuente
Pueden suceder cosas durante la inicialización de variables globales / estáticas. El código se activará al iniciar la aplicación.
fuente
Todos los constructores [*] para objetos de alcance de archivo se llaman antes de llegar
main
, al igual que todas las expresiones de inicializador para variables de alcance de archivo que no son de objeto.Editar: Además, todos los destructores [*] para todos los objetos de alcance de archivo se llaman en orden inverso de construcción después de las
main
salidas. Teóricamente, podría poner su programa de Fibonacci en el destructor de un objeto.[*] Tenga en cuenta que 'todos' ignora el comportamiento de cargar y descargar dinámicamente bibliotecas con las que su programa no estaba vinculado directamente. Sin embargo, aquellos técnicamente están fuera del lenguaje base C ++.
fuente
main
?main
está vacío, por lo que esos DLL / DSO tendrían que ser cargados por destructores, lo cual es muy perverso. Pero, siendo esto de la informática, supongo que deberíamos tener cuidado con palabras como "todos".