Кажется, что argv[argc]
всегда NULL
, поэтому я думаю, что мы можем пересечь список аргументов без argc
. Один цикл while
сделает это.
Если в конце argv
всегда есть NULL
, зачем нам нужен argc
?
Кажется, что argv[argc]
всегда NULL
, поэтому я думаю, что мы можем пересечь список аргументов без argc
. Один цикл while
сделает это.
Если в конце argv
всегда есть NULL
, зачем нам нужен argc
?
Да, argv[argc]==NULL
гарантируется. См. C11 5.1.2.2.1 Запуск программы (мой акцент)
Если они объявлены, параметры главной функции должны подчиняться следующие ограничения:
Значение argc должно быть неотрицательным. argv [argc] должен быть нулевым указатель.
Предоставление argc
поэтому не является жизненно важным, но по-прежнему полезно. Помимо всего прочего, это позволяет быстро проверить правильность количества аргументов.
Изменить: вопрос был изменен, чтобы включить С++. n3337 черновик 3.6.1 Основная функция говорит
2... argc - количество аргументов, переданных программе из среда, в которой выполняется программа..... Значение argc должны быть неотрицательными. Значение argv [argc] должно быть 0.
Да, argv[argc]
гарантированно является нулевым указателем. argc
используется для удобства.
Цитируя официальное объяснение из Обоснования C99, обратите внимание на слова избыточная проверка:
Обоснование для международного стандарта - Языки программирования - C §5.1.2.2.1 Запуск программы
Спецификация
argc
иargv
в качестве аргументовmain
распознает обширную предыдущую практику.argv[argc]
требуется, чтобы он был нулевым указателем, чтобы обеспечить избыточную проверку для конца списка, также на основе обычной практики.
Это по историческим причинам и совместимость со старым кодом. Первоначально не было гарантии, что в качестве последнего элемента массива argv будет существовать нулевой указатель. Но argc всегда существовал.
Мы "нуждаемся" в нем, потому что это требуется по различным стандартам.
Мы можем полностью игнорировать это значение, но поскольку это первый параметр main
, мы должны иметь его в списке параметров. В С++ (и, возможно, нестандартных диалектах 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
, есть только массив с элементами.