Почему аргумент main char ** argv является массивом строк в c - PullRequest
0 голосов
/ 19 мая 2018

В основной функции в c довольно часто можно увидеть что-то подобное:

int main(int argc, char **argv){}

У меня есть несколько вопросов по этому поводу.Кажется, что это массив строк, потому что я могу получить доступ к argv[0] и получить имя программы, или получить доступ к argv[1] и получить аргумент, который передается в программу.Почему char **argv массив строк?Я бы предположил, что это указатель на указатель на символ с именем argv.Если это не массив строк, то почему я могу получить к нему доступ как таковой?

1 Ответ

0 голосов
/ 19 мая 2018

В C, когда имя массива используется в большинстве выражений, значение, которое используется в выражении, является адресом первого элемента массива, а его тип является указателем на тип этого элемента.Это остается верным, когда массив передается функции.Таким образом, даже если синтаксис C позволяет вам объявить:

void foo(int x[]);

Тип, который имеет x, не является массивом int, а указателем на int.Итак, на самом деле это то же самое, что и:

void foo(int *x);

Для main это будет означать, что:

int main(int argc, char *argv[]);

на самом деле совпадает с:

int main(int argc, char **argv);

Разрешение имени массива "распадаться" на тип указателя было функцией, уникально созданной для функций нового типа C, чтобы поддерживать обратную совместимость с предшествующими типами C.От Развитие языка C

... Например, записи каталога ранних систем Unix могут быть описаны в C как

struct {
     int    inumber;
     char   name[14];
};

Я хотел, чтобы структура не просто характеризовала абстрактный объект, но и описывала набор битов, которые могут быть прочитаны из каталога.Где компилятор может скрыть указатель на имя, требуемое семантикой?Даже если бы структуры рассматривались более абстрактно, а пространство для указателей могло бы быть каким-то образом скрыто, как я мог бы решить техническую проблему правильной инициализации этих указателей при выделении сложного объекта, возможно, такого, который указывал структуры, содержащие массивы, содержащие структуры на произвольную глубину?

Решение представляет собой решающий скачок в эволюционной цепочке между типизированным BCPL и типизированным C. Он устраняет материализацию указателя в хранилище и вместо этого вызывает создание указателя, когда имя массива упоминается в выражении.,Правило, которое сохраняется в сегодняшнем C, состоит в том, что значения типа массива, когда они появляются в выражениях, преобразуются в указатели на первый из объектов, составляющих массив.

...