A Borland C++ három main() argumentumot támogat. Az első kettő a hagyományos argc és argv. Ezek az egyetlen érvek fő funkciókat(), az ANSI C szabvány által meghatározott. Lehetővé teszik parancssori argumentumok átadását a programnak. A parancssori argumentumok a program nevét követő információk parancs sor operációs rendszer. Például, amikor egy programot a Borland soros fordítóval fordítanak le, a bcc tipikusan begépelve program_neve

Ahol program_neve a lefordítandó program. A program nevét argumentumként adjuk át a fordítónak.

Az argc paraméter a parancssori argumentumok számát tartalmazza, és egy egész szám. Mindig legalább 1, mert a program neve az első argumentum. Az argv paraméter egy mutató karaktermutatók tömbjére. Ennek a tömbnek minden eleme egy parancssori argumentumra mutat. Minden parancssori argumentum karakterlánc. A program minden számot belső formátumba konvertál. A következő program a „Hello” szöveget írja ki, amelyet a felhasználónév követ, ha közvetlenül a program neve után írják be:

#beleértve

{
if(argc!=2)
{
printf("Elfelejtette beírni a nevét\n");
visszatérés 1;
}
printf("Hello %s", argv);
visszatérés 0;
}

Ha hívják ez a program név és a felhasználónév Sergey, akkor a program futtatásához írja be:
neve Szergej.
A program eredményeként megjelenik:
Szia Szergej.

A parancssori argumentumokat szóközzel vagy tabulátorral kell elválasztani. A vessző, pontosvessző és hasonló karakterek nem minősülnek elválasztónak. Például:

Három sorból áll, míg

Herb, Rick, Fred

Ez egy sor – a vessző nem elválasztójel.

Ha szóközöket vagy tabulátorokat tartalmazó karakterláncot szeretne egyetlen argumentumként átadni, zárja be dupla idézőjelek. Például ez az egyik érv:

"ez egy teszt"

Fontos az argv helyes deklarálása. A legjellemzőbb módszer a következő:

Az üres zárójelek azt jelzik, hogy a tömbnek nincs rögzített hossza. Az egyes elemeket argv indexeléssel érheti el. Például az argv az első sorra mutat, amely mindig a program nevét tartalmazza. argv a következő sorra mutat, és így tovább.

Az alábbiakban egy kis példa látható a parancssori argumentumok használatára. Visszaszámol a parancssorban megadott értéktől, és a nulla elérésekor jelet ad ki. Vegye figyelembe, hogy az első argumentum a szabványos atoi() függvény segítségével egész számmá konvertált számot tartalmaz. Ha a "display" karakterlánc második argumentumként szerepel, akkor maga a számláló jelenik meg a képernyőn.

/* számláló program */

#beleértve
#beleértve
#beleértve
int main(int argc, char *argv)
{
int diszp, gróf;
if(argc<2)
{
printf("Meg kell adnod a számlálás hosszát\n");
printf("a parancssorban. Próbáld újra.\n");
visszatérés 1;
}
if (argc==3 && !strcmp(argv,"megjelenítés")) disp = 1;
else disp = 0;
for(count=atoi(argv); count; -count)
if (disp) printf("%d", count);
printf("%c", "\a"); /* a legtöbb számítógépen ez egy hívás */
visszatérés 0;
}

Vegye figyelembe, hogy ha nincs megadva argumentum, hibaüzenet jelenik meg. Ez leginkább azokra a programokra jellemző, amelyek parancssori argumentumokat használnak az utasítások kiadására, ha a megfelelő információk nélkül próbálták meg futtatni a programot.

Az egyes parancssori karakterek eléréséhez adjon hozzá egy második indexet az argv-hez. Például a következő program kiírja az összes argumentumot, amellyel meghívták, egy-egy karakterrel:

#beleértve
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(");
}
visszatérés 0;
}

Emlékeznünk kell arra, hogy az első index a karakterlánc eléréséhez, a második pedig a karakterlánc karakterének eléréséhez szolgál.

Általában az argc és az argv a forrásparancsok lekérésére szolgál. Elméletileg akár 32767 argumentum is lehet, de a legtöbb operációs rendszer ezt sem engedi meg közelíteni. Általában ezeket az argumentumokat fájlnév vagy beállítások megadására használják. A parancssori argumentumok használata professzionális megjelenést kölcsönöz a programnak, és lehetővé teszi a program kötegfájlokban való használatát.

