Из стандарта (C11), особенно выделенный жирным шрифтом бит:
Если они объявлены, параметры основной функции должны подчиняться следующим ограничениям:
- Значение
argc
должно быть неотрицательным. argv[argc]
должно быть нулевым указателем. - Если значение
argc
больше нуля, элементы массива argv[0]
до argv[argc-1]
включительно должны содержать указатели на строки, которым перед запуском программы присваиваются значения, определяемые реализацией. Цель состоит в том, чтобы предоставить программе информацию, определенную перед запуском программы, из другого места в размещенной среде. Если среда хоста не способна предоставлять строки с буквами как в верхнем, так и в нижнем регистре, реализация должна гарантировать, что строки принимаются в нижнем регистре. - Если значение
argc
равно больше нуля, строка, на которую указывает argv[0]
, представляет имя программы; argv[0][0]
должно быть нулевым символом, если имя программы недоступно из среды хоста. Если значение argc
больше единицы, строки, на которые указывает argv[1]
- argv[argc-1]
, представляют параметры программы. - Параметры
argc
и argv
и строки, на которые указывает массив argv
, должны быть изменены программой и сохранят свои последние сохраненные значения между запуском программы и завершением программы.
Другими словами, argc
включает аргумент, представляющий имя программы - фактические параметры программы начинаются с argv[1]
. Это становится очевидным из вывода программы согласно следующей расшифровке, где первым аргументом является имя программы:
pax> cat testprog.c
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Argument count: %d\n", argc);
printf("Arguments:\n");
for (int i = 0; i < argc; i++)
printf(" %s\n", argv[i]);
return 0;
}
pax> gcc --std=c11 -o testprog testprog.c && ./testprog 1 2 3
Argument count: 4
Arguments:
./testprog
1
2
3
pax> ./testprog
Argument count: 1
Arguments:
./testprog