programing

main() 메서드는 C에서 어떻게 동작합니까?

prostudy 2022. 5. 30. 22:02
반응형

main() 메서드는 C에서 어떻게 동작합니까?

주요 방법을 기술하는 데 두 가지 다른 서명이 있다는 것을 알고 있습니다.

int main()
{
   //Code
}

또는 명령줄 인수를 처리하기 위해 다음과 같이 씁니다.

int main(int argc, char * argv[])
{
   //code
}

»C++이 과부하가 될 수 것은 , 그 방법에서는C이 두 합니까?main능하하??? ???

C언어의 특징 중 일부는 우연히 작동한 해킹으로 시작되었습니다.

main의 여러 시그니처와 가변장 인수 리스트가 이러한 기능의 1개입니다.

프로그래머들은 추가 인수를 함수에 전달할 수 있으며 주어진 컴파일러에 어떠한 나쁜 일도 일어나지 않는다는 것을 알게 되었습니다.

이것은, 콜의 표기법이 다음과 같은 경우입니다.

  1. 호출 함수는 인수를 삭제합니다.
  2. 맨 왼쪽 인수는 스택의 맨 위 또는 스택프레임의 맨 아래 쪽에 가깝기 때문에 스플리어스 인수는 주소 지정을 무효화하지 않습니다.

이러한 규칙에 준거하는 콜규칙의 1세트는 스택베이스 파라미터 패스입니다.이것에 의해, 발신자가 인수를 팝 해, 오른쪽에서 왼쪽으로 푸시 됩니다.

 ;; pseudo-assembly-language
 ;; main(argc, argv, envp); call

 push envp  ;; rightmost argument
 push argv  ;; 
 push argc  ;; leftmost argument ends up on top of stack

 call main

 pop        ;; caller cleans up   
 pop
 pop

의 호출 규약을 특별히 .main 그 의 종류도 main는 인수가 없는 함수일 수 있으며, 이 경우 스택에 푸시된 항목을 인식하지 않습니다.인수로 , 이 는 「」를 찾습니다.argc ★★★★★★★★★★★★★★★★★」argv2번으로 하다환경 포인터(공통 확장자)를 가진 플랫폼 고유의 3개의 인수 배리언트인 경우에도 동작합니다.이 인수는 스택의 상단에서3번째 요소로 검출됩니다.

따라서 고정 콜은 모든 경우에 사용할 수 있으며, 하나의 고정 스타트업 모듈을 프로그램에 연결할 수 있습니다.이 모듈은 다음과 같은 함수로 C로 표기할 수 있습니다.

/* I'm adding envp to show that even a popular platform-specific variant
   can be handled. */
extern int main(int argc, char **argv, char **envp);

void __start(void)
{
  /* This is the real startup function for the executable.
     It performs a bunch of library initialization. */

  /* ... */

  /* And then: */
  exit(main(argc_from_somewhere, argv_from_somewhere, envp_from_somewhere));
}

즉, 이 시작 모듈은 항상 3인수 메인만 호출합니다.이 인수를 main만 받는 int, char **호출 규약에 의해 정상적으로 동작하고 인수를 필요로 하지 않는 경우에도 정상적으로 동작합니다.

프로그램에서 이러한 작업을 수행할 경우 ISO C에 의해 정의되지 않은 동작으로 간주됩니다. 즉, 함수를 선언 및 호출하고 다른 방법으로 정의하는 것입니다.그러나 컴파일러의 스타트업 트릭은 포터블일 필요는 없습니다.포터블 프로그램 규칙에 따라 실행할 수 없습니다.

, 할 수 합니다.는 이 문제를 다루어야 합니다.main컴파일 중임main예를 들어 3개의 인수 호출과 호환되는 코드를 생성할 수 있습니다.

즉, 다음과 같이 기술합니다.

int main(void)
{
   /* ... */
}

그러나 컴파일러가 이를 볼 때 기본적으로 코드 변환을 수행하므로 컴파일러가 컴파일하는 함수는 다음과 같습니다.

int main(int __argc_ignore, char **__argv_ignore, char **__envp_ignore)
{
   /* ... */
}

__argc_ignore되지 않는인수에 .이러한 이름은 스코프에 추가되지 않으며 사용되지 않는 인수에 대한 경고도 없습니다.코드 변환에 의해 컴파일러는 3개의 인수를 정리해야 한다는 것을 알고 있는 올바른 링크를 가진 코드를 내보냅니다.