Ha megadja a Borland C++-hoz mellékelt WILDARGS.OBJ fájlt, használhat helyettesítő karaktereket a *.EXE típusú argumentumokban. (A Borland C++ automatikusan kezeli a mintákat, és ennek megfelelően növeli az argc-t.) Például, ha a WILDARGS.OBJ-t a következő programhoz csatlakoztatja, akkor kiírja, hogy hány fájl egyezik a parancssorban megadott fájl nevével:

/* Kapcsolja össze ezt a programot a WILDARGS.OBJ-vel */

#beleértve
int main(int argc, char *argv)
{
regisztrál int i;
printf("%d fájl megegyezik a megadott névvel\n", argc-1);
printf("Ezek: ");
for(i=1; i printf("%s", argv[i]);
visszatérés 0;
}

Ha ezt a programot WA-nak nevezzük, akkor a következőképpen futtassuk, megkapjuk az EXE kiterjesztésű fájlok számát, valamint ezeknek a fájlok nevének listáját:

Az argc és argv mellett a Borland C++ egy harmadik parancssori argumentumot is biztosít -env. Az env paraméter lehetővé teszi, hogy a program hozzáférjen az operációs rendszer környezetével kapcsolatos információkhoz. Az env paraméternek követnie kell az argc és argv paramétereket, és a következőképpen deklarálható:

Mint látható, az env ugyanúgy deklarálva van, mint az argv. Csakúgy, mint az argv, ez is egy karakterlánc-tömb mutatója. Minden sor az operációs rendszer által meghatározott környezeti karakterlánc. Az env paraméternek nincs megfelelője az argc paraméternek, amely megmondja, hogy hány környezeti sor van. Ehelyett a környezet utolsó sora nulla. A következő program kinyomtatja az operációs rendszerben jelenleg definiált összes környezeti karakterláncot:

/* ez a program kiírja az összes környezeti sort */

#beleértve
int main(int argc, char *argv, char *env)
{
int t;
for(t=0; env[t]/t++)
printf("%s\n", env[t]);
visszatérés 0;
}

Vegye figyelembe, hogy bár a program nem használja az argc-t és az argv-t, ezeknek jelen kell lenniük a paraméterlistában. C nem ismeri a paraméterek nevét. Ehelyett használatukat a paraméterek deklarálási sorrendje határozza meg. Valójában a paramétert tetszés szerint hívhatja. Mivel az argc, argv és env hagyományos nevek, a legjobb, ha továbbra is használja őket, hogy a programot olvasók azonnal felismerjék, hogy ezek a main() függvény argumentumai.

A programok esetében tipikus feladat a környezeti karakterláncban meghatározott érték megkeresése. Például a PATH karakterlánc tartalma lehetővé teszi a programok számára a keresési útvonalak használatát. A következő program bemutatja, hogyan lehet megtalálni a szabványos keresési útvonalakat deklaráló karakterláncokat. A szabványos strstr() könyvtárfüggvényt használja, amelynek a következő prototípusa van:

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

Az strstr() függvény az str1 által mutatott karakterláncot keresi az str2 által mutatott karakterláncban. Ha ilyen karakterláncot találunk, akkor egy mutatót ad vissza az első pozícióra. Ha nem található egyezés, a függvény NULL-t ad vissza.

/* a program a környezeti karakterláncokban keres egy PATH-ot tartalmazó karakterláncot */

#beleértve
#beleértve
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]);
}
visszatérés 0;
}

Ha konzolalkalmazást hoz létre C++ programozási nyelven, automatikusan létrejön egy ehhez nagyon hasonló sor:

int main(int argc, char* argv) // main() függvény paraméterei

Ez a sor a main() fő függvény fejléce, az argc és argv paraméterek zárójelben vannak deklarálva. Tehát, ha a program a parancssoron keresztül fut, akkor bármilyen információt át lehet vinni ebbe a programba, ehhez vannak argc és argv paraméterek. Az argc paraméter int adattípusú, és a fő függvénynek átadott paraméterek számát tartalmazza. Ráadásul az argc mindig legalább 1, még akkor is, ha nem adunk át semmilyen információt, mivel a függvény neve tekinthető az első paraméternek. Az argv paraméter karakterláncokra mutató mutatók tömbje. Csak karakterlánc típusú adatok vihetők át a parancssorban. A mutatók és a karakterláncok két nagy téma, amelyekhez külön szakaszok készültek. Tehát minden információ az argv paraméteren keresztül kerül továbbításra. Készítsünk egy programot, amelyet a Windows parancssorán keresztül futtatunk, és átadunk neki néhány információt.

