main funktions- och kommandoradsargument

Alla C++-program måste ha en main funktion. Om du försöker kompilera ett C++-program utan en main funktion genererar kompilatorn ett fel. (Dynamiska länkbibliotek och static bibliotek har main ingen funktion.) Funktionen main är där källkoden börjar köras, men innan ett program går in i main funktionen är alla static klassmedlemmar utan explicita initialiserare inställda på noll. I Microsoft C++initieras även globala static objekt före posten till main. Flera begränsningar gäller för funktionen main som inte gäller för andra C++-funktioner. Funktionen main :

  • Det går inte att överbelasta (se Funktionsöverlagring).
  • Det går inte att deklarera som inline.
  • Det går inte att deklarera som static.
  • Det går inte att ta adressen.
  • Det går inte att anropa från programmet.

Funktionssignaturen main

Funktionen main har ingen deklaration eftersom den är inbyggd i språket. Om det gjorde det skulle deklarationssyntaxen för main se ut så här:

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

Om inget returvärde anges i maintillhandahåller kompilatorn ett returvärde på noll.

Standardkommandoradsargument

Argumenten för main tillåter praktisk kommandoradsparsering av argument. Typerna för argc och argv definieras av språket. Namnen argc och argv är traditionella, men du kan namnge dem vad du vill.

Argumentdefinitionerna är följande:

argc
Ett heltal som innehåller antalet argument som följer i argv. Parametern argc är alltid större än eller lika med 1.

argv
En matris med null-avslutade strängar som representerar kommandoradsargument som angetts av programmets användare. Enligt konventionen argv[0] är kommandot som programmet anropas med. argv[1] är det första kommandoradsargumentet. Det sista argumentet från kommandoraden är argv[argc - 1], och argv[argc] är alltid NULL.

Information om hur du undertrycker kommandoradsbearbetning finns i Anpassa C++-kommandoradsbearbetning.

Anmärkning

Enligt konventionen argv[0] är filnamnet för programmet. I Windows är det dock möjligt att skapa en process med hjälp CreateProcessav . Om du använder både de första och andra argumenten (lpApplicationName och lpCommandLine), argv[0] kanske inte är det körbara namnet. Du kan använda GetModuleFileName för att hämta det körbara namnet och dess fullständigt kvalificerade sökväg.

Microsoft-specifika tillägg

I följande avsnitt beskrivs Microsoft-specifikt beteende.

Funktionen wmain och _tmain makrot

Om du utformar källkoden så att den använder Unicode-breda tecken kan du använda den Microsoft-specifika wmain startpunkten, som är wide-character-versionen av main. Här är den effektiva deklarationssyntaxen för wmain:

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

Du kan också använda det Microsoft-specifika _tmain, som är ett makro för processor som definierats i tchar.h. _tmain löses till main om inte _UNICODE har definierats. I så fall _tmain löser sig till wmain. Makrot _tmain och andra makron som börjar med _t är användbara för kod som måste skapa separata versioner för både smala och breda teckenuppsättningar. Mer information finns i Använda generiska textmappningar.

Återvänder void från main

Som ett Microsoft-tillägg main kan funktionerna och wmain deklareras som returnerade void (inget returvärde). Det här tillägget är också tillgängligt i vissa andra kompilatorer, men det rekommenderas inte. Den är tillgänglig för symmetri när main inte returnerar ett värde.

Om du deklarerar main eller returnerar voidkan du inte returnera en exit kod till den överordnade processen eller operativsystemet med hjälp av en return -wmaininstruktion. Om du vill returnera en exit kod när main eller wmain deklareras som voidmåste du använda exit funktionen.

Kommandoradsargumentet envp

Signaturerna main eller wmain tillåter ett valfritt Microsoft-specifikt tillägg för åtkomst till miljövariabler. Det här tillägget är också vanligt i andra kompilatorer för Windows- och UNIX-system. Namnet envp är traditionellt, men du kan namnge miljöparametern vad du vill. Här är de effektiva deklarationerna för argumentlistorna som innehåller miljöparametern:

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

envp
Den valfria envp parametern är en matris med strängar som representerar variablerna som anges i användarens miljö. Den här matrisen avslutas av en NULL-post. Den kan deklareras som en matris med pekare till char (char *envp[]) eller som en pekare till char (char **envp). Om programmet använder wmain i stället för mainanvänder du wchar_t datatypen i stället för char.

