main аргументы функции и командной строки

Все программы C++ должны иметь функцию main . При попытке скомпилировать программу C++ без main функции компилятор вызывает ошибку. (Библиотеки и static библиотеки динамической main компоновки не имеют функции.) Функция main заключается в том, где начинается выполнение исходного кода, но перед вводом main программы в функцию все static члены класса без явных инициализаторов заданы равным нулю. В Microsoft C++глобальные static объекты также инициализированы перед записью main. Несколько ограничений main применяются к функции, которая не применяется к другим функциям C++. Функция main:

  • Невозможно перегружать (см . перегрузку функции).
  • Невозможно объявить как inline.
  • Невозможно объявить как static.
  • Не удается принять свой адрес.
  • Не удается вызвать из программы.

Сигнатура main функции

Функция main не имеет объявления, так как она встроена в язык. Если это сделать, синтаксис main объявления будет выглядеть следующим образом:

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

Если возвращаемое значение не указано, mainкомпилятор предоставляет возвращаемое значение нуля.

Стандартные аргументы командной строки

Аргументы для main обеспечения удобного анализа аргументов командной строки. Типы для параметров argc и argv определяются языком. Имена argc и argv являются традиционными, но вы можете назвать их независимо от того, что вы хотите.

Используются следующие определения аргументов.

argc
Целое число, содержащее количество аргументов, которые следуют в argv. Параметр argc всегда больше или равен 1.

argv
Массив завершающихся null строк, представляющих введенные пользователем программы аргументы командной строки. По соглашению — это команда, argv[0] с помощью которой вызывается программа. argv[1] — первый аргумент командной строки. Последний аргумент из командной строки имеет argv[argc - 1]argv[argc] значение NULL.

Сведения о том, как отключить обработку командной строки, см. в разделе "Настройка обработки командной строки C++".

Примечание.

По соглашению argv[0] — это имя файла программы. Однако в Windows можно создать процесс с помощью CreateProcess. Если вы используете оба первых и второго аргумента (lpApplicationName и lpCommandLine), argv[0] может не быть исполняемым именем. Можно использовать GetModuleFileName для получения исполняемого имени и полного пути.

Расширения, относящиеся к Корпорации Майкрософт

В следующих разделах описано поведение майкрософт.

wmain Функция и _tmain макрос

Если вы разрабатываете исходный код для использования широких charактеров Юникода, вы можете использовать точку входа, определенную wmain корпорацией Майкрософт, которая является широкойchar версией main. Ниже приведен синтаксис эффективного объявления для wmain:

int wmain();
int wmain(int argc, wchar_t *argv[]);

Вы также можете использовать определенный корпорацией Майкрософт _tmainмакрос препроцессора, определенный в tchar.h. _tmain разрешает, main если _UNICODE не определено. В противном случае функция _tmain разрешается в функцию wmain. Макросы _tmain и другие макросы, которые начинаются с _t , полезны для кода, который должен создавать отдельные версии для узких и широких charнаборов актировщиков. Дополнительные сведения см. в разделе "Использование универсальных текстовых сопоставлений".

void Возврат изmain

Как расширение Майкрософт, mainwmain функции могут быть объявлены как возвращаемые void (без возвращаемого значения). Это расширение также доступно в некоторых других компиляторах, но его использование не рекомендуется. Он доступен для симметрии, если main не возвращает значение.

При объявлении main или возврате voidкода в родительский процесс или wmain операционную систему невозможно вернуть exit с помощью инструкцииreturn. Чтобы вернуть exit код, когда main или wmain как voidобъявлен, необходимо использовать функцию exit .

envp Аргумент командной строки

wmain Сигнатуры main позволяют дополнительному расширению майкрософт для доступа к переменным среды. Это расширение также распространено в других компиляторах для систем Windows и UNIX. Имя envp традиционное, но можно присвоить параметру среды любое имя. Ниже приведены действующие объявления для списков аргументов, включающих параметр среды:

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

envp
Необязательный envp параметр — это массив строк, представляющий переменные, заданные в среде пользователя. Этот массив завершается записью NULL. Его можно объявить как массив указателей char на (char *envp[]) или как указатель на указатели char на (char **envp). Если программа использует wmain вместо mainэтого, используйте wchar_t вместо него тип charданных.

Блок среды, переданный main и wmain является "замороженным" копией текущей среды. Если вы позже измените среду, выполнив вызов putenv или_wputenv, текущая среда (возвращаемая getenv или _environ_wgetenv_wenviron переменная) изменится, но блок, на который указывает, envp не изменится. Дополнительные сведения о подавлении обработки среды см. в разделе "Настройка обработки командной строки C++". Аргумент envp совместим со стандартом C89, но не со стандартами C++.

Примеры аргументов main

В следующем примере показано, как использовать argcаргументы и envpargvаргументы mainдля:

// argument_definitions.cpp
// compile with: /EHsc
#include <iostream>
#include <string.h>