입니다.__start기능(또는 그 이름이 무엇이든)을 선택하거나 여러 가지 사전 선택 옵션에서 적어도 하나를 선택합니다.에는, 되고 있는 의 「어느 이냐」, 「어느 것이냐」에할 수 .main사용되고 있습니다.는 이하고 " " " 에 하는 올바른 의 스타트업 할 수 .main이치노으로 소수의 의 C만 .main이 접근방식은 실현 가능합니다.

C99를 취급해야 .main특히, 어느 정도, 만약 함수가 종료된다면, 해킹을 지원하기 위해return스테이트먼트, 동작은 마치return 0실행되었습니다.이것도 마찬가지로 코드 변환으로 처리할 수 있습니다.컴파일러는 함수가 호출된 것을 알아차립니다.main컴파일 중입니다.그런 다음 신체 끝에 도달할 수 있는지 여부를 확인합니다.이 경우 A가 삽입됩니다.return 0;

의 과부하가 발생하지 않는다.mainC++에서도 가능합니다.주 함수는 프로그램의 시작점이며 하나의 정의만 존재해야 합니다.

표준 C의 경우

호스트 환경(일반 환경)의 경우 C99 표준에는 다음과 같이 기술되어 있습니다.

5.1.2.1 프로그램 부팅

프로그램 시작 시 호출되는 함수의 이름이 지정됩니다.main구현에서는 이 함수에 대한 프로토타입이 없음을 선언합니다.다음과 같은 반환 유형으로 정의되어야 한다.int파라미터 없음:

int main(void) { /* ... */ }

또는 2개의 파라미터(여기에서는argc그리고.argv단, 임의의 이름을 사용할 수 있습니다.이는 선언된 함수의 로컬이기 때문입니다).

int main(int argc, char *argv[]) { /* ... */ }

또는 동등한 것,9) 또는 다른 구현 정의 방식.

9) 그래서...int다음과 같이 정의된 typeef 이름으로 대체할 수 있습니다.int또는 타입argv라고 쓸 수 있다char **argv기타 등등.

표준 C++의 경우:

3.6.1 주요 기능 [basic.start.main]

1 프로그램에는 main이라고 하는 글로벌 기능이 포함되어 있어야 합니다.이것은 프로그램의 지정된 시작입니다.[...]

2 실장에서는 주요 기능을 미리 정의해서는 안 된다.이 기능은 과부하가 걸리지 않아야 한다.타입 int의 반환 타입을 가져야 하지만, 그 이외의 타입은 구현 정의되어 있다.모든 구현은 다음과 같은 주요 정의를 모두 허용해야 한다.

int main() { /* ... */ }

그리고.

int main(int argc, char* argv[]) { /* ... */ }

C++ 표준은 명시적으로 "[주 함수]는 유형 int의 반환 유형을 가져야 하지만, 그렇지 않으면 유형이 구현 정의되어야 한다"고 명시하고 있으며, C 표준과 동일한 두 개의 서명을 요구한다.

호스트 환경(C 라이브러리도 지원하는 C 환경) - 운영 체제가 호출합니다.main.

비호스트 환경(임베디드 애플리케이션 전용)에서는, 다음과 같은 프리프로세서의 지시에 따라서, 프로그램의 엔트리 포인트(또는 종료)를 언제라도 변경할 수 있습니다.

#pragma startup [priority]
#pragma exit [priority]

여기서 priority는 옵션의 정수입니다.

pragma startup은 메인(priority별) 전에 기능을 실행하고 pragma exit은 메인 기능 후에 기능을 실행합니다.스타트업 디렉티브가 여러 개 있는 경우 priority에 따라 어떤 명령어를 먼저 실행할지 결정됩니다.

과부하가 필요 없습니다.네, 두 가지 버전이 있는데 한 가지 버전만 사용할 수 있습니다.

이것은 C 및 C++ 언어의 이상한 비대칭 및 특수한 규칙 중 하나입니다.

내 생각에 그것은 단지 역사적 이유 때문에 존재하며 그 배후에 진짜 심각한 논리는 없다.주의:main다른 이유로도 특별합니다(예를 들어,mainC++에서는 재귀가 불가능하고 주소를 받을 수 없으며 C99/C++에서는 마지막을 생략할 수 있습니다.return스테이트먼트)를 참조해 주세요.

또한 C++에서도 과부하가 아닙니다.프로그램은 첫 번째 양식 또는 두 번째 양식을 가지며 둘 다 가질 수 없습니다.

의 특이한 점main한 가지 이상의 방법으로 정의할 수 있다는 것이 아니라 두 가지 다른 방법 중 한 가지로만 정의할 수 있다는 것입니다.

