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
Как расширение Майкрософт, main
wmain
функции могут быть объявлены как возвращаемые 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
аргументы и envp
argv
аргументы 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. В этом случае не следует подавлять подпрограмму обработки среды, так как она используется для передачи данных о среде из родительского процесса в дочерний.
См. также
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по