нужно char *const argv[]
.Я предполагаю, что это указатель на массив указателей на символы.
Нет, это массив указателей char* const
.Это может помочь при чтении этих объявлений справа налево:
[]
Массив (неизвестного размера) ... argv
... named argv ... const
... of const ... *
... указатели ... char
... на символ.
На простом английском языке: массив (неизвестного размера) с именем argv, предназначенный только для чтения указателей на символ.
Так что можно передать двойной указатель char на этот символАргумент?
Обратите внимание на тонкую разницу между аргументами и параметрами.Параметр, относящийся к переменной в объявлении функции, аргумент, относящийся к вещам, которые вы передаете функции на стороне вызывающей стороны.Здесь это имеет значение.
Поскольку функция, принимающая параметр типа char *const argv[]
, будет автоматически корректировать этот параметр компилятором в указатель на первый элемент (иногда называемый «распадом массива»).Вот почему нам не нужно указывать размер массива - он будет «затухать» независимо от размера массива.
Первый элемент - это char*const
, а указатель на такой элемент имеет тип char*const*
, так что именно этого типа ожидает функция.Указатель на константный указатель на тип char - на втором уровне косвенности сам указатель не может быть изменен.
Как это бывает, char**
- это тип, который может быть неявно преобразован в char*const*
, посколькупоследний является «квалифицированной» версией первого - это тот же тип, но с «больше const
в нужных местах».Как правило, любой type*
может быть преобразован в type*const
.
Если бы параметр был const char* argv[]
, было бы невозможно использовать char**
, потому что в этом случае const
принадлежитк указанному типу, а не к указателю.
Как уже отмечалось, обратите внимание, что argv[-1] = NULL;
- это нонсенс, оно должно быть argv[argvcount] = NULL;