main() 메서드는 C에서 어떻게 동작합니까?
주요 방법을 기술하는 데 두 가지 다른 서명이 있다는 것을 알고 있습니다.
int main()
{
//Code
}
또는 명령줄 인수를 처리하기 위해 다음과 같이 씁니다.
int main(int argc, char * argv[])
{
//code
}
»C++
이 과부하가 될 수 것은 , 그 방법에서는C
이 두 합니까?main
능하하??? ???
C언어의 특징 중 일부는 우연히 작동한 해킹으로 시작되었습니다.
main의 여러 시그니처와 가변장 인수 리스트가 이러한 기능의 1개입니다.
프로그래머들은 추가 인수를 함수에 전달할 수 있으며 주어진 컴파일러에 어떠한 나쁜 일도 일어나지 않는다는 것을 알게 되었습니다.
이것은, 콜의 표기법이 다음과 같은 경우입니다.
- 호출 함수는 인수를 삭제합니다.
- 맨 왼쪽 인수는 스택의 맨 위 또는 스택프레임의 맨 아래 쪽에 가깝기 때문에 스플리어스 인수는 주소 지정을 무효화하지 않습니다.
이러한 규칙에 준거하는 콜규칙의 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
★★★★★★★★★★★★★★★★★」argv
2번으로 하다환경 포인터(공통 확장자)를 가진 플랫폼 고유의 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;
의 과부하가 발생하지 않는다.main
C++에서도 가능합니다.주 함수는 프로그램의 시작점이며 하나의 정의만 존재해야 합니다.
표준 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
다른 이유로도 특별합니다(예를 들어,main
C++에서는 재귀가 불가능하고 주소를 받을 수 없으며 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
'programing' 카테고리의 다른 글
Axios를 사용하여 이미지를 서버에 업로드하려면 어떻게 해야 합니까? (0) | 2022.05.30 |
---|---|
Vue에서 선택한 옵션을 조건부로 설정하는 방법 (0) | 2022.05.30 |
매개 변수를 사용하여 기본 매개 변수 없는 생성자를 생성할 때 해당 생성자가 사라지는 이유는 무엇입니까? (0) | 2022.05.30 |
VueJS 컴포넌트에서 윈도 스크롤이벤트를 듣는 방법 (0) | 2022.05.30 |
C의 플래그를 삭제하려면 어떻게 해야 하나요? (0) | 2022.05.30 |