Наверное, дело в удобстве. Предоставляет программисту простой способ выручить раньше, если не хватает аргументов, без зацикливания. В противном случае у нас наверняка были бы функции, int argc(char *argv[])
вызывающие
5
Для ясности "\0"- это не то же самое, что указатель NULL ( 0эквивалент NULL в C ++)
Матс Петерссон
31
Зачем нам нужно, чтобы argv [argc] был NULL, если у нас есть argc?
Ambroz Bizjak
7
Как еще вы могли бы определить количество аргументов за постоянное время?
avakar
4
Не думайте, что теги linux / unix здесь подходят, так как это поведение должно быть справедливо для всех компиляторов во всех операционных системах.
Даррел Хоффман
Ответы:
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 .
И argcможет быть довольно большой, потому что оболочка делает расширение (так в расширяется за счет оболочки , прежде чем в исполняемый файл). В моей системе у меня может быть несколько сотен тысяч. ls **execve/bin/lsargc
Василий Старынкевич
Это довольно круто, это никогда не приходило мне в голову, поскольку я всегда считал argcдостаточным, но я определенно могу думать о ситуациях, когда эта гарантия была бы актуальной и даже необходимой. +1
Томас
6
@BasileStarynkevitch Время простого прохождения через массив значений указателей еще раз до NULL для получения счетчика является ничтожным по сравнению с временем, уже потраченным на создание массива указателей, и даже более несущественным по сравнению с фактическим использованием каждого значения аргумента в программе. А если просто проверить, больше ли количество аргументов N, то перебирать весь массив не нужно. Тем не менее, я полностью согласен, что это argcбыло и остается хорошо.
hyde
43
Да, argv[argc]гарантированно будет нулевой указатель. argcиспользуется для удобства.
Цитируя официальное объяснение из C99 Rationale, обратите внимание на слова избыточной проверки :
Описание argcи argvаргументы в пользу mainпризнания обширной предшествующей практики. argv[argc]должен быть нулевым указателем, чтобы обеспечить избыточную проверку конца списка, также на основе общепринятой практики.
Это по историческим причинам и совместимости со старым кодом. Первоначально не было гарантии, что в качестве последнего элемента массива argv будет существовать нулевой указатель. Но argc существовал всегда .
... Что в некотором роде обидно. Если бы это было так int main(char *argv[], int argc, ...), то некоторые программы могли бы просто опустить, argcпотому что они им не нужны. Противоположное (нужно, argcно не нужно argv), вероятно, никогда не пригодится в реальной программе.
hyde
@hyde: см. комментарий Базиля Старынкевича выше
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 Cfor(int i=0; argv[i];++i){
puts(argv[i]);}return0;}
В стандартном C с настройками общих предупреждений неиспользуемый параметр генерирует предупреждение, которое можно исправить с помощью оператора, например, (void)argc;который заставляет использовать имя без генерации кода.
argcприятно иметь, потому что в противном случае многим программам пришлось бы проходить через параметры, чтобы получить счет. Кроме того, во многих языках программирования с массивами, имеющими длину, нет никаких argcпараметров, есть только массив с элементами.
int argc(char *argv[])
"\0"
- это не то же самое, что указатель NULL (0
эквивалент NULL в C ++)Ответы:
Да,
argv[argc]==NULL
гарантировано. См. C11 5.1.2.2.1 Запуск программы (выделено мной)argc
Поэтому обеспечение не жизненно важно, но все же полезно. Помимо прочего, он позволяет быстро проверить, что было передано правильное количество аргументов.Изменить: вопрос был изменен, чтобы включить C ++. n3337 draft 3.6.1 Основная функция говорит
источник
argc
может быть довольно большой, потому что оболочка делает расширение (так в расширяется за счет оболочки , прежде чем в исполняемый файл). В моей системе у меня может быть несколько сотен тысяч.ls *
*
execve
/bin/ls
argc
argc
достаточным, но я определенно могу думать о ситуациях, когда эта гарантия была бы актуальной и даже необходимой. +1argc
было и остается хорошо.Да,
argv[argc]
гарантированно будет нулевой указатель.argc
используется для удобства.Цитируя официальное объяснение из C99 Rationale, обратите внимание на слова избыточной проверки :
источник
Это по историческим причинам и совместимости со старым кодом. Первоначально не было гарантии, что в качестве последнего элемента массива argv будет существовать нулевой указатель. Но argc существовал всегда .
источник
int main(char *argv[], int argc, ...)
, то некоторые программы могли бы просто опустить,argc
потому что они им не нужны. Противоположное (нужно,argc
но не нужноargv
), вероятно, никогда не пригодится в реальной программе.Он нам «нужен», потому что этого требуют разные стандарты.
Мы можем полностью игнорировать значение, но, поскольку это первый параметр
main
, мы должны иметь его в списке параметров. В C ++ (и, вероятно, в нестандартных диалектах C) вы можете просто опустить имя параметра, как этот фрагмент C ++ (легко преобразовать в C):В стандартном C с настройками общих предупреждений неиспользуемый параметр генерирует предупреждение, которое можно исправить с помощью оператора, например,
(void)argc;
который заставляет использовать имя без генерации кода.argc
приятно иметь, потому что в противном случае многим программам пришлось бы проходить через параметры, чтобы получить счет. Кроме того, во многих языках программирования с массивами, имеющими длину, нет никакихargc
параметров, есть только массив с элементами.источник