在一次采访中,我遇到了这样的问题:
您的朋友给了您一个源代码文件,该文件在控制台上打印了斐波那契数字。请注意,main()块为空,并且内部没有任何语句。
说明这是怎么可能的(提示:全局实例!)
我真的很想知道,这样的事情怎么可能!
在一次采访中,我遇到了这样的问题:
您的朋友给了您一个源代码文件,该文件在控制台上打印了斐波那契数字。请注意,main()块为空,并且内部没有任何语句。
说明这是怎么可能的(提示:全局实例!)
我真的很想知道,这样的事情怎么可能!
assert或#pragma message等记录输出。这将在编译过程中将输出重定向到控制台。该程序甚至可能永远不会完全编译,但这肯定是在面试中展示“开箱即用”思想的一种有趣方式。这满足了引用的问题,因为它没有提及有关生成二进制文件的任何内容;而是只讨论可以在控制台上显示“内容”的C文件。;-)
Answers:
它很可能实现为(或其变体):
void print_fibs()
{
//implementation
}
int ignore = (print_fibs(), 0);
int main() {}
在此代码中,全局变量ignore必须在进入main()函数之前进行初始化。现在,为了初始化全局变量,print_fibs()需要在可以执行任何操作的位置执行该命令-在这种情况下,请计算斐波纳契数并打印出来!我在以下问题(很久以前问过)中显示了类似的内容:
请注意,这样的代码并不安全,通常最好避免使用。例如,std::cout对象可能在print_fibs()执行时未初始化,如果是的话std::cout,该函数会做什么呢?但是,如果在其他情况下它不依赖于此类初始化顺序,则可以安全地调用初始化函数(这是C和C ++中的常见做法)。
std::ios_base::Init。并且<iostream>保证行为“好像”它包含std::ios_base_Init名称空间范围内的对象的实例。
bool和变量bool fibsPrinted。如果该功能仅在此处使用,那可能会稍微清洁一点。(但是差异可能不足以担心。)
std::cout在库中的某个位置。但是,正如我已经指出的那样,该标准要求在std::ios_base::Init对象的第一个构造函数完成之前对其进行初始化,并且它要求包括的<iostream>行为就像std::ios_base::Init对象是在名称空间范围内定义的。如果翻译单元<iostream>在要初始化的对象的定义之前包括在内,std::cout则可以保证构造该单元。
文件作用域对象的all [*]构造函数在到达之前就被调用main,非对象文件作用域变量的所有初始化表达式也是如此。
编辑:而且,所有文件作用域对象的all [*]析构函数在main退出后都会以相反的构造顺序被调用。从理论上讲,您可以将fibonacci程序放在对象的析构函数中。
[*]请注意,“全部”将忽略动态加载和卸载未与程序直接链接的库的行为。但是,从技术上讲,这些都不在C ++基本语言之外。
main?
main为空,因此那些DLL / DSO必须由析构函数加载,这是不明智的。但是,这是计算机科学,我想我们应该小心使用“ all”之类的词。