Em uma entrevista, fui confrontado com uma pergunta como esta:
Seu amigo deu a você um único arquivo de código-fonte que imprime os números de Fibonacci no console. Observe que o bloco main () está vazio e não possui nenhuma instrução dentro dele.
Explique como isso é possível (dica: instância global!)
Eu realmente quero saber sobre isso, como uma coisa dessas pode ser possível!
assert
ou#pragma message
etc. Isso redirecionará a saída para o console durante a compilação. O programa pode nunca ser compilado totalmente, mas esta é uma maneira divertida de mostrar seu pensamento "out-of-the-box" durante a entrevista. Isso satisfaz a questão citada, pois NÃO menciona nada sobre a geração de binários; em vez disso, ele apenas fala sobre um arquivo C que pode exibir "coisas" no console. ;-)Respostas:
É mais provável que seja implementado como (ou uma variante dele):
void print_fibs() { //implementation } int ignore = (print_fibs(), 0); int main() {}
Neste código, a variável global
ignore
deve ser inicializada antes de entrar namain()
função. Agora, para inicializar o global,print_fibs()
precisa ser executado onde você pode fazer qualquer coisa - neste caso, computar os números de fibonacci e imprimi-los! Algo semelhante que mostrei na seguinte pergunta (que eu havia feito há muito tempo):Observe que esse código não é seguro e deve ser evitado em geral. Por exemplo, o
std::cout
objeto não pode ser inicializado quandoprint_fibs()
é executado, se sim, o questd::cout
faria na função? No entanto, se em outras circunstâncias, ele não depender dessa ordem de inicialização, então é seguro chamar as funções de inicialização (que é uma prática comum em C e C ++).fonte
std::ios_base::Init
objeto. E<iostream>
tem a garantia de se comportar "como se" contivesse uma instância de umstd::ios_base_Init
objeto no escopo do namespace.(print_fibs(), 0)
sejaint
. Aqui está a demonstração online .bool
e a variávelbool fibsPrinted
. Isso provavelmente é um pouco mais limpo se a função só funcionar aqui. (Mas a diferença provavelmente não é suficiente para se preocupar.)std::cout
está em algum lugar da biblioteca. Mas, como já indiquei, o padrão exige que ele seja inicializado antes que o primeiro construtor de umstd::ios_base::Init
objeto termine, e exige que a inclusão<iostream>
se comporte como se umstd::ios_base::Init
objeto fosse definido no escopo do namespace. Se a unidade de tradução incluir<iostream>
antes da definição do objeto sendo inicializado,std::cout
é garantido que será construído.Espero que isto ajude
class cls { public: cls() { // Your code for fibonacci series } } objCls; int main() { }
Assim que uma variável global da classe é declarada, o construtor é chamado e aí você adiciona a lógica para imprimir a série de Fibonacci.
fonte
Sim, é possível. Você precisa declarar uma instância global de um objeto que calcula os números de Fibonacci no construtor do objeto.
fonte
Eu conheço alguns exemplos como esse que você conta. Uma maneira de obtê-lo é usando a metaprogramação de modelo. Usando-o, você pode mover algum processo de computação para a compilação.
Aqui você pode obter um exemplo com os números de Fibonacci
Se você usá-lo em um construtor de classe estática, poderá escrever os números sem precisar escrever nenhum código na função principal.
Espero que ajude você.
fonte
Coisas podem acontecer durante a inicialização de variáveis globais / estáticas. O código será acionado no início do aplicativo.
fonte
Todos os construtores [*] para objetos de escopo de arquivo são chamados antes de alcançar
main
, assim como todas as expressões de inicializador para variáveis de escopo de arquivo não-objeto.Editar: Além disso, todos os destruidores [*] para todos os objetos de escopo de arquivo são chamados na ordem reversa de construção após as
main
saídas. Você poderia, teoricamente, colocar seu programa fibonacci no destruidor de um objeto.[*] Observe que 'all' ignora o comportamento de carregar e descarregar dinamicamente as bibliotecas às quais seu programa não foi diretamente vinculado. Esses, tecnicamente, estão fora da linguagem C ++ base.
fonte
main
?main
está vazio, então essas DLLs / DSOs teriam que ser carregadas por destruidores, o que é muito perverso. Mas, sendo isso ciência da computação, acho que devemos ter cuidado com palavras como "todos".