Borland C++ podporuje tři argumenty main(). První dva jsou tradiční argc a argv. To jsou jediné argumenty hlavní funkce(), definované standardem ANSI C. Umožňují předávání argumentů příkazového řádku programu. Argumenty příkazového řádku jsou informace následující za názvem programu příkazový řádek operační systém. Například, když je program zkompilován pomocí inline kompilátoru Borland, bcc se obvykle zadává název_programu

Kde název_programu je program, který se má zkompilovat. Název programu je předán kompilátoru jako argument.

Parametr argc obsahuje počet argumentů příkazového řádku a je to celé číslo. Vždy je alespoň 1, protože název programu je kvalifikován jako první argument. Parametr argv je ukazatel na pole ukazatelů znaků. Každý prvek tohoto pole ukazuje na argument příkazového řádku. Všechny argumenty příkazového řádku jsou řetězce. Všechna čísla jsou programem převedena do interního formátu. Následující program vypíše „Ahoj“ následované uživatelským jménem, ​​pokud je napsáno hned za názvem programu:

#zahrnout

{
if(argc!=2)
{
printf("Zapomněli jste napsat své jméno\n");
návrat 1;
}
printf("Ahoj %s", argv);
návrat 0;
}

Pokud zavolá tento program jméno a uživatelské jméno je Sergey, pak pro spuštění programu zadejte:
jméno Sergej.
V důsledku programu se objeví:
Ahoj Sergeji.

Argumenty příkazového řádku musí být odděleny mezerami nebo tabulátory. Čárky, středníky a podobné znaky se nepovažují za oddělovače. Například:

Skládá se ze tří řádků, zatímco

Herb, Rick, Fred

Toto je jeden řádek – čárky nejsou oddělovače.

Pokud chcete předat řetězec obsahující mezery nebo tabulátory jako jeden argument, uzavřete jej dvojité uvozovky. Například toto je jeden argument:

"tohle je zkouška"

Je důležité správně deklarovat argv. Nejtypičtější metodou je:

Prázdné závorky označují, že pole nemá pevnou délku. K jednotlivým prvkům můžete přistupovat pomocí indexování argv. Například argv ukazuje na první řádek, který vždy obsahuje název programu. argv ukazuje na další řádek a tak dále.

Níže je malý příklad použití argumentů příkazového řádku. Odpočítává od hodnoty zadané na příkazovém řádku a při dosažení nuly vydá signál. Všimněte si, že první argument obsahuje číslo převedené na celé číslo pomocí standardní funkce atoi(). Pokud je jako druhý argument přítomen řetězec "display", pak se na obrazovce zobrazí samotné počítadlo.

/* program na počítání */

#zahrnout
#zahrnout
#zahrnout
int main(int argc, char *argv)
{
int disp, počet;
if(argc<2)
{
printf("Musíte zadat délku počítání\n");
printf("na příkazovém řádku. Zkuste to znovu.\n");
návrat 1;
}
if (argc==3 && !strcmp(argv,"zobrazit")) disp = 1;
jinak disp = 0;
for(count=atoi(argv); count; -count)
if (disp) printf("%d", pocet);
printf("%c", "\a"); /* na většině počítačů se jedná o volání */
návrat 0;
}

Všimněte si, že pokud nejsou zadány žádné argumenty, zobrazí se chybová zpráva. To je nejtypičtější pro programy, které používají argumenty příkazového řádku k vydávání pokynů, pokud byl proveden pokus o spuštění programu bez správných informací.

Chcete-li získat přístup k jednotlivým znakům příkazového řádku, přidejte do argv druhý index. Například následující program vytiskne všechny argumenty, se kterými byl volán, jeden znak po druhém:

