2012-02-21 3 views
2

질문 에서처럼 명령 줄 인수는 C (일반적으로 모든 언어)에서 어떻게 작동합니까? 생각할 수있는 논리적 인 설명은 운영 체제가 시작될 때 프로세스의 환경 적 가치를 설정하는 것입니다. 하지만 사실이라면 argp [i] 등으로 액세스 할 수 없어야합니다 (메인 arg를 ** argv 대신 char ** argp로 예상하도록 수정했습니다). 설명 해주십시오.명령 줄 인수는 어떻게 작동합니까?

+1

왜 argp [i]로 액세스 할 수 없어야한다고 생각하십니까? (함수 인자 이름은 보통 컴파일 된 프로그램에서는 의미가 없으므로 main argv에 대한 2. 인자의 이름은 단지 관습에 불과하다. 원하는 경우 'FOOBAR'라고 이름을 붙일 수있다) – nos

+1

'main'에 대한 인자는 다른 함수에 대한 인수와 같습니다. 이름은 실제로 중요하지 않습니다. 유형 프로토 타입이 일치하는 한 함수 프로토 타입과 실제 함수에서 서로 다른 인수 이름을 가질 수도 있습니다. 'main'에 대한 인수가 어디에서 오는 것인지는 중요하지 않습니다. 그냥 정수 나 포인터 배열 (또는 포인터를 포인터로 사용하는 것)으로 취급하십시오. –

답변

6

다른 답변보다 구현을 조금 더 설명하려고합니다.
정확하지는 않지만 관련 부분을 충분히 설명하기를 바랍니다.

쉘 아래에 ./myprog a b c을 입력하십시오.
쉘은 구문을 분석하여 세 개의 매개 변수를 사용하여 ./myproj을 실행하려고한다고 판단합니다.
./myprog이 실행될 새 프로세스를 만들기 위해 fork을 호출합니다.
여전히 쉘 프로그램을 실행하는 하위 프로세스는 5 개의 문자 포인터 배열을 준비합니다. 첫 번째는 문자열 ./prog을 가리키고, 다음 세 개는 문자열 a, bc에 연결되고 마지막 값은 NULL로 설정됩니다.
다음으로 execve 함수를 호출하여 매개 변수 배열이 생성 된 ./myprog을 실행합니다.
execve 셸 프로그램 대신 메모리에 ./myprog을로드합니다. 쉘 프로그램이 할당 한 모든 메모리를 해제하지만 매개 변수 배열을 유지합니다.
새 프로그램에서는 main이 호출되고 매개 변수 배열은 argv으로 전달됩니다.

+0

왜'execve'가'argc' 인수를 요구하지 않습니까? –

+0

실제로 배열에는 다섯 개의 항목이 포함됩니다. 첫 번째 (0 번째) 위치에 프로그램 이름을 잊지 마십시오. –

+0

그리고 새로운 프로세스를 실제로 생성하기 위해 fork-exec 이외의 다른 메커니즘을 사용할 수도 있습니다. 그것은 전적으로 OS에 달려 있으며,이 질문의 목적에 대해서는 별 상관이 없습니다. OS와 셸에서 명령을 실행하는 데 사용되는 메커니즘이 무엇이든 관계없이 명령 줄 인수를 전달해야합니다. 이것은 유닉스와 같은 일을하는 방식입니다. 여기서 인수는'fork'와'execve'에 의해 "복제"됩니다. –

1

당신이 주된 논증에주는 이름은 무엇 이었습니까? 중요한 것은 유형과 순서입니다. Env Vars를 사용하려면 다음 클로저를 사용하십시오.

int main(int argc, char ** myCommandLineArguments, char ** myEnvironmentVars) 

이게 궁금하신가요?

+0

답변 해 주셔서 감사합니다. 사실, 내 질문은 액세스하는 방법에 대한 것이 아니라 프로그램에서 누가 어떻게 사용할 수 있는지에 관한 것입니다. – Thunderman

2

C 프로그램에서 OS는 0으로 끝나는 문자열에 대한 포인터의 배열을 만듭니다. 카운트는 argc으로 전달되고 배열은 argv으로 전달됩니다. 너는 이미 이것을 알고있다. argcargv이라는 이름은 중요하지 않습니다. 모든 이름을 사용할 수 있습니다. 데이터 유형 및 순서는 중요합니다 ... 이어야하며 argcchar*[] 또는 char**이어야합니다. 다른 언어들도 비슷한 메커니즘을 가지고 있습니다. 예를 들어 C#은 하나의 string[] 인수를 .NET 배열로 전달하고 내부적으로 길이를 추적합니다. 자세한 내용은 여기를 참조하십시오. http://en.wikipedia.org/wiki/Main_function#C_and_C.2B.2B

환경 변수 이름은 프로그램의 변수 이름과 구분됩니다. argcargv은 환경 변수가 아니며 ... main()의 로컬 변수입니다.

환경 변수에 액세스하려면 getenv()을 사용하십시오.

업데이트 :이 내용이 프로그램에서 어떻게 제공되는지 알고 싶었습니다. 그것을하는 OS입니다. 하지만 OS가 그렇게하기 전에 실행 프로그램 (호출자)을 호출하는 프로그램이 명령 줄을 처리하게됩니다. 일반적으로 호출자는 쉘 (bash, csh, zsh, cmd.exe)이거나 그놈 또는 Windows 탐색기와 같은 데스크탑 환경입니다. 호출자는 execve (* nix에서) 또는 CreateProcess (Windows에서)을 통해 이러한 인수를 전달합니다.

관련 문제