인터뷰에서 나는 다음과 같은 질문에 직면했습니다.
친구가 콘솔에 피보나치 수를 인쇄하는 단일 소스 코드 파일을 제공했습니다. main () 블록은 비어 있고 내부에 명령문이 없습니다.
이것이 어떻게 가능한지 설명하십시오 (힌트 : 글로벌 인스턴스!)
나는 이것에 대해 정말로 알고 싶습니다. 어떻게 그런 일이 가능할 수 있는지!
인터뷰에서 나는 다음과 같은 질문에 직면했습니다.
친구가 콘솔에 피보나치 수를 인쇄하는 단일 소스 코드 파일을 제공했습니다. main () 블록은 비어 있고 내부에 명령문이 없습니다.
이것이 어떻게 가능한지 설명하십시오 (힌트 : 글로벌 인스턴스!)
나는 이것에 대해 정말로 알고 싶습니다. 어떻게 그런 일이 가능할 수 있는지!
assert또는 #pragma message등을 사용하여 출력을 기록하는 것입니다. 이렇게하면 컴파일 중에 출력이 콘솔로 리디렉션됩니다. 프로그램이 완전히 컴파일되지 않을 수도 있지만, 이것은 인터뷰 중에 "즉석"사고를 보여주는 재미있는 방법입니다. 이것은 생성되는 바이너리에 대해 아무것도 언급하지 않기 때문에 인용 된 질문을 만족시킵니다. 오히려 콘솔에 "stuff"를 표시 할 수있는 C 파일에 대해 이야기합니다. ;-)
답변:
다음과 같이 구현 될 가능성이 높습니다.
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>include는 std::ios_base::Init객체가 네임 스페이스 범위에서 정의 된 것처럼 동작 해야합니다 . 번역 단위 <iostream>가 초기화되는 객체의 정의 이전에 포함 std::cout되는 경우 구성이 보장됩니다.
네 가능합니다. 객체 생성자에서 피보나치 수를 계산하는 객체의 전역 인스턴스를 선언해야합니다.
파일 범위 객체에 대한 모든 [*] 생성자는 객체가 main아닌 파일 범위 변수에 대한 모든 이니셜 라이저 표현식과 마찬가지로 에 도달하기 전에 호출 됩니다.
편집 : 또한 모든 파일 범위 개체에 대한 all [*] 소멸자는 main종료 후 생성의 역순으로 호출 됩니다. 이론적으로 피보나치 프로그램을 객체의 소멸자에 넣을 수 있습니다.
[*] 'all'은 프로그램이 직접 연결되지 않은 라이브러리를 동적으로로드 및 언로드하는 동작을 무시합니다. 기술적으로는 기본 C ++ 언어 밖에 있습니다.
main?
main은 비어 있으므로 해당 DLL / DSO는 소멸자에 의해로드되어야하며 이는 비뚤어진 것입니다. 그러나 이것은 컴퓨터 과학이기 때문에 "all"과 같은 단어에주의해야한다고 생각합니다.