using namespace std;
int main( int argc, char *argv[], char *envp[] )
{
    bool numberLines = false;    // Default is no line numbers.

    // If /n is passed to the .exe, display numbered listing
    // of environment variables.
    if ( (argc == 2) && _stricmp( argv[1], "/n" ) == 0 )
         numberLines = true;

    // Walk through list of strings until a NULL is encountered.
    for ( int i = 0; envp[i] != NULL; ++i )
    {
        if ( numberLines )
            cout << i << ": "; // Prefix with numbers if /n specified
        cout << envp[i] << "\n";
    }
}

Анализ аргументов командной строки C++

Правила синтаксического анализа командной строки, используемые кодом Microsoft C/C++, относятся к корпорации Майкрософт. Код запуска среды выполнения использует эти правила при интерпретации аргументов, заданных в командной строке операционной системы:

  • Аргументы разделяются пробелами (пробел или табуляция).

  • Первый аргумент (argv[0]) обрабатывается особым образом. Он представляет имя программы. Это должен быть допустимый путь, поэтому разрешены части, заключенные в двойные кавычки ("). Эти знаки двойных кавычек не включаются в выходные данные argv[0]. Части, окруженные двойными кавычками, предотвращают интерпретацию пробела или действия табуляции charв качестве конца аргумента. Последующие правила в этом списке не применяются.

  • Строка, окруженная двойными кавычками, интерпретируется как один аргумент, который может содержать актировщики пробелов char. Строку в кавычках можно встроить в аргумент. Курсор (^) не распознается как экранный charактер или разделитель. Внутри заключенной в кавычки строки пара двойных кавычек интерпретируется как одна экранированная двойная кавычка. Если командная строка заканчивается до того, как будет найдена закрывающая двойная кавычка, все charвыступающие, прочитанные до сих пор, будут выводиться в качестве последнего аргумента.

  • Символ двойной кавычки после обратной косой черты (\") интерпретируется как литеральный символ двойной кавычки (").

  • Символы обратной косой черты считаются литералами, если сразу за ними не стоит двойная кавычка.

  • Если двойная кавычка стоит после четного числа символов обратной косой черты, в массив argv помещается по одному символу обратной косой черты (\) для каждой пары символов обратной косой черты (\\), а сама двойная кавычка (") интерпретируется как разделитель строк.

  • Если двойная кавычка стоит после нечетного числа символов обратной косой черты, в массив argv помещается по одному символу обратной косой черты (\) для каждой пары символов обратной косой черты (\\). Двойная кавычка интерпретируется как escape-последовательность повторнойmainобратной косой черты, что приводит к тому, что двойный кавычки литералов (") помещается в argv.

Пример синтаксического анализа аргументов командной строки

В следующем примере программы показана передача аргументов командной строки:

// command_line_arguments.cpp
// compile with: /EHsc
#include <iostream>

using namespace std;
int main( int argc,      // Number of strings in array argv
          char *argv[],   // Array of command-line argument strings
          char *envp[] )  // Array of environment variable strings
{
    int count;

    // Display each command-line argument.
    cout << "\nCommand-line arguments:\n";
    for( count = 0; count < argc; count++ )
         cout << "  argv[" << count << "]   "
                << argv[count] << "\n";
}

Результаты анализа командных строк

В следующей таблице показаны примеры входных данных и ожидаемые выходные данные, иллюстрирующие применение правил из приведенного выше списка.

Входные данные в командной строке argv[1] argv[2] argv[3]
"abc" d e abc d e
a\\b d"e f"g h a\\b de fg h
a\\\"b c d a\"b c d
a\\\\"b c" d e a\\b c d e
a"b"" c d ab" c d

Развертывание подстановочных знаков

Компилятор Майкрософт при необходимости позволяет использовать дикие картаchar актеры, вопросительный знак () и звездочку (?*), чтобы указать имя файла и аргументы пути в командной строке.

Аргументы командной строки обрабатываются внутренней подпрограммой в коде запуска среды выполнения, который по умолчанию не расширяет дикие элементы карта в отдельные строки в массиве argv строк. Вы можете включить расширение wild карта, включив setargv.obj файл (wsetargv.objфайл дляwmain) в /link параметры компилятора или LINK в командной строке.

Дополнительные сведения о параметрах компоновщика для запуска среды выполнения см. в статье Параметры ссылок.

Настройка обработки командной строки C++

Если программа не принимает аргументы командной строки, можно сохранить небольшой объем пространства, подавив подпрограмму обработки командной строки. Для этого включите файл noarg.obj (для main и wmain) в параметры компилятора /link или командную строку LINK.

Аналогичным образом, если вы никогда не использовали таблицу среды для доступа к аргументу envp, можно подавить внутреннюю подпрограмму обработки среды. Для этого включите файл noenv.obj (для main и wmain) в параметры компилятора /link или командную строку LINK.

Программа может вызывать семейство подпрограмм spawn или exec в библиотеке среды выполнения C. В этом случае не следует подавлять подпрограмму обработки среды, так как она используется для передачи данных о среде из родительского процесса в дочерний.

См. также

Основные понятия