В стандарте C ISO / IEC 9899: 2018 (C18), §5.1.2.2.1 - «Запуск программы», написано:
2 - Если они объявлены, параметры основной функции должны подчиняться следующим ограничениям:
- argv [argc] должен быть нулевым указателем.
Мой вопрос:
- Почему _1 _ / _ 2_ должен быть / является указателем на
NULL
?
Это то, что для меня не имеет смысла. argv[]
- это массив указателей, указывающих на char
. argv
- указатель на массив указателей, указывающий на char
. Даже если при вызове не заданы флаги, указатель не должен превращаться в указатель на NULL
.
Разве char* argv[]
массив указателей на char
и char **argv
не является вложенным указателем на char
указатели? Как может вложенный указатель на char
(char**
) быть указателем на NULL
?
Я прочитал ответы на argv [argc] ==?, где в качестве ответов цитируется вышеупомянутая фраза из стандарта. а также спросил @ pmg´s answer, который дал мне ответ:
Независимо от используемых имен, согласно спецификации c char * argv [argc] объявляет массив с именем argv, способный содержать указатели argc на char. При передаче функции массив преобразуется в указатель на ее 1-й элемент (так что указатель на указатель на char [вот почему обычно можно увидеть main (int argc, char ** argv)]), теряющую информацию о размере (char * a [10] имеет 10 элементов; char ** a - указатель --- если указатель указывает на массив, невозможно узнать, сколько элементов имеет базовый массив).
но, к сожалению, несмотря на скромные усилия, я все еще не могу понять, почему указатель на указатель (вложенный указатель) на char
(char**
) превращается в указатель на NULL
.
Ответы на Является ли argv [argc] равным указателю NULL, также не отвечают почему это должен быть указатель на NULL
, только это является указателем на NULL
при цитировании приведенного выше утверждения стандарта.
Заранее спасибо.
argc
- это количество элементов в массивеargv
, наивысший индекс допустимой записи равенargc-1
. То есть последний аргумент -argv[argc-1]
. Технически это могло сделатьargv[argc]
неопределенным. Было выбрано значение NULL. Это дает дополнительные способы перебора списка аргументов (проверка на NULL вместо использованияargc
в качестве счетчика цикла). - person lurker   schedule 04.01.2020argv
:while (*argv) puts(*argv++);
. Возможно, такие петли были широко распространены во времена процесса стандартизации. - person Lxer Lx   schedule 04.01.2020argv[argc]
был реализован как NULL еще в 1970-х? :) - person lurker   schedule 04.01.2020argv[argc]
не является указателем наNULL
. Это нулевой указатель. Его значение -NULL
. Это не указывает наNULL
. - person Eric Postpischil   schedule 04.01.2020NULL
? - person qwerty_url   schedule 24.06.2021NULL
(по сути) значение, которое может иметь указатель. (Я говорю «фактически», потому что есть технические определения этого и «константы нулевого указателя», которые здесь не имеют отношения.) Указатель либо указывает на некоторый объект или функцию, либо является нулевым указателем (в этом случае он не указывает к любому объекту или функции). Если мы рассмотрим некоторыйchar *x
, имеющий определенное значение, то либоx
указывает наchar
, либо это нулевой указатель. Если это нулевой указатель, он ни на что не указывает; это не указывает наNULL
. - person Eric Postpischil   schedule 24.06.2021char **p
, это указатель на указатель, поэтому он мог бы указывать на какое-то место, где мы сохранили нулевой указатель. Даже в этом случае это будет указатель на нулевой указатель; это не будет указатель наNULL
(из-за технического определенияNULL
как макроса определенной формы). - person Eric Postpischil   schedule 24.06.2021