To prawdopodobnie kwestia wygody. Daje programiście łatwy sposób na wczesne wycofanie się, jeśli nie ma wystarczającej liczby argumentów, bez zapętlania. W przeciwnym razie na pewno posiadają funkcje zwane int argc(char *argv[])robi dokładnie to :-))
cnicutar
5
Żeby było jasne "\0", nie jest taki sam jak wskaźnik NULL ( 0jest odpowiednikiem NULL w C ++)
Mats Petersson
31
Dlaczego potrzebujemy, aby argv [argc] miało wartość NULL, jeśli mamy argc?
Ambroz Bizjak
7
Jak inaczej określiłbyś liczbę argumentów w stałym czasie?
avakar
4
Nie myśl, że tagi linux / unix są tutaj odpowiednie, ponieważ takie zachowanie powinno być prawdziwe dla wszystkich kompilatorów we wszystkich systemach operacyjnych.
Darrel Hoffman
Odpowiedzi:
106
Tak, argv[argc]==NULLjest gwarantowane. Zobacz C11 5.1.2.2.1 Uruchomienie programu ( wyróżnienie moje)
Jeżeli są zadeklarowane, parametry funkcji głównej muszą spełniać następujące ograniczenia:
Wartość argc nie jest ujemna.
argv [argc] będzie pustym wskaźnikiem.
argcDlatego dostarczanie nie jest niezbędne, ale nadal jest przydatne. Między innymi pozwala na szybkie sprawdzenie, czy została podana poprawna liczba argumentów.
Edycja: pytanie zostało zmienione w celu uwzględnienia C ++. n3337 szkic 3.6.1 Mówi główna funkcja
2 ... argc będzie liczbą argumentów przekazanych do programu ze środowiska, w którym program jest uruchamiany. .... Wartość argc nie powinna być ujemna. Wartość argv [argc] powinna wynosić 0 .
I argcmoże być dość duże, ponieważ powłoka robi ekspansji (tak w jest rozszerzany przez powłokę przed z wykonywalny). W moim systemie mogę mieć kilkaset tysięcy. ls **execve/bin/lsargc
Basile Starynkevitch
To całkiem fajne, nigdy nie przyszło mi to do głowy, ponieważ zawsze uważałem za argcwystarczające, ale zdecydowanie mogę wymyślić sytuacje, w których ta gwarancja byłaby istotna, a nawet wymagana. +1
Thomas
6
@BasileStarynkevitch Czas zwykłego przechodzenia przez tablicę wartości wskaźnika jeden dodatkowy raz do NULL, aby uzyskać liczbę, jest niewielki w porównaniu z czasem spędzonym na generowaniu tablicy wskaźników, a nawet bardziej nieistotny w porównaniu z faktycznym użyciem wartości każdego argumentu w programie. A jeśli po prostu sprawdzisz, czy liczba argumentów jest większa niż N, to przechodzenie przez całą tablicę nie jest potrzebne. Mimo to w pełni się zgadzam, że to argcbyła i jest dobra rzecz.
hyde
43
Tak, argv[argc]na pewno będzie pustym wskaźnikiem. argcjest używany dla wygody.
Cytując oficjalne wyjaśnienie z C99 Rationale, zwróć uwagę na słowa redundant check :
Specyfikacja argci argvjako argumenty mainuznające rozległą wcześniejszą praktykę. argv[argc]musi być zerowym wskaźnikiem, aby zapewnić nadmiarowe sprawdzenie końca listy, również na podstawie powszechnej praktyki.
Dzieje się tak ze względów historycznych i zgodności ze starym kodem. Początkowo nie było gwarancji, że będzie istniał wskaźnik zerowy jako ostatni element tablicy argv. Ale argc istniał zawsze .
... Co jest w pewnym sensie wstydem. Gdybyśmy to zrobili int main(char *argv[], int argc, ...), niektóre programy mogłyby po prostu pominąć ten element, argcponieważ go nie potrzebują. Wręcz przeciwnie (potrzeba, argcale nie argv) prawdopodobnie nigdy nie jest przydatna w prawdziwym programie.
hyde
@hyde: patrz komentarz powyżej Basile Starynkevitch
zentrunix
6
„Potrzebujemy” tego, bo wymagają tego różne standardy.
Możemy całkowicie zignorować wartość, ale ponieważ jest to pierwszy parametr programu main, musimy go mieć na liście parametrów. W C ++ (i prawdopodobnie niestandardowych dialektach C) możesz po prostu pominąć nazwę parametru, na przykład ten fragment kodu C ++ (łatwy do konwersji na 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 Cfor(int i=0; argv[i];++i){
puts(argv[i]);}return0;}
W standardowym C, z typowymi ustawieniami ostrzeżeń, nieużywany parametr generuje ostrzeżenie, które można naprawić za pomocą instrukcji, na przykład (void)argc;która powoduje użycie nazwy bez generowania żadnego kodu.
argcdobrze jest mieć, ponieważ w przeciwnym razie wiele programów musiałoby przejść przez parametry, aby uzyskać liczbę. Ponadto w wielu językach programowania z tablicami o długości nie ma żadnego argcparametru, jest tylko tablica z elementami.
int argc(char *argv[])
robi dokładnie to :-))"\0"
, nie jest taki sam jak wskaźnik NULL (0
jest odpowiednikiem NULL w C ++)Odpowiedzi:
Tak,
argv[argc]==NULL
jest gwarantowane. Zobacz C11 5.1.2.2.1 Uruchomienie programu ( wyróżnienie moje)argc
Dlatego dostarczanie nie jest niezbędne, ale nadal jest przydatne. Między innymi pozwala na szybkie sprawdzenie, czy została podana poprawna liczba argumentów.Edycja: pytanie zostało zmienione w celu uwzględnienia C ++. n3337 szkic 3.6.1 Mówi główna funkcja
źródło
argc
może być dość duże, ponieważ powłoka robi ekspansji (tak w jest rozszerzany przez powłokę przed z wykonywalny). W moim systemie mogę mieć kilkaset tysięcy.ls *
*
execve
/bin/ls
argc
argc
wystarczające, ale zdecydowanie mogę wymyślić sytuacje, w których ta gwarancja byłaby istotna, a nawet wymagana. +1argc
była i jest dobra rzecz.Tak,
argv[argc]
na pewno będzie pustym wskaźnikiem.argc
jest używany dla wygody.Cytując oficjalne wyjaśnienie z C99 Rationale, zwróć uwagę na słowa redundant check :
źródło
Dzieje się tak ze względów historycznych i zgodności ze starym kodem. Początkowo nie było gwarancji, że będzie istniał wskaźnik zerowy jako ostatni element tablicy argv. Ale argc istniał zawsze .
źródło
int main(char *argv[], int argc, ...)
, niektóre programy mogłyby po prostu pominąć ten element,argc
ponieważ go nie potrzebują. Wręcz przeciwnie (potrzeba,argc
ale nieargv
) prawdopodobnie nigdy nie jest przydatna w prawdziwym programie.„Potrzebujemy” tego, bo wymagają tego różne standardy.
Możemy całkowicie zignorować wartość, ale ponieważ jest to pierwszy parametr programu
main
, musimy go mieć na liście parametrów. W C ++ (i prawdopodobnie niestandardowych dialektach C) możesz po prostu pominąć nazwę parametru, na przykład ten fragment kodu C ++ (łatwy do konwersji na C):W standardowym C, z typowymi ustawieniami ostrzeżeń, nieużywany parametr generuje ostrzeżenie, które można naprawić za pomocą instrukcji, na przykład
(void)argc;
która powoduje użycie nazwy bez generowania żadnego kodu.argc
dobrze jest mieć, ponieważ w przeciwnym razie wiele programów musiałoby przejść przez parametry, aby uzyskać liczbę. Ponadto w wielu językach programowania z tablicami o długości nie ma żadnegoargc
parametru, jest tylko tablica z elementami.źródło