#zahrnout
int main(int argc, char *argv)
{
int t, i;
for(t=0; t {
i = 0;
while(argv[t][i])
{
printf("%c", argv[t][i]);
}
printf(");
}
návrat 0;
}

Je třeba mít na paměti, že první index je pro přístup k řetězci a druhý je pro přístup k charakteru řetězce.

Typicky se argc a argv používají k získání zdrojových příkazů. Teoreticky můžete mít až 32767 argumentů, ale většina operačních systémů vám ani nedovolí se k tomu přiblížit. Tyto argumenty se obvykle používají k určení názvu souboru nebo voleb. Použití argumentů příkazového řádku dodává programu profesionální vzhled a umožňuje použití programu v dávkových souborech.

Pokud zahrnete soubor WILDARGS.OBJ dodávaný s Borland C++, můžete použít zástupné znaky v argumentech typu *.EXE. (Borland C++ zpracovává vzory automaticky a příslušně zvyšuje argc.) Pokud například připojíte WILDARGS.OBJ k následujícímu programu, vytiskne, kolik souborů odpovídá názvu souboru zadanému na příkazovém řádku:

/* Propojit tento program s WILDARGS.OBJ */

#zahrnout
int main(int argc, char *argv)
{
zaregistrovat int i;
printf("%d souborů odpovídá zadanému názvu\n", argc-1);
printf("Jsou to: ");
for(i=1; i printf("%s", argv[i]);
návrat 0;
}

Pokud tento program nazveme WA a spustíme jej následovně, získáme počet souborů, které mají příponu EXE, a seznam názvů těchto souborů:

Kromě argc a argv nabízí Borland C++ také třetí argument příkazového řádku -env. Parametr env umožňuje programu přístup k informacím o prostředí operačního systému. Parametr env musí následovat po argc a argv a je deklarován takto:

Jak vidíte, env je deklarováno stejným způsobem jako argv. Stejně jako argv je to ukazatel na pole řetězců. Každý řádek je řetězec prostředí definovaný operačním systémem. Parametr env nemá žádný protějšek k parametru argc, který říká, kolik řádků prostředí existuje. Místo toho je poslední řádek prostředí null. Následující program vytiskne všechny řetězce prostředí aktuálně definované v operačním systému:

/* tento program vypíše všechny řádky prostředí */

#zahrnout
int main(int argc, char *argv, char *env)
{
int t;
for(t=0; env[t]/ t++)
printf("%s\n", env[t]);
návrat 0;
}

Všimněte si, že ačkoli argc a argv program nepoužívá, musí být uvedeny v seznamu parametrů. C nezná názvy parametrů. Místo toho je jejich použití určeno pořadím, ve kterém jsou parametry deklarovány. Ve skutečnosti můžete parametr nazvat, jak chcete. Protože argc, argv a env jsou tradiční názvy, je nejlepší je používat, aby každý, kdo čte program, okamžitě poznal, že se jedná o argumenty funkce main().

U programů je typickým úkolem najít hodnotu definovanou v řetězci prostředí. Například obsah řetězce PATH umožňuje programům používat vyhledávací cesty. Následující program ukazuje, jak najít řetězce, které deklarují standardní vyhledávací cesty. Používá standardní knihovní funkci strstr(), která má následující prototyp:

Char *strstr(const char *str1, const char *str2);

Funkce strstr() hledá řetězec, na který ukazuje str1, v řetězci, na který ukazuje str2. Pokud je takový řetězec nalezen, vrátí se ukazatel na první pozici. Pokud není nalezena žádná shoda, funkce vrátí hodnotu NULL.

/* program hledá v řetězcích prostředí řetězec obsahující PATH */

#zahrnout
#zahrnout
int main (int argc, char *argv, char *env)
{
int t;
for(t=0; env[t]; t++)
{
if(strstr(env[t], "PATH"))
printf("%s\n", env[t]);
}
návrat 0;
}

Při vytváření konzolové aplikace v programovacím jazyce C++ se automaticky vytvoří řádek velmi podobný tomuto:

int main(int argc, char* argv) // parametry funkce main().

Tento řádek je hlavičkou hlavní funkce main() , parametry argс a argv jsou deklarovány v závorkách. Pokud je tedy program spuštěn přes příkazový řádek, je možné do tohoto programu přenést jakékoli informace, k tomu jsou zde parametry argc a argv. Parametr argc je datového typu int a obsahuje počet parametrů předávaných hlavní funkci. Navíc argc je vždy alespoň 1, i když nepředáváme žádné informace, protože jméno funkce je považováno za první parametr. Parametr argv je pole ukazatelů na řetězce. Přes příkazový řádek lze předávat pouze data typu řetězec. Ukazatele a řetězce jsou dvě velká témata, pro která byly vytvořeny samostatné sekce. Veškeré informace jsou tedy přenášeny prostřednictvím parametru argv. Pojďme si vyvinout program, který spustíme přes příkazový řádek Windows a předáme mu nějaké informace.

// argc_argv.cpp: Určuje vstupní bod pro aplikaci konzoly. #include "stdafx.h" #include pomocí jmenného prostoru std; int main(int argc, char* argv) ( if (argc ><< argv<

// kód Kód::Blocks

// Kód Dev-C++

// argc_argv.cpp: Určuje vstupní bod pro aplikaci konzoly. #zahrnout pomocí jmenného prostoru std; int main(int argc, char* argv) ( if (argc > 1)// pokud předáme argumenty, pak argc bude větší než 1 (v závislosti na počtu argumentů) ( cout<< argv<

Po odladění programu otevřete příkazový řádek Windows a přetáhněte spustitelný soubor našeho programu do okna příkazového řádku, na příkazovém řádku se zobrazí úplná cesta k programu (cestu k programu však můžete napsat ručně), po že můžete stisknout ENTER a program se spustí (viz obrázek 1).

Obrázek 1 - Parametry hlavní funkce

Protože jsme program pouze spustili a nepředali jsme mu žádné argumenty, objevila se zpráva Not arguments. Obrázek 2 ukazuje spuštění stejného programu přes příkazový řádek, ale s předáním argumentu Open.

Obrázek 2 - Parametry hlavní funkce

Argumentem je slovo Open , jak můžete vidět z obrázku, toto slovo se objevilo na obrazovce. Můžete předat několik parametrů najednou a oddělit je čárkou. Pokud je nutné předat parametr skládající se z několika slov, pak musí být uzavřena do dvojitých uvozovek a pak budou tato slova považována za jeden parametr. Obrázek například ukazuje spuštění programu a předává mu argument sestávající ze dvou slov - Funguje to .

Obrázek 3 - Parametry hlavní funkce

A pokud odstraníte uvozovky. Pak uvidíme pouze slovo To. Pokud neplánujete při spouštění programu předávat žádné informace, můžete odstranit argumenty ve funkci main(), můžete také změnit názvy těchto argumentů. Někdy dochází k úpravám parametrů argc a argv, ale vše závisí na typu vytvářené aplikace nebo na vývojovém prostředí.

Při automatickém vytváření konzolové aplikace v programovacím jazyce C++ se automaticky vytvoří hlavní funkce, která je velmi podobná této:

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

Hlavička funkce obsahuje podpis hlavní funkce main() s argumenty argc a argv .
Pokud se program spouští přes příkazový řádek, pak je možné do tohoto programu přenést libovolné informace. K tomu existují argumenty příkazového řádku argc a argv.
Parametr argc je typu int a obsahuje počet parametrů předávaných hlavní funkci. Navíc argc je vždy alespoň 1, i když hlavní funkci nejsou předány žádné informace, protože jméno aplikace je považováno za první parametr.
Parametr argv je pole ukazatelů na řetězce. Přes příkazový řádek lze předávat pouze data typu řetězec.

Když spustíte program prostřednictvím příkazového řádku Windows, můžete mu předat některé informace. V tomto případě bude příkazový řádek vypadat takto:
Jednotka:\cesta\název.exe argument1 argument2 ...

Argumenty příkazového řádku jsou odděleny jednou nebo více mezerami.

Argument argv obsahuje plně kvalifikovaný název aplikace:

#zahrnout
pomocí jmenného prostoru std;

cout<< argv << endl;

návrat 0;
}

Výsledek provedení

Příklad: výpočet součinu dvou celých čísel
Program používá funkci převodu řetězce na celé číslo StrToInt() odtud .

#zahrnout
pomocí jmenného prostoru std;
int StrToInt(char*s) (…)
int main(int argc, char * argv) (

Int a = 0, b = 0;

If (argc > 1)

a = StrToInt(argv);

Pokud (argc > 2)

b = StrToInt(argv);

cout<< a <<«*» << b << «= « << a*b << endl;

návrat 0;
}

Program se spouští jako

Výsledek provedení

Ladění programu pomocí argumentů příkazového řádku

Chcete-li předat argumenty příkazového řádku při ladění programu, musíte vstoupit do nabídky Vlastnosti projekt.


Na kartě Vlastnosti konfigurace -> Ladění Vybrat Argumenty příkazu a nastavit jejich hodnoty.

Když spustíte program v režimu ladění, zadané argumenty bude program považovat za argumenty příkazového řádku.

Programům C můžete předat určité argumenty. Když se na začátku výpočtu zavolá main(), předají se mu tři parametry. První z nich určuje počet argumentů příkazu při přístupu k programu. Druhým je pole ukazatelů na znakové řetězce obsahující tyto argumenty (jeden argument na řetězec). Třetí je také pole ukazatelů na znakové řetězce, slouží k přístupu k parametrům operačního systému (proměnným prostředí).

Každý takový řádek je reprezentován jako:

proměnná = hodnota\0

Poslední řádek lze najít dvěma koncovými nulami.

Pojmenujme argumenty funkce main(): argc, argv a env (jakákoli jiná jména jsou možná). Pak jsou povoleny následující popisy:

main(int argc, char *argv)

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

Předpokládejme, že na jednotce A: je nějaký program prog.exe. Pojďme to řešit takto:

A:\>prog.exe soubor1 soubor2 soubor3

Potom argv je ukazatel na řetězec A:\prog.exe, argv je ukazatel na řetězec file1 a tak dále. Na první aktuální argument ukazuje argv a na poslední argv. Pokud argc=1, pak za názvem programu na příkazovém řádku nejsou žádné parametry. V našem příkladu argc=4.

rekurze

Rekurze je způsob volání, při kterém funkce volá sama sebe.

Důležitým bodem při sestavování rekurzivního programu je organizace výstupu. Zde je snadné udělat chybu, že funkce bude důsledně volat sama sebe donekonečna. Rekurzivní proces proto musí krok za krokem problém zjednodušit tak, aby se pro něj nakonec objevilo nerekurzivní řešení. Použití rekurze není vždy žádoucí, protože může vést k přetečení zásobníku.

Funkce knihovny

V programovacích systémech se podprogramy pro řešení běžných problémů spojují do knihoven. Mezi tyto úkoly patří: výpočet matematických funkcí, vstup/výstup dat, zpracování řetězců, interakce s nástroji operačního systému atd. Použití knihovních podprogramů zbavuje uživatele potřeby vyvíjet vhodné nástroje a poskytuje mu doplňkovou službu. Funkce obsažené v knihovnách jsou dodávány s programovacím systémem. Jejich deklarace jsou uvedeny v souborech *.h (jedná se o tzv. include nebo hlavičkové soubory). Proto, jak je uvedeno výše, na začátku programu s knihovními funkcemi by měly být řádky jako:

#zahrnout<включаемый_файл_типа_h>

Například:

#zahrnout

K dispozici jsou také prostředky pro rozšiřování a vytváření nových knihoven s uživatelskými programy.

Globálním proměnným je přiděleno pevné místo v paměti po dobu trvání programu. Lokální proměnné jsou uloženy v zásobníku. Mezi nimi je paměťová oblast pro dynamickou alokaci.

Funkce malloc() a free() se používají k dynamickému přidělování volné paměti. Funkce malloc() paměť alokuje, funkce free() ji uvolní. Prototypy těchto funkcí jsou uloženy v hlavičkovém souboru stdlib.h a vypadají takto:

void *malloc(velikost_t velikost);

void *free(void *p);

Funkce malloc() vrací ukazatel typu void; pro správné použití musí být hodnota funkce převedena na ukazatel na příslušný typ. Při úspěchu funkce vrátí ukazatel na první bajt volné paměti o velikosti. Pokud není dostatek paměti, vrátí se hodnota 0. Operace sizeof() se používá k určení počtu bajtů potřebných pro proměnnou.

Příklad použití těchto funkcí:

#zahrnout

#zahrnout

p = (int *) malloc(100 * sizeof(int)); /* Přidělte paměť pro 100

celá čísla */

printf("Nedostatek paměti\n");

pro (i = 0; i< 100; ++i) *(p+i) = i; /* Использование памяти */

pro (i = 0; i< 100; ++i) printf("%d", *(p++));

zdarma(p); /* Volná paměť */

Před použitím ukazatele vráceného malloc() se musíte ujistit, že je dostatek paměti (ukazatel není null).

Preprocesor

C preprocesor je program, který zpracovává vstup do kompilátoru. Preprocesor se podívá na zdrojový program a provede následující akce: připojí k němu dané soubory, provede substituce a také spravuje podmínky kompilace. Preprocesor je určen pro programové řádky, které začínají symbolem #. Na jeden řádek je povolen pouze jeden příkaz (direktiva preprocesoru).

Směrnice

#define náhrada identifikátoru

způsobí, že následující text programu nahradí pojmenovaný identifikátor textem náhrady (všimněte si chybějícího středníku na konci tohoto příkazu). Tato směrnice v podstatě zavádí definici makra (makro), kde „identifikátor“ je název definice makra a „substituce“ je posloupnost znaků, kterými preprocesor nahradí zadaný název, když jej najde v textu programu. Název makra se obvykle píše velkými písmeny.

Zvažte příklady:

První řádek způsobí, že program nahradí identifikátor MAX konstantou 25. Druhý umožňuje použít v textu místo úvodní složené závorky (() slovo BEGIN.

Všimněte si, že vzhledem k tomu, že preprocesor nekontroluje kompatibilitu mezi symbolickými názvy definic maker a kontextem, ve kterém jsou použity, doporučuje se definovat takové identifikátory nikoli direktivou #define, ale klíčovým slovem const s explicitním označením typu. (to platí spíše pro C + +):

const int MAX = 25;

(typ int lze vynechat, protože je standardně nastaven).

Pokud direktiva #define vypadá takto:

#define identifier(identifikátor, ..., identifikátor) ​​substituce

a mezi prvním identifikátorem a úvodní závorkou není mezera, pak se jedná o definici substituce makra s argumenty. Například po zobrazení řádku jako:

#define READ(val) scanf("%d", &val)

příkaz READ(y); se zachází stejně jako scanf("%d",&y);. Zde je argument argument a substituce makra se provádí s argumentem.

Pokud jsou v substituci dlouhé definice, které pokračují na dalším řádku, je na konec dalšího pokračování řádku umístěn znak \.

Do definice makra můžete umístit objekty oddělené znaky ##, například:

#define PR(x, y) x##y

Poté PR(a, 3) zavolá substituci a3. Nebo například definice makra

#define z(a, b, c, d) a(b##c##d)

změní z(sin, x, +, y) na sin(x+y).

Znak # umístěný před argument makra označuje, že je převeden na řetězec. Například po směrnici

#define PRIM(var) printf(#var"= %d", var)

následující část textu programu

se převádí takto:

printf("rok""= %d", rok);

Pojďme si popsat další direktivy preprocesoru. Direktivu #include jsme viděli již dříve. Může být použit ve dvou formách:

#include "název souboru"

#zahrnout<имя файла>

Účinkem obou příkazů je zahrnutí souborů se zadaným názvem do programu. První načte soubor z aktuálního adresáře nebo adresáře zadaného jako prefix. Druhý příkaz hledá soubor ve standardních umístěních definovaných v programovacím systému. Pokud soubor, jehož název je napsán v uvozovkách, není v zadaném adresáři nalezen, bude hledání pokračovat v podadresářích zadaných pro příkaz #include<...>. Direktivy #include mohou být vnořeny do sebe.

Další skupina direktiv umožňuje selektivně kompilovat části programu. Tento proces se nazývá podmíněná kompilace. Tato skupina zahrnuje direktivy #if, #else, #elif, #endif, #ifdef, #ifndef. Základní tvar směrnice #if je:

#if konstantní_výraz příkazová_sekvence

Zde se kontroluje hodnota konstantního výrazu. Pokud je pravdivá, provede se daná sekvence příkazů a pokud je nepravdivá, pak se tato sekvence příkazů přeskočí.

Akce direktivy #else je podobná akci příkazu else v jazyce C, například:

#if konstantní_výraz

posloupnost_2

Pokud je konstantní výraz pravdivý, pak se provede sekvence_operátorů_1, a pokud je nepravda, provede se sekvence_operátorů_2.

Direktiva #elif znamená akci typu "else if". Hlavní forma jeho použití je následující:

#if konstantní_výraz

sekvence_příkazů

#elif konstantní_výraz_1

posloupnost_1

#elif konstantní_výraz_n

sekvence_výroků_n

Tato forma je podobná konstrukci jazyka C formuláře: if...else if...else if...

Směrnice

#ifdef identifikátor

nastavuje, zda je zadaný identifikátor aktuálně definován, tzn. zda byl zahrnut do direktiv ve tvaru #define. Zobrazit řádek

#ifndef identifikátor

zkontroluje, zda zadaný identifikátor není aktuálně definován. Za kteroukoli z těchto direktiv může následovat libovolný počet řádků textu, případně obsahující příkaz #else (nelze použít #elif) a končící řádkem #endif. Pokud je kontrolovaná podmínka pravdivá, pak jsou všechny řádky mezi #else a #endif ignorovány, a pokud je nepravda, pak řádky mezi kontrolou a #else (pokud není slovo #else, pak #endif). Direktivy #if a #ifndef lze vnořit jedna do druhé.

Zobrazit směrnici

#undef identifikátor

způsobí, že zadaný identifikátor bude považován za nedefinovaný, tzn. není vyměnitelný.

Zvažte příklady. Tyto tři směrnice jsou:

zkontrolujte, zda je definován identifikátor WRITE (tj. byl to příkaz ve tvaru #define WRITE...), a pokud ano, pak je jméno WRITE považováno za nedefinované, tzn. není vyměnitelný.

směrnice

#define WRITE fprintf

zkontrolujte, zda není identifikátor WRITE definován, a pokud ano, pak je místo jména fprintf určen identifikátor WRITE.

Direktiva #error je napsána v následujícím tvaru:

#error error_message

Pokud se objeví v textu programu, kompilace se zastaví a na displeji se zobrazí chybová zpráva. Tento příkaz se používá hlavně během fáze ladění. Všimněte si, že chybová zpráva nemusí být uzavřena do dvojitých uvozovek.

Direktiva #line je určena ke změně hodnot proměnných _LINE_ a _FILE_ definovaných v programovacím systému C. Proměnná _LINE_ obsahuje číslo řádku právě prováděného programu. Identifikátor _FILE_ je ukazatel na řetězec s názvem kompilovaného programu. Direktiva #line je napsána takto:

#číslo řádku "název souboru"

Číslo je zde jakékoli kladné celé číslo, které bude přiřazeno proměnné _LINE_, název_souboru je volitelný parametr, který přepíše hodnotu _FILE_.

Direktiva #pragma umožňuje předat některé instrukce kompilátoru. Například čára

označuje, že v programu C jsou řetězce jazyka symbolických instrukcí. Například:

Zvažte některé globální identifikátory nebo názvy maker (názvy definic maker). Je definováno pět takových jmen: _LINE_, _FILE_, _DATE_, _TIME_, _STDC_. Dva z nich (_LINE_ a _FILE_) již byly popsány výše. Identifikátor _DATE_ určuje řetězec, který ukládá datum, kdy byl zdrojový soubor přeložen do objektového kódu. Identifikátor _TIME_ určuje řetězec, který ukládá čas, kdy byl zdrojový soubor přeložen do objektového kódu. Makro _STDC_ má hodnotu 1, pokud jsou použity standardně definované názvy maker. Jinak tato proměnná nebude definována.

Stává se, že data jsou do programu přenášena z příkazového řádku při jeho volání. Taková data se nazývají argumenty příkazového řádku. Vypadá to například takto:

./a.out test.txt ls -lt /home/peter/

To volá programy a.out (z aktuálního adresáře) a ls (ze stejného adresáře zadaného v proměnné prostředí PATH). První program z příkazové řádky obdrží jedno slovo - test.txt, druhý - dvě: -lt a /home/peter/.

Pokud je program napsán v C, pak při jeho spuštění je řízení okamžitě přeneseno na funkci main(), proto je to ona, kdo obdrží argumenty příkazového řádku, které jsou přiřazeny k jejím parametrům proměnných.

Doposud jsme definovali funkci main() tak, že nebere žádné parametry a nic nevrací. Ve skutečnosti v C jakákoli funkce ve výchozím nastavení (pokud není definováno nic jiného) vrací celé číslo. To lze ověřit. Pokud napíšete kód takto:

main() ( printf("Ahoj \n"); návrat 0; )

Pak během kompilace nedojde k žádnému varování ani chybě. Totéž se stane, pokud napíšeme int main() . To dokazuje, že výchozí funkce vrací celé číslo a ne nic (void). Ačkoli to, co funkce vrací, lze vždy „přepsat“, například voidmain() nebo float main() .

Když je program volán z příkazového řádku, vždy se mu předá dvojice dat:

  1. celé číslo, označující počet slov (prvků oddělených mezerami) na příkazovém řádku při volání,
  2. ukazatel na pole řetězců, kde každý řádek je jedno slovo z příkazového řádku.

Všimněte si, že se bere v úvahu i samotný název programu. Pokud hovor vypadá například takto:

./a.out 12 téma 2

Pak je první argument programu 4 a pole řetězců je definováno jako (./a.out“, „12“, „téma“, „2“).

Věnujte pozornost terminologii, existují pouze dva argumenty programu (číslo a pole), ale tolik argumentů příkazového řádku, kolik chcete. Argumenty příkazového řádku jsou "přeloženy" do argumentů programu (do argumentů funkce main()).
Tato data (číslo a ukazatel) jsou předána programu, i když je jednoduše volán jménem, ​​aniž by mu bylo cokoliv předáno: ./a.out. V tomto případě je první argument 1 a druhý argument ukazuje na pole pouze jednoho řetězce ("./a.out").

Skutečnost, že jsou data předána programu, neznamená, že by je měla přijímat funkce main(). Pokud je funkce main() definována bez parametrů, pak argumenty příkazového řádku nelze získat. I když nic vám nebrání je poslat. Nedojde k žádné chybě.

Chcete-li získat přístup k datům předávaným programu, musí být přiřazeny k proměnným. Protože argumenty jsou okamžitě předány do main() , jeho hlavička by měla vypadat takto:
hlavní (int n, char *arr)

První proměnná (n) obsahuje počet slov a druhá proměnná obsahuje ukazatel na pole řetězců. Často je druhý parametr zapsán jako **arr . Nicméně je to stejné. Připomeňme, že samotné pole řetězců obsahuje jako své prvky ukazatele na řetězce. A ve funkci předáme ukazatel na první prvek pole. Ukazuje se, že předáváme ukazatel na ukazatel, tzn. **arr.

Cvičení
Napište program jako tento:

#zahrnout int main(int argc, char ** argv) ( int i; printf ("%d \n", argc); pro (i= 0; i< argc; i++ ) puts (argv[ i] ) ; }

Při volání vypíše počet slov na příkazovém řádku a každé slovo na nový řádek. Volejte to bez argumentů příkazového řádku a s argumenty.

V programu jsme použili proměnné parametry argc a argv. Je zvykem používat právě taková jména, ale ve skutečnosti to může být cokoliv. Je lepší se tohoto standardu držet, aby byly vaše programy srozumitelnější nejen vám, ale i ostatním programátorům.

Praktický význam předávání dat programu

Pokud máte zkušenosti s příkazovým řádkem GNU/Linuxu, víte, že většina příkazů má přepínače a argumenty. Například při prohlížení obsahu adresářů, kopírování, přesouvání jsou jako argumenty zadány objekty systému souborů, na kterých je příkaz spuštěn. Vlastnosti jeho implementace jsou určeny pomocí klíčů. Například v příkazu

Cp -r ../les_1 ../les_101

cp je název příkazu, -r je přepínač a ../les_1 a ../les_101 jsou argumenty příkazu.

Obecně se nejčastěji při spouštění programů přenášejí adresy souborů a „modifikátory“ (to jsou klíče) procesu provádění programu.

Napišme program, který otevře soubory určené uživatelem na příkazovém řádku pro zápis nebo připojení a zapíše (přidá) tam stejné informace, které uživatel zadá z klávesnice během provádění programu:

#zahrnout #zahrnout main (int argc, char ** argv) ( int i, ch; FILE * f[ 5 ] ; if (argc< 3 || argc >7 ) ( klade ( "Neplatný počet parametrů"); návrat 1; ) if (strcmp (argv[ 1 ] , "-w" ) != 0 && strcmp (argv[ 1 ], "-a" ) != 0 ) ( vloží ( "První parametr může být -w nebo -a"); návrat 2; ) pro (i= 0; i< argc- 2 ; i++ ) { f[ i] = fopen (argv[ i+ 2 ] , argv[ 1 ] + 1 ) ; if (f[ i] == NULL) { printf ("Soubor %s nelze otevřít\n ", argv[i+2]); návrat 3; ) ) while ((ch = getchar () ) != EOF) pro (i= 0; i< argc- 2 ; i++ ) putc (ch, f[ i] ) ; for (i= 0 ; i < argc- 2 ; i++ ) fclose (f[ i] ) ; return 0 ; }

Vysvětlení ke kódu:

  1. Vytvoří se pole pěti ukazatelů souborů. Proto nelze současně otevřít více než pět souborů. Ukazatel souboru prvního souboru bude uložen v prvku pole f, druhý - v f atd.
  2. Kontroluje se počet argumentů příkazového řádku. Musí být alespoň tři, protože. první je název programu, druhý je režim otevření souboru, třetí je první nebo jediný soubor, do kterého se má zapisovat. Protože program umožňuje otevřít pouze pět souborů, celkový počet argumentů příkazového řádku nemůže překročit sedm. Pokud je tedy počet argumentů menší než 3 nebo větší než 7, pak program končí, protože Příkaz return způsobí ukončení funkce, i když je za ním další kód. Vrácenou hodnotu funkce, která se nerovná 0, může nadřazený proces interpretovat jako zprávu, že program skončil s chybou.
  3. Zkontroluje se správnost druhého argumentu příkazového řádku. Pokud není ani "-w" ani "-a", pak podmíněný výraz v druhém if vrátí 1 (pravda). Funkce strcmp() umožňuje porovnávat řetězce a vrací 0, pokud jsou stejné.
  4. Smyčka for otevírá soubory na zadaných adresách, které začínají na třetím prvku pole argv. Proto se k i přidá 2, aby se získaly prvky pole argv, počínaje třetím. Výraz argc-2 označuje počet předávaných jmen souborů; protože argc ukládá celkový počet argumentů příkazového řádku, z nichž první dva nejsou názvy souborů.
  5. Výraz argv+1 vám umožňuje "vyjmout" podřetězec "w" (nebo "a") z řetězce "-w" (nebo "-a"), protože argv je v podstatě ukazatel na první prvek řetězce. Přidáním jedničky k ukazateli jej posuneme na další prvek v poli.
  6. Pokud soubor nelze otevřít, funkce fopen() vrátí hodnotu NULL. V tomto případě program končí.
  7. Každý znak zadaný uživatelem z klávesnice je zapsán do všech otevřených souborů.
  8. Na konci jsou soubory uzavřeny.