// argc_argv.cpp: Megadja a konzolalkalmazás belépési pontját. #include "stdafx.h" #include névtér használata std; int main(int argc, char* argv) ( if (argc ><< argv<

// kód Code::Blocks

// Dev-C++ kód

// argc_argv.cpp: Megadja a konzolalkalmazás belépési pontját. #beleértve névtér használata std; int main(int argc, char* argv) ( ha (argc > 1)// ha argumentumokat adunk át, akkor az argc nagyobb lesz 1-nél (az argumentumok számától függően) ( cout<< argv<

A program hibakeresése után nyissuk meg a Windows parancssort és húzzuk be programunk futtatható fájlját a parancssori ablakba, a parancssorban megjelenik a program teljes elérési útja (de a program elérési útját manuálisan is megírhatjuk), miután hogy megnyomhatod BELÉPés a program elindul (lásd 1. ábra).

1. ábra - A fő funkció paraméterei

Mivel csak futtattuk a programot, és nem adtunk át neki argumentumot, a Not arguments üzenet jelent meg. A 2. ábra ugyanazon program elindítását mutatja a parancssoron keresztül, de az Open argumentum átadásával.

2. ábra - A fő funkció paraméterei

Az érv az Open szó, amint az ábrán látható, ez a szó jelent meg a képernyőn. Egyszerre több paramétert is átadhat, vesszővel elválasztva őket. Ha több szóból álló paramétert kell átadni, akkor azokat dupla idézőjelbe kell tenni, és ezek a szavak egy paraméternek számítanak. Például az ábra a program elindítását mutatja, két szóból álló argumentumot átadva neki - Működik .

3. ábra - A fő funkció paraméterei

És ha eltávolítja az idézőjeleket. Akkor csak az It szót fogjuk látni. Ha nem tervezünk semmilyen információt átadni a program indításakor, akkor a main() függvényben eltávolíthatjuk az argumentumokat, illetve megváltoztathatjuk ezen argumentumok nevét is. Néha módosulnak az argc és argv paraméterek, de mindez a létrehozandó alkalmazás típusától vagy a fejlesztői környezettől függ.

Amikor automatikusan létrehoz egy konzolalkalmazást C++ programozási nyelven, automatikusan létrejön egy fő funkció, amely nagyon hasonló ehhez:

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

A függvény fejléce tartalmazza a main() fő függvény aláírását argc és argv argumentumokkal.
Ha a program a parancssoron keresztül fut, akkor bármilyen információ átvihető ebbe a programba. Ehhez vannak argc és argv parancssori argumentumok.
Az argc paraméter int típusú, és a fő függvénynek átadott paraméterek számát tartalmazza. Sőt, az argc mindig legalább 1, még akkor is, ha nem adunk át információt a fő függvénynek, mivel az alkalmazás neve tekinthető az első paraméternek.
Az argv paraméter karakterláncokra mutató mutatók tömbje. Csak karakterlánc típusú adatok vihetők át a parancssorban.

Amikor egy programot a Windows parancssorán keresztül futtat, átadhat neki bizonyos információkat. Ebben az esetben a parancssor így fog kinézni:
Meghajtó:\útvonal\név.exe argumentum1 argumentum2 ...

A parancssori argumentumokat egy vagy több szóköz választja el.

Az argv argumentum a teljes képzésű alkalmazásnevet tartalmazza:

#beleértve
névtér használata std;

cout<< argv << endl;

visszatérés 0;
}

A végrehajtás eredménye

Példa: két egész szám szorzatának kiszámítása
A program a string integer konverziós függvényt használja StrToInt() innen.

#beleértve
névtér használata std;
int StrToInt(char*s) (…)
int main(int argc, char * argv) (

int a = 0, b = 0;

Ha (argc > 1)

a = StrToInt(argv);

Ha (argc > 2)

b = StrToInt(argv);

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

visszatérés 0;
}

A program a következő néven indul