main는 사용자 정의 함수입니다.실장에서는 이 함수의 프로토타입을 선언하지 않습니다.

에 대해서도 마찬가지다.foo또는bar단, 이러한 이름으로 함수를 원하는 방식으로 정의할 수 있습니다.

다른 점은 말이다.main는, 독자적인 코드에 의해서만이 아니라, 실장(런타임 환경)에 의해서 기동됩니다.구현은 일반적인 C 함수 호출 시멘틱스에 한정되지 않기 때문에 몇 가지 변형에 대처할 수 있습니다(그리고 반드시 처리해야 합니다). 그러나 무한히 많은 가능성을 처리하는 것은 아닙니다.int main(int argc, char *argv[])형식은 명령줄 인수를 허용합니다.int main(void)C 또는 C 또는int main()C++는 명령줄 인수를 처리할 필요가 없는 단순한 프로그램에 편리합니다.

컴파일러의 처리 방법에 대해서는, 실장에 의해서 다릅니다.대부분의 시스템에서는 2개의 형식이 효과적으로 호환되도록 하기 위한 호출규칙이 있으며 모든 인수가 에 전달됩니다.main파라미터 없이 정의된 것은 조용히 무시됩니다.그렇지 않은 경우 컴파일러나 링커에서 취급하는 것은 어렵지 않습니다.main특별히시스템에서 어떻게 작동하는지 궁금할 경우 일부 어셈블리 목록을 볼 수 있습니다.

그리고 C와 C++의 많은 것들과 마찬가지로, 세부 사항들은 대부분 언어 설계자들과 그 이전 세대들에 의해 내려진 역사와 자의적인 결정의 결과물이다.

C 와 C++ 는 모두, 다음의 실장 정의의 정의를 허가하고 있는 것에 주의해 주세요.main--하지만, 그것들을 사용할 좋은 이유가 거의 없습니다.또, OS가 없는 임베디드 시스템 등, 실장을 자유롭게 실시하기 위해서, 프로그램의 엔트리 포인트는 실장에 정의되어 있기 때문에, 반드시 「」라고 불릴 필요는 없습니다.main.

main는 링커에 의해 결정된 시작 주소의 이름일 뿐입니다.main는 기본 이름입니다.프로그램의 모든 함수 이름은 함수가 시작되는 시작 주소입니다.

함수 인수는 스택에서 푸시/팝되므로 함수에 대해 지정된 인수가 없는 경우 스택에서 푸시/팝된 인수는 없습니다.그것이 바로 논쟁이 있든 없든 메인이 작동할 수 있는 방법이다.

음, 같은 함수의 두 개의 다른 시그니처는 당신이 원할 때만 화면에 표시되므로, 만약 당신의 프로그램이 당신의 코드를 실제로 처리하기 전에 데이터를 필요로 한다면, 당신은 그것들을 -을 사용하여 전달할 수 있습니다.

    int main(int argc, char * argv[])
    {
       //code
    }

여기서 변수 argc는 전달된 데이터 수를 저장하고 argv는 콘솔에서 전달된 값을 가리키는 char 포인터의 배열입니다.그렇지 않으면 항상 함께 가는 것이 좋다.

    int main()
    {
       //Code
    }

그러나 어떤 경우든 하나의 프로그램 내에 하나의 main()만 존재할 수 있습니다.그것은 프로그램의 실행이 시작되는 유일한 포인트이기 때문에, 1개 이상의 main()은 존재할 수 없기 때문입니다.(그 가치가 있기를)

이전에도 비슷한 질문을 했습니다.(실제 함수 정의와 비교하여) 파라미터가 없는 함수가 컴파일되는 이유는 무엇입니까?

상위 답변 중 하나는 다음과 같습니다.

주식회사func()는 임의의 수의 인수를 전달할 수 있음을 의미합니다.인수를 원하지 않으면 다음과 같이 선언해야 합니다.func(void)

그래서 그런 것 같아요.main선언되어 있습니다('예외'라는 용어를 적용할 수 있는 경우).main) 실제로 다음과 같이 쓸 수 있습니다.

int main(int only_one_argument) {
    // code
}

컴파일되어 실행됩니다.

이것을 덮어쓸 필요는 없습니다.한 번에 한 개만 사용할 수 있기 때문입니다.네, 두 가지 다른 버전의 주요 기능이 있습니다.

언급URL : https://stackoverflow.com/questions/19419569/how-does-the-main-method-work-in-c

반응형