programing

루프나 조건문을 사용하지 않고1 ~ 1000 으로 인쇄하는 C 코드는 어떻게 동작합니까?

newsource 2022. 9. 24. 12:38

루프나 조건문을 사용하지 않고1 ~ 1000 으로 인쇄하는 C 코드는 어떻게 동작합니까?

찾았다C루프나 조건 없이 1부터1000까지 출력하는 코드:근데 어떻게 동작하는지 모르겠어요누가 코드를 살펴보고 각 행에 대해 설명해 줄 수 있나요?

#include <stdio.h>
#include <stdlib.h>

void main(int j) {
  printf("%d\n", j);
  (&main + (&exit - &main)*(j/1000))(j+1);
}

절대 그런 식으로 코드를 작성하지 마세요.


위해서j<1000,j/1000는 제로입니다(표준 나눗셈).그래서:

(&main + (&exit - &main)*(j/1000))(j+1);

는 다음과 같습니다.

(&main + (&exit - &main)*0)(j+1);

즉, 다음과 같습니다.

(&main)(j+1);

호출 대상main와 함께j+1.

한다면j == 1000다음 행과 같은 행이 표시됩니다.

(&main + (&exit - &main)*1)(j+1);

결론부터 말하면

(&exit)(j+1);

어느 것이exit(j+1)프로그램을 종료합니다.


(&exit)(j+1)그리고.exit(j+1)C99 § 6.3.2.1/4에서 인용한 것과 본질적으로 동일합니다.

함수 지정자는 함수 유형을 가진 표현식입니다.연산자 크기 또는 단항 & 연산자의 피연산자일 때를 제외하고, "함수 반환형" 타입의 함수 지정자는 "함수 반환형 포인터" 타입의 식으로 변환된다.

exit는 함수 지정자입니다.단항이 없어도&address-of-operator는 기능에 대한 포인터로 취급됩니다.(the.&는 것을 명확하게 합니다.)

함수 호출은 「6.5.2.2/1」에 기재되어 있습니다.

호출된 함수를 나타내는 표현은 보이드를 반환하는 함수 또는 배열 유형 이외의 객체 유형을 반환하는 함수에 대한 유형 포인터를 가져야 한다.

그렇게exit(j+1)기능 타입이 기능 포인터 타입으로 자동 변환되기 때문에 동작합니다.(&exit)(j+1)는, 포인터 타입의 함수로의 명시적인 변환에서도 동작합니다.

즉, 위의 코드가 적합하지 않습니다(main2개의 인수를 받아들이거나 전혀 인수하지 않습니다).&exit - &main§ 6.5.6/9에 따라 정의되지 않은 것 같다.

2개의 포인터를 감산할 경우, 양쪽 모두 같은 배열 객체의 요소 또는 배열 객체의 마지막 요소 의 요소를 가리켜야 합니다.

추가(&main + ...)§ 6.5.6/7에는 다음과 같이 기재되어 있으므로 추가된 수량이 0일 경우 그 자체로 유효하며 사용할 수 있습니다.

이러한 연산자의 목적상 배열의 요소가 아닌 객체에 대한 포인터는 객체 유형을 요소 유형으로 하여 길이 1의 배열의 첫 번째 요소에 대한 포인터와 동일하게 동작합니다.

따라서 0을 더하는 것은&main(하지만 별로 쓸모가 없다)는 괜찮습니다.

재귀, 포인터 산술, 정수 나눗셈의 반올림 동작을 사용합니다.

j/1000은 모든 term에 합니다.j < 1000 1회j하면 1.1000으로

, 그럼 ㅇㅇ, ㅇㅇ가 a + (b - a) * n서, snowledge.n1 0 이 됩니다.an == 0 , , , , 입니다.bn == 1.★★★★★★ 。&main)main() 및 )의 개요&exit★★★★★★에a ★★★★★★★★★★★★★★★★★」b 「 」라는 .(&main + (&exit - &main) * (j/1000))&mainj밑돌고 있습니다.&exit이렇게 하면 인수에 입력됩니다.j+1.

전체 동작을 합니다. , 에는 재귀적인 동작이 있습니다.j밑돌고 있습니다.main합니다.j 1000이라고 합니다.exit대신 종료 코드 1001로 프로그램을 종료합니다(약간 더럽지만 작동).

https://stackoverflow.com/a/7937813/6607497은 모든 것을 설명하지만, 참을성이 없는 사람들을 위해 다음과 같은 동등한 (불필요한)를 제공합니다.

#include <stdio.h>
#include <stdlib.h>
    
void main(int j) {
    printf("%d\n", j);
    if (i/1000 == 0)
        main(j+1);
    else
        exit(j+1);
}

그래서 나는 그것이 어떻게 작동하는지는 명백하다고 생각한다.유일한 진짜 궁금한 사용하고 있는"goto 계산된"(사용되고 있는 유일한 진짜 트릭은 goto"계산된 goto"입니다.calcated).입니다.&main + (&exit - &main)*(j/1000)), 둘 중 어느 한쪽에 평가),중하나에 대해 평가합니다 다음.main반면 동안에하는j/1000또는 제로 0이다 또는exit그렇지 않으면(실제로 만약그렇지 않으면(실제로 그것이 맞다면)1).

아마도 또한 프로그램, 프로그램이 오용되고 있는 것에 주의해 주세요 또를 악용하다고 지적했다.argc~하듯이로j당신이 프로그램에 인수를 전달하기 때문에 다르게, 그리고 그것은 아마 사고 당신은 2000명이 넘는 매개 변수 추가를 계산할 것이다...따라서 프로그램에 인수를 전달하면 카운트가 달라지며 2000개이상의 파라미터를 추가하면크래시 됩니다.

언급URL : https://stackoverflow.com/questions/7937789/how-does-the-c-code-that-prints-from-1-to-1000-without-loops-or-conditional-stat