A végrehajtás eredménye

Program hibakeresése parancssori argumentumokkal

A program hibakeresése során a parancssori argumentumok átadásához el kell érnie a menüt Tulajdonságok projekt.


A lapon Konfigurációs tulajdonságok -> Hibakeresés választ Parancs argumentumokés meghatározzák az értékeiket.

Amikor a programot hibakeresési módban futtatja, a beírt argumentumokat a program parancssori argumentumként kezeli.

Bizonyos argumentumokat átadhat a C programoknak. Amikor a main() meghívásra kerül a számítás elején, három paraméter kerül átadásra. Ezek közül az első határozza meg a parancsargumentumok számát a program elérésekor. A második az ezeket az argumentumokat tartalmazó karakterláncokra mutató mutatók tömbje (karakterlánconként egy argumentum). A harmadik szintén a karakterláncokra mutató mutatók tömbje, amely az operációs rendszer paramétereinek (környezeti változóinak) elérésére szolgál.

Bármely ilyen vonal a következőképpen jelenik meg:

változó = érték\0

Az utolsó sort két záró nulla találja meg.

Nevezzük el a main() függvény argumentumát: argc, argv és env (bármilyen más név is lehetséges). Ekkor a következő leírások megengedettek:

main(int argc, char *argv)

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

Tegyük fel, hogy van valami prog.exe program az A: meghajtón. Fogalmazzuk meg így:

A:\>prog.exe fájl1 fájl2 fájl3

Ekkor az argv az A:\prog.exe karakterláncra mutató mutató, az argv pedig a file1 karakterláncra mutató mutató, és így tovább. Az első tényleges argumentumra az argv, az utolsóra pedig az argv mutat rá. Ha argc=1, akkor a parancssorban a program neve után nincsenek paraméterek. Példánkban argc=4.

rekurzió

A rekurzió egy olyan hívási módszer, amelyben egy függvény önmagát hívja meg.

A rekurzív program összeállításának fontos pontja a kilépés megszervezése. Könnyen elkövethetjük itt azt a hibát, hogy a függvény következetesen a végtelenségig hívja magát. Ezért a rekurzív folyamatnak lépésről lépésre le kell egyszerűsítenie a problémát, hogy a végén egy nem rekurzív megoldás jelenjen meg rá. A rekurzió használata nem mindig kívánatos, mivel veremtúlcsorduláshoz vezethet.

Könyvtári funkciók

A programozási rendszerekben a gyakran előforduló problémák megoldására szolgáló szubrutinokat könyvtárakká egyesítik. Ezek a feladatok a következők: matematikai függvények számítása, adatbevitel/kimenet, karakterlánc-feldolgozás, interakció az operációs rendszer eszközeivel, stb. A könyvtári rutinok használata megkíméli a felhasználót a megfelelő eszközök fejlesztésétől, és további szolgáltatást biztosít számára. A könyvtárakban található funkciókat a programozási rendszerrel együtt szállítjuk. Deklarációikat *.h fájlokban adják meg (ezek az ún. include vagy header fájlok). Ezért, amint fentebb említettük, a könyvtári funkciókkal rendelkező program elején olyan soroknak kell lenniük, mint:

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

Például:

#beleértve

Lehetőségek vannak felhasználói programokkal bővíteni és új könyvtárakat létrehozni.

A globális változók fix helyet foglalnak el a memóriában a program időtartamára. A helyi változókat a verem tárolja. Közöttük van egy memóriaterület a dinamikus allokációhoz.

A malloc() és free() függvények a szabad memória dinamikus lefoglalására szolgálnak. A malloc() függvény lefoglalja a memóriát, a free() függvény felszabadítja. Ezeknek a függvényeknek a prototípusait az stdlib.h fejlécfájl tárolja, és így néznek ki:

void *malloc(méret_t méret);

void *free(void *p);

A malloc() függvény egy void típusú mutatót ad vissza; a megfelelő használat érdekében a függvényértéket át kell alakítani a megfelelő típusú mutatóvá. Siker esetén a függvény egy mutatót ad vissza a szabad memória első bájtjára. Ha nincs elég memória, akkor a 0 értéket adjuk vissza, A sizeof() művelet segítségével határozható meg a változóhoz szükséges bájtok száma.

Példa a függvények használatára:

#beleértve