Miljöblocket som skickas till main och wmain är en "frusen" kopia av den aktuella miljön. Om du senare ändrar miljön genom att göra ett anrop till putenv eller _wputenvändras den aktuella miljön (som returneras av getenv eller _wgetenv och _environ variabeln eller _wenviron ) men blocket som pekas på av envp ändras inte. Mer information om hur du undertrycker miljöbearbetning finns i Anpassa C++-kommandoradsbearbetning. Argumentet envp är kompatibelt med C89-standarden, men inte med C++-standarder.

Exempelargument för main

I följande exempel visas hur du använder argumenten argc, argvoch envp till 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";
    }
}

Parsa C++-kommandoradsargument

De kommandoradsparsingregler som används av Microsoft C/C++-kod är Microsoft-specifika. Körningsstartkoden använder dessa regler vid tolkning av argument som anges på kommandoraden för operativsystemet:

  • Argument avgränsas med blanksteg, som antingen är ett blanksteg eller en flik.

  • Det första argumentet (argv[0]) behandlas särskilt. Den representerar programnamnet. Eftersom det måste vara ett giltigt sökvägsnamn tillåts delar omgivna av dubbla citattecken ("). De dubbla citattecknen ingår inte i argv[0] utdata. De delar som omges av dubbla citattecken förhindrar tolkning av ett blanksteg eller tabbtecken som slutet av argumentet. De senare reglerna i den här listan gäller inte.

  • En sträng omgiven av dubbla citattecken tolkas som ett enda argument, som kan innehålla blankstegstecken. En citerad sträng kan bäddas in i ett argument. Caret (^) känns inte igen som ett escape-tecken eller avgränsare. Inom en citerad sträng tolkas ett par dubbla citattecken som ett enda undantaget dubbel citattecken. Om kommandoraden slutar innan ett avslutande dubbel citattecken hittas är alla tecken som lästs hittills utdata som det sista argumentet.

  • Ett dubbelt citattecken som föregås av ett omvänt snedstreck (\") tolkas som ett literalt citattecken (").

  • Omvänt snedstreck tolkas bokstavligen, såvida de inte omedelbart föregår ett dubbelt citattecken.

  • Om ett jämnt antal omvänt snedstreck följs av ett dubbelt citattecken placeras ett omvänt snedstreck (\) i matrisen argv för varje par omvänt snedstreck (\\) och det dubbla citattecknet (") tolkas som en stränggränsare.

  • Om ett udda antal omvänt snedstreck följs av ett dubbelt citattecken placeras ett omvänt snedstreck (\) i matrisen argv för varje par omvänt snedstreck (\\). Det dubbla citattecknet tolkas som en escape-sekvens av det återstående omvänt snedstrecket, vilket gör att ett literalt dubbel citattecken (") placeras i argv.

Exempel på kommandoradsargumentparsing

Följande program visar hur kommandoradsargument skickas:

// 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";
}

Resultat av parsning av kommandorader

I följande tabell visas exempel på indata och förväntade utdata som visar reglerna i föregående lista.

Kommandoradsindata 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

Expansion av jokertecken

Med Microsoft-kompilatorn kan du också använda jokertecken , frågetecknet (?) och asterisken (*), för att ange filnamn och sökvägsargument på kommandoraden.

Kommandoradsargument hanteras av en intern rutin i körningsstartkoden, som som standard inte expanderar jokertecken till separata strängar i strängmatrisen argv . Du kan aktivera jokerteckenexpansion genom att inkludera setargv.obj filen (wsetargv.obj filen för wmain) i kompilatoralternativen /link eller LINK kommandoraden.

Mer information om alternativ för startlänkar för körning finns i Länkalternativ.

Anpassa C++-kommandoradsbearbetning

Om programmet inte använder kommandoradsargument kan du utelämna kommandoradsbearbetningsrutinen för att spara en liten mängd utrymme. Om du vill förhindra dess användning tar du med noarg.obj filen (för både main och wmain) i kompilatoralternativen /link eller LINK kommandoraden.

På samma sätt kan du utelämna den interna miljöbearbetningsrutinen om du aldrig kommer åt miljötabellen envp via argumentet. Om du vill förhindra dess användning tar du med noenv.obj filen (för både main och wmain) i kompilatoralternativen /link eller LINK kommandoraden.

Programmet kan göra anrop till spawn eller exec familj av rutiner i C-körningsbiblioteket. Om det gör det bör du inte ignorera miljöbearbetningsrutinen, eftersom den används för att skicka en miljö från den överordnade processen till den underordnade processen.

Se även

Grundläggande begrepp