argv의 끝에 항상 null이 있는데 왜 argc가 필요합니까?


117

argv[argc]는 항상 있는 것 NULL같으므로,없이 인수 목록을 탐색 할 수 있다고 생각합니다 argc. 단일 while루프가이를 수행합니다.

NULL끝에 항상이있는 경우 argv왜 우리는이 필요 argc합니까?


17
아마도 편리함의 문제 일 것입니다. 프로그래머가 반복하지 않고 인수가 충분하지 않은 경우 조기에 쉽게 구제 할 수있는 방법을 제공합니다. 그렇지 않으면 우리는 확실히 이것을 int argc(char *argv[])하는 함수를 가질 것입니다 :-))
cnicutar

5
명확하게 "\0"말하면 NULL 포인터와 동일하지 않습니다 ( 0C ++에서 NULL과 동일)
Mats Petersson

31
argc가있는 경우 왜 argv [argc]가 NULL이되어야합니까?
Ambroz Bizjak 2013-08-31

7
일정한 시간에 인수의 수를 어떻게 결정합니까?
avakar

4
이 동작은 모든 운영 체제의 모든 컴파일러에 적용되어야하므로 여기서 linux / unix 태그가 적절하다고 생각하지 마십시오.
Darrel Hoffman

답변:


106

예, argv[argc]==NULL보장됩니다. C11 5.1.2.2.1 프로그램 시작 (내 강조)을 참조하십시오.

선언 된 경우 주 기능에 대한 매개 변수는 다음 제약 조건을 준수해야합니다.

argc의 값은 음수가 아니어야합니다. argv [argc]는 널 포인터 여야합니다.

argc따라서 제공하는 것이 중요하지는 않지만 여전히 유용합니다. 무엇보다도 올바른 수의 인수가 전달되었는지 빠르게 확인할 수 있습니다.

편집 : 질문이 C ++를 포함하도록 수정되었습니다. n3337 draft 3.6.1 주요 기능

2 ... argc는 프로그램이 실행되는 환경에서 프로그램으로 전달 된 인수의 수입니다. .... argc의 값은 음수가 아니어야합니다. argv [argc]의 값은 0이어야합니다 .


36
그리고 argc(그렇게 쉘이 확장을하고 있기 때문에, 매우 큰 수 ls **전에 쉘 확장 execve/bin/ls실행). 내 시스템에서는 argc수십만 개를 가질 수 있습니다 .
Basile Starynkevitch 2013-08-31

그것은 꽤 멋지다. 나는 항상 argc충분 하다고 생각했기 때문에 결코 발생하지 않았지만 ,이 보증이 적절하고 심지어 필요한 상황을 확실히 생각할 수있다. +1
Thomas

6
@BasileStarynkevitch NULL이 될 때까지 포인터 값 배열을 한 번 더 밟아서 카운트를 얻는 시간은 이미 포인터 배열을 생성하는 데 소요 된 시간에 비해 작으며 프로그램에서 각 인수 값을 실제로 사용하는 것에 비해 훨씬 더 관련이 없습니다. 그리고 인수 개수가 N보다 큰지 확인하면 전체 배열을 통과 할 필요가 없습니다. 그래도 전적으로 동의합니다. 그것은 argc좋은 일입니다.
hyde

43

예, argv[argc]null 포인터가 보장됩니다. argc편의를 위해 사용됩니다.

C99 Rationale의 공식 설명을 인용하면 중복 검사 라는 단어에 유의 하십시오 .

국제 표준의 근거 — 프로그래밍 언어 — C §5.1.2.2.1 프로그램 시작

광범위한 사전 관행 을 인식하기 위한 인수 argc및 의 사양 . 목록의 끝 부분에 대한 중복 검사를 제공하기 위해 null 포인터 여야합니다.argvmainargv[argc]


19

역사적인 이유와 이전 코드와의 호환성 때문입니다. 원래, argv 배열의 마지막 요소로 널 포인터가 존재한다는 보장이 없었습니다. 그러나 argc는 항상 존재했습니다.


... 어떤면에서 부끄러운 일입니다. 을 가졌다면 int main(char *argv[], int argc, ...)일부 프로그램은 argc필요하지 않기 때문에 생략 할 수 있습니다. 반대 (필요 argc하지만 아님 argv)는 실제 프로그램에서 결코 유용하지 않습니다.
하이드

@hyde : Basile Starynkevitch에 의해 위의 주석 참조
zentrunix

6

다양한 표준에서 요구하기 때문에 "필요"합니다.

값을 완전히 무시할 수는 있지만의 첫 번째 매개 변수 main이므로 매개 변수 목록에 있어야합니다. C ++ (및 비표준 C 언어)에서는 다음 C ++ 스 니펫 (C로 쉽게 변환)과 같이 매개 변수 이름을 생략 할 수 있습니다.

#include <stdio.h> // C-compatible include, guarantees puts in global namespace

// program will print contents of argv, one item per line, starting from argv[0]

int main(int /*argc*/, char *argv[]) { // uncomment argc for C

    //(void)argc; // uncomment statement for C

    for (int i=0; argv[i]; ++i) {
        puts(argv[i]);
    }

    return 0;
}

일반적인 경고 설정을 사용하는 표준 C에서 사용되지 않는 매개 변수는 경고를 생성하며, 이는 (void)argc;코드를 생성하지 않고 이름이 사용되도록 하는 명령문으로 수정할 수 있습니다 .

argc그렇지 않으면 많은 프로그램이 계수를 얻기 위해 매개 변수를 살펴 봐야하기 때문에 가지고 있으면 좋습니다. 또한 길이가있는 배열이있는 많은 프로그래밍 언어에는 argc매개 변수 가없고 항목이있는 배열 만 있습니다.


질문은 C와 C ++에 관한 것입니다. C에서는 매개 변수 이름이 필요합니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.