#beleértve

p = (int *) malloc(100 * sizeof(int)); /* Memória lefoglalása 100-hoz

egész számok */

printf("Memória megtelt\n");

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

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

szabad(p); /* Szabad memória */

A malloc() által visszaadott mutató használata előtt meg kell győződnie arról, hogy van elég memória (a mutató nem null).

Előfeldolgozó

A C előfeldolgozó egy olyan program, amely feldolgozza a fordító bemenetét. Az előfeldolgozó megnézi a forrásprogramot, és a következő műveleteket hajtja végre: csatlakoztatja hozzá az adott fájlokat, végrehajtja a helyettesítéseket, valamint a fordítási feltételeket is kezeli. Az előfeldolgozó a # szimbólummal kezdődő programsorokhoz készült. Soronként csak egy parancs (előfeldolgozó direktíva) engedélyezett.

Irányelv

#define azonosító helyettesítés

hatására a következő programszöveg lecseréli a megnevezett azonosítót a helyettesítő szövegre (figyelje meg, hogy a parancs végén nincs pontosvessző). Ez a direktíva lényegében egy makródefiníciót (makrót) vezet be, ahol az „azonosító” a makródefiníció neve, a „csere” pedig az a karaktersorozat, amellyel az előfeldolgozó lecseréli a megadott nevet, amikor megtalálja azt a programszövegben. A makró nevét általában nagybetűvel írják.

Vegye figyelembe a példákat:

Az első sor hatására a program lecseréli a MAX azonosítót a 25 konstansra. A második lehetővé teszi, hogy a szövegben a nyitó kapcsos kapcsos zárójel (() helyett a BEGIN szót használja.

Vegye figyelembe, hogy mivel az előfeldolgozó nem ellenőrzi a makródefiníciók szimbolikus nevei és a felhasználási környezet közötti kompatibilitást, ajánlatos az ilyen azonosítókat ne a #define direktívával, hanem az explicit típusú const kulcsszóval definiálni. jelzés (ez inkább a C ++-ra igaz):

const int MAX = 25;

(az int típus elhagyható, mivel alapértelmezés szerint be van állítva).

Ha a #define direktíva így néz ki:

#define identifier(azonosító, ..., azonosító) helyettesítés

és nincs szóköz az első azonosító és a nyitó zárójel között, akkor ez egy makró helyettesítő definíció argumentumokkal. Például egy olyan sor megjelenése után, mint:

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

utasítás READ(y); ugyanúgy kezeli, mint a scanf("%d",&y);. Itt a val egy argumentum, és a makró helyettesítése az argumentummal történik.

Ha a helyettesítésben vannak olyan hosszú definíciók, amelyek a következő sorban folytatódnak, akkor a következő sor végére egy \ karakter kerül.

Elhelyezhet objektumokat ## karakterrel elválasztva egy makródefinícióban, például:

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

Ezt követően a PR(a, 3) az a3 helyettesítést hívja meg. Vagy például egy makródefiníció

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

megváltoztatja z(sin, x, +, y) sin(x+y) értékre.

A makró argumentum előtt elhelyezett # szimbólum azt jelzi, hogy a rendszer karakterláncsá konvertálja. Például az irányelv után

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

a programszöveg következő töredéke

így van konvertálva:

printf("év""= %d", év);

Ismertessen más előfeldolgozó direktívákat. Az #include direktíva már korábban is megjelent. Kétféle formában használható:

#include "fájlnév"

#beleértve<имя файла>

Mindkét parancs hatása az, hogy a megadott nevű fájlokat tartalmazza a program. Az első betölt egy fájlt az aktuális vagy az előtagként megadott könyvtárból. A második parancs megkeresi a fájlt a programozási rendszerben meghatározott szabványos helyeken. Ha az idézőjelbe írt fájl nem található a megadott könyvtárban, akkor a keresés az #include parancshoz megadott alkönyvtárban folytatódik.<...>. Az #include direktívák egymásba ágyazhatók.

Az irányelvek következő csoportja lehetővé teszi a program egyes részeinek szelektív összeállítását. Ezt a folyamatot feltételes összeállításnak nevezik. Ez a csoport tartalmazza az #if, #else, #elif, #endif, #ifdef, #ifndef direktívákat. Az #if direktíva alapformája a következő:

#if állandó_kifejezés utasítás_sorrendje

Itt ellenőrizzük a konstans kifejezés értékét. Ha igaz, akkor az adott utasítássorozat végrehajtásra kerül, ha pedig hamis, akkor ez az állítássorozat kimarad.

Az #else direktíva művelete hasonló az else parancs műveletéhez a C nyelvben, például:

#if állandó_kifejezés

utasítás_sorrend_2

Itt, ha a konstans kifejezés igaz, akkor a szekvencia_of_operators_1, ha pedig hamis, akkor a szekvencia_of_operators_2 kerül végrehajtásra.

Az #elif direktíva "else if" típusú műveletet jelent. Használatának fő formája a következő:

#if állandó_kifejezés

állítás_sorrendje

#elif állandó_kifejezés_1

utasítás_sorrend_1

#elif állandó_kifejezés_n

állítások_szekvenciája_n

Ez a forma hasonló a form C nyelvi konstrukciójához: if...else if...else if...

Irányelv

#ifdef azonosító

beállítja, hogy a megadott azonosító aktuálisan definiálva van-e, pl. hogy benne volt-e a #define alakú direktívákban. Sor megtekintése

#ifndef azonosító

ellenőrzi, hogy a megadott azonosító jelenleg nincs-e definiálva. Ezen direktívák bármelyikét követheti tetszőleges számú szövegsor, amely esetleg tartalmazhat egy #else utasítást (az #elif nem használható), és az #endif sorral végződik. Ha az ellenőrzött feltétel igaz, akkor az #else és az #endif közötti összes sort figyelmen kívül hagyja, ha hamis, akkor a check és az #else közötti sorokat (ha nincs #else szó, akkor #endif). Az #if és #ifndef direktívák egymásba ágyazhatók.

Tekintse meg az irányelvet

#undef azonosító

a megadott azonosítót definiálatlannak tekinti, azaz. nem cserélhető.

Vegye figyelembe a példákat. A három irányelv a következő:

ellenőrizze, hogy a WRITE azonosító definiálva van-e (azaz #define WRITE... alakú parancs volt), és ha igen, akkor a WRITE nevet definiálatlannak tekinti, pl. nem cserélhető.

irányelveket

#define ÍRÁS fprintf

ellenőrizze, hogy a WRITE azonosító definiálatlan-e, és ha igen, akkor az fprintf név helyett a WRITE azonosító kerül meghatározásra.

Az #error direktíva a következő formában van írva:

#error error_message

Ha ez előfordul a program szövegében, akkor a fordítás leáll, és hibaüzenet jelenik meg a kijelzőn. Ezt a parancsot főleg a hibakeresési fázisban használják. Vegye figyelembe, hogy a hibaüzenetet nem kell idézőjelbe tenni.

A #line direktíva a C programozási rendszerben definiált _LINE_ és _FILE_ változók értékeinek megváltoztatására szolgál. A _LINE_ változó az éppen futó program sorszámát tartalmazza. A _FILE_ azonosító a fordítandó program nevét tartalmazó karakterláncra mutató mutató. A #line direktíva a következőképpen van írva:

#sorszám "fájlnév"

Itt a szám bármely pozitív egész szám, amely a _LINE_ változóhoz lesz hozzárendelve, a fájlnév pedig egy opcionális paraméter, amely felülírja a _FILE_ értékét.

A #pragma direktíva lehetővé teszi néhány utasítás átadását a fordítónak. Például a vonal

azt jelzi, hogy vannak assembly nyelvű karakterláncok egy C programban. Például:

Tekintsünk néhány globális azonosítót vagy makrónevet (makródefiníciók neveit). Öt ilyen név van meghatározva: _LINE_, _FILE_, _DATE_, _TIME_, _STDC_. Ezek közül kettőt (_LINE_ és _FILE_) már fentebb leírtunk. A _DATE_ azonosító egy karakterláncot ad meg, amely a forrásfájl objektumkódba fordításának dátumát tárolja. A _TIME_ azonosító egy karakterláncot ad meg, amely tárolja a forrásfájl objektumkódba fordításának idejét. Az _STDC_ makró értéke 1, ha szabványos makróneveket használnak. Ellenkező esetben ez a változó nem lesz definiálva.

Előfordul, hogy a program meghívásakor a parancssorból adatátvitelre kerül a program. Az ilyen adatokat parancssori argumentumoknak nevezzük. Így néz ki például:

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

Ez meghívja az a.out (az aktuális könyvtárból) és az ls (a PATH környezeti változóban megadott könyvtárból) programokat. Az első program egy szót kap a parancssorból - teszt.txt, a második - kettőt: -lt és /home/peter/.

Ha a program C-ben van írva, akkor az induláskor a vezérlés azonnal átkerül a main() függvényre, ezért ő kapja meg a változó paramétereihez rendelt parancssori argumentumokat.

Eddig úgy határoztuk meg a main() függvényt, hogy nem vesz fel semmilyen paramétert és nem ad vissza semmit. Valójában C-ben minden függvény alapértelmezés szerint (ha nincs más definiálva) egész számot ad vissza. Ez ellenőrizhető. Ha így írod a kódot:

main() ( printf("Szia \n") ; return 0 ; )

Ekkor a fordítás során nem történik figyelmeztetés vagy hiba. Ugyanez történik, ha int main() -t írunk. Ez bizonyítja, hogy az alapértelmezett függvény egy egész számot ad vissza, nem pedig semmit (void). Bár amit a függvény visszaad, az mindig "felülírható", például voidmain() vagy float main() .

Amikor egy programot parancssorból hívunk meg, mindig egy adatpár kerül átadásra:

  1. egész szám, a szavak (szóközökkel elválasztott elemek) számát jelöli a parancssorban híváskor,
  2. mutató a karakterláncok tömbjére, ahol minden sor egy szó a parancssorból.

Vegye figyelembe, hogy magát a program nevét is figyelembe veszi. Például, ha a hívás így néz ki:

./a.out 12 2. téma

Ekkor a program első argumentuma 4, és a karakterláncok tömbje a következőképpen van definiálva: (./a.out", "12", "theme", "2").

Ügyeljen a terminológiára, csak két program argumentum van (egy szám és egy tömb), de annyi parancssori argumentum, amennyit csak akar. A parancssori argumentumokat program argumentumaivá "lefordítják" (a main() függvény argumentumaivá).
Ezeket az adatokat (számot és mutatót) akkor is átadja a programnak, ha egyszerűen név szerint hívják anélkül, hogy bármit is átadnának neki: ./a.out. Ebben az esetben az első argumentum 1, a második argumentum pedig csak egy karakterláncból álló tömbre mutat (""./a.out").

Az a tény, hogy az adatok átadásra kerülnek a programnak, nem jelenti azt, hogy a main() függvénynek meg kell kapnia azokat. Ha a main() függvény paraméterek nélkül van definiálva, akkor a parancssori argumentumokhoz nem lehet hozzáférni. Bár semmi sem akadályozza meg, hogy elküldje őket. Nem történik hiba.

A programnak átadott adatokhoz való hozzáféréshez azokat változókhoz kell rendelni. Mivel az argumentumok azonnal átadódnak a main() -nak, a fejlécének így kell kinéznie:
fő (int n, char *arr)

Az első változó (n) a szavak számát, a második változó pedig egy karakterlánc-tömbre mutató mutatót tartalmaz. A második paraméter gyakran **arr-ként íródik. Ez azonban ugyanaz. Emlékezzünk vissza, hogy maga a karakterláncok tömbje elemként karakterláncokra mutató mutatókat tartalmaz. A függvényben pedig átadunk egy mutatót a tömb első elemére. Kiderül, hogy egy mutatót adunk át egy mutatónak, azaz. **arr.

Gyakorlat
Írj egy ilyen programot:

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

Meghíváskor kiírja a parancssorban lévő szavak számát, és minden szót egy új sorba. Hívja meg parancssori argumentumok nélkül és argumentumokkal.

A programban az argc és argv változó paramétereket használtuk. Szokásos csak ilyen neveket használni, de valójában bármi lehet. Jobb, ha betartja ezt a szabványt, hogy a programjai érthetőbbek legyenek nemcsak Önnek, hanem más programozóknak is.

Az adatok programnak való átadásának gyakorlati jelentősége

Ha van tapasztalata a GNU/Linux parancssorral kapcsolatban, tudja, hogy a legtöbb parancsnak vannak kapcsolói és argumentumai. Például a könyvtárak tartalmának megtekintésekor, másolásakor, mozgatásakor argumentumként adjuk meg azokat a fájlrendszer-objektumokat, amelyeken a parancs végrehajtásra kerül. Megvalósításának jellemzői kulcsok segítségével határozhatók meg. Például a parancsban

Cp -r ../les_1 ../les_101

cp a parancs neve, -r a kapcsoló, a ../les_1 és ../les_101 pedig a parancs argumentumai.

Általában a programok indításakor leggyakrabban a programvégrehajtási folyamat fájlcímei és "módosítói" (ezek a kulcsok) kerülnek átvitelre.

Írjunk egy programot, amely megnyitja a felhasználó által a parancssorban megadott fájlokat írásra vagy hozzáfűzésre, és oda írja (adja hozzá) ugyanazokat az információkat, amelyeket a felhasználó a program végrehajtása során a billentyűzetről beír:

#beleértve #beleértve main (int argc, char ** argv) ( int i, ch; FILE * f[5] ; if (argc< 3 || argc >7 ) ( tesz ( "Érvénytelen számú paraméter") ; visszatérés 1 ; ) if (strcmp (argv[ 1 ] , "-w" ) != 0 && strcmp (argv[ 1 ] , "-a" ) != 0 ) ( elhelyezi ( "Az első paraméter lehet -w vagy -a") ; visszatérés 2 ; ) for (i= 0 ; i< argc- 2 ; i++ ) { f[ i] = fopen (argv[ i+ 2 ] , argv[ 1 ] + 1 ) ; if (f[ i] == NULL) { printf ("A %s fájl nem nyitható meg\n", argv[ i+ 2 ] ) ; visszatérés 3 ; ) ) while ((ch = getchar () ) != EOF) for (i= 0 ; i< argc- 2 ; i++ ) putc (ch, f[ i] ) ; for (i= 0 ; i < argc- 2 ; i++ ) fclose (f[ i] ) ; return 0 ; }

Magyarázatok a kódhoz:

  1. Létrejön egy öt fájlmutatóból álló tömb. Ezért legfeljebb öt fájl nyitható meg egyszerre. Az első fájl fájlmutatója az f tömbelemben, a második - az f tömbelemben lesz tárolva, és így tovább.
  2. A parancssori argumentumok száma ellenőrzésre kerül. Legalább háromnak kell lennie, mert. az első a program neve, a második a fájl megnyitási módja, a harmadik az első vagy egyetlen fájl, amelybe írni kell. Mivel a program csak öt fájl megnyitását teszi lehetővé, a parancssori argumentumok száma nem haladhatja meg a hetet. Ezért, ha az argumentumok száma kevesebb, mint 3 vagy több, mint 7, akkor a program véget ér, mert A return utasítás hatására a függvény kilép, még akkor is, ha több kód van utána. A 0-val nem egyenlő függvény visszatérési értéke a szülőfolyamat által úgy értelmezhető, mint egy üzenet, hogy a program hibával fejezte be.
  3. A második parancssori argumentum helyességét ellenőrzi. Ha nem "-w" és nem "-a", akkor a második if feltételes kifejezése 1-et (igaz) ad vissza. Az strcmp() függvény lehetővé teszi a karakterláncok összehasonlítását, és 0-t ad vissza, ha egyenlők.
  4. A for ciklus megnyitja a megadott címeken lévő fájlokat, amelyek az argv tömb harmadik elemétől kezdődnek. Ezért adunk 2-t az i-hez, hogy megkapjuk az argv tömb elemeit, a harmadiktól kezdve. Az argc-2 kifejezés az átadott fájlnevek számát jelzi; mert Az argc a parancssori argumentumok teljes számát tárolja, amelyek közül az első kettő nem fájlnév.
  5. Az argv+1 kifejezés lehetővé teszi a "w" (vagy "a") részkarakterlánc kivágását a "-w" (vagy "-a") karakterláncból, mert Az argv lényegében egy mutató a karakterlánc első elemére. Ha hozzáadunk egyet a mutatóhoz, azt a tömb következő elemére toljuk.
  6. Ha a fájl nem nyitható meg, az fopen() függvény NULL-t ad vissza. Ebben az esetben a program véget ér.
  7. A felhasználó által a billentyűzetről beírt minden karakter beírásra kerül az összes megnyitott fájlba.
  8. A végén a fájlok bezáródnak.