Borland C++ obsługuje trzy argumenty main(). Pierwsze dwa to tradycyjne argc i argv. To jedyne argumenty główne funkcje(), zdefiniowane przez standard ANSI C. Pozwalają na przekazywanie do programu argumentów wiersza poleceń. Argumenty wiersza poleceń to informacje następujące po nazwie programu w wiersz poleceń system operacyjny. Na przykład, gdy program jest kompilowany za pomocą wbudowanego kompilatora Borland, zwykle wpisuje się bcc Nazwa programu

Gdzie Nazwa programu to program, który ma zostać skompilowany. Nazwa programu jest przekazywana do kompilatora jako argument.

Parametr argc zawiera liczbę argumentów wiersza poleceń i jest liczbą całkowitą. Zawsze wynosi co najmniej 1, ponieważ nazwa programu jest kwalifikowana jako pierwszy argument. Parametr argv jest wskaźnikiem do tablicy wskaźników znakowych. Każdy element tej tablicy wskazuje na argument wiersza poleceń. Wszystkie argumenty wiersza poleceń są ciągami. Wszystkie liczby są konwertowane przez program na format wewnętrzny. Poniższy program drukuje „Hello”, a następnie nazwę użytkownika, jeśli zostanie wpisana zaraz po nazwie programu:

#włączać

{
jeśli(argc!=2)
{
printf("Zapomniałeś wpisać swoje imię\n");
powrót 1;
}
printf("Witaj %s", argv);
zwróć 0;
}

Jeśli zostaniesz wywołany ten program name, a nazwa użytkownika to Sergey, aby uruchomić program należy wpisać:
imię Siergiej.
W wyniku programu pojawi się:
Witaj Siergiej.

Argumenty wiersza poleceń muszą być oddzielone spacjami lub tabulatorami. Przecinki, średniki i podobne znaki nie są uważane za separatory. Na przykład:

Składa się z trzech linii, podczas gdy

Zioło, Rick, Fred

To jest jedna linia - przecinki nie są ogranicznikami.

Jeśli chcesz przekazać ciąg zawierający spacje lub tabulatory jako pojedynczy argument, umieść go w podwójne cudzysłowy. Na przykład jest to jeden argument:

"to jest test"

Ważne jest, aby poprawnie zadeklarować argv. Najbardziej typowa metoda to:

Puste nawiasy wskazują, że tablica nie ma stałej długości. Możesz uzyskać dostęp do poszczególnych elementów za pomocą indeksowania argv. Na przykład argv wskazuje na pierwszą linię, która zawsze zawiera nazwę programu. argv wskazuje na następny wiersz i tak dalej.

Poniżej znajduje się mały przykład użycia argumentów wiersza poleceń. Odlicza od wartości określonej w wierszu poleceń i emituje sygnał po osiągnięciu zera. Zauważ, że pierwszy argument zawiera liczbę przekonwertowaną na liczbę całkowitą przy użyciu standardowej funkcji atoi(). Jeśli jako drugi argument występuje ciąg "display", to sam licznik zostanie wyświetlony na ekranie.

/* program liczący */

#włączać
#włączać
#włączać
int main(int argc, char *argv)
{
int disp, liczyć;
if(argc<2)
{
printf("Musisz podać długość licznika\n");
printf("w wierszu poleceń. Spróbuj ponownie.\n");
powrót 1;
}
if (argc==3 && !strcmp(argv,"wyświetlanie")) disp = 1;
w przeciwnym razie disp = 0;
for(liczba=atoi(argv); ilość; -liczba)
if (disp) printf("%d", liczba);
printf("%c", "\a"); /* na większości komputerów to jest połączenie */
zwróć 0;
}

Zauważ, że jeśli nie podano żadnych argumentów, pojawi się komunikat o błędzie. Jest to najbardziej typowe dla programów, które używają argumentów wiersza poleceń do wydawania instrukcji, jeśli podjęto próbę uruchomienia programu bez poprawnych informacji.

Aby uzyskać dostęp do poszczególnych znaków wiersza poleceń, dodaj drugi indeks do argv. Na przykład poniższy program wypisuje wszystkie argumenty, z którymi został wywołany, po jednym znaku na raz:

#włączać
int main(int argc, char *argv)
{
int t, ja;
dla(t=0; t {
i = 0;
while(argv[t][i])
{
printf("%c", argv[t][i]);
}
printf(");
}
zwróć 0;
}

Należy pamiętać, że pierwszy indeks służy do dostępu do napisu, a drugi do dostępu do znaku napisu.

Zazwyczaj argc i argv są używane do pobierania poleceń źródłowych. Teoretycznie możesz mieć do 32767 argumentów, ale większość systemów operacyjnych nawet nie pozwala się do tego zbliżyć. Zazwyczaj te argumenty są używane do określenia nazwy pliku lub opcji. Użycie argumentów wiersza poleceń nadaje programowi profesjonalny wygląd i umożliwia używanie programu w plikach wsadowych.

Jeśli dołączysz plik WILDARGS.OBJ dostarczony z Borland C++, możesz użyć symboli wieloznacznych w argumentach typu *.EXE. (Borland C++ obsługuje wzorce automatycznie i odpowiednio zwiększa argc.) Na przykład, jeśli połączysz WILDARGS.OBJ z następującym programem, wypisze, ile plików pasuje do nazwy pliku podanej w wierszu poleceń:

/* Połącz ten program z WILDARGS.OBJ */

#włączać
int main(int argc, char *argv)
{
zarejestruj się w i;
printf("%d pliki pasują do podanej nazwy\n", argc-1);
printf("Są to: ");
dla(i=1; i printf("%s", argv[i]);
zwróć 0;
}

Jeśli nazwiemy ten program WA, a następnie uruchomimy go w następujący sposób, otrzymamy liczbę plików, które mają rozszerzenie EXE, oraz listę nazw tych plików:

Oprócz argc i argv, Borland C++ dostarcza również trzeci argument wiersza poleceń -env. Parametr env umożliwia programowi dostęp do informacji o środowisku systemu operacyjnego. Parametr env musi następować po argc i argv i jest deklarowany w następujący sposób:

Jak widać, env jest deklarowane w taki sam sposób jak argv. Podobnie jak argv, jest to wskaźnik do tablicy łańcuchów. Każda linia to łańcuch środowiskowy zdefiniowany przez system operacyjny. Parametr env nie ma odpowiednika parametru argc, który mówi, ile jest wierszy środowiska. Zamiast tego ostatni wiersz środowiska ma wartość null. Poniższy program drukuje wszystkie łańcuchy środowiskowe aktualnie zdefiniowane w systemie operacyjnym:

/* ten program wypisuje wszystkie wiersze środowiska */

#włączać
int main(int argc, char *argv, char *env)
{
int t;
for(t=0; env[t]/ t++)
printf("%s\n", env[t]);
zwróć 0;
}

Zauważ, że chociaż argc i argv nie są używane przez program, muszą być obecne na liście parametrów. C nie zna nazw parametrów. Zamiast tego ich użycie zależy od kolejności deklarowania parametrów. W rzeczywistości możesz nazwać parametr, jak chcesz. Ponieważ argc, argv i env są nazwami tradycyjnymi, najlepiej jest ich nadal używać, aby każdy czytający program mógł natychmiast rozpoznać, że są to argumenty funkcji main().

W przypadku programów typowym zadaniem jest znalezienie wartości zdefiniowanej w ciągu środowiska. Na przykład zawartość ciągu PATH umożliwia programom korzystanie ze ścieżek wyszukiwania. Poniższy program demonstruje, jak znaleźć ciągi, które deklarują standardowe ścieżki wyszukiwania. Używa standardowej funkcji bibliotecznej strstr(), która ma następujący prototyp:

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

Funkcja strstr() szuka łańcucha wskazywanego przez str1 w łańcuchu wskazywanym przez str2. Jeśli taki ciąg zostanie znaleziony, zwracany jest wskaźnik do pierwszej pozycji. Jeśli nie zostanie znalezione żadne dopasowanie, funkcja zwraca NULL.

/* program przeszukuje łańcuchy środowiskowe w poszukiwaniu łańcucha zawierającego PATH */

#włączać
#włączać
int main (int argc, char *argv, char *env)
{
int t;
for(t=0; env[t]; t++)
{
if(strstr(śr[t], "ŚCIEŻKA"))
printf("%s\n", env[t]);
}
zwróć 0;
}

Podczas tworzenia aplikacji konsolowej w języku programowania C++ automatycznie tworzona jest linia bardzo podobna do tej:

int main(int argc, char* argv) // parametry funkcji main()

Ta linia jest nagłówkiem funkcji głównej main() , parametry argс i argv są zadeklarowane w nawiasach. Tak więc, jeśli program jest uruchamiany z wiersza poleceń, możliwe jest przesłanie do tego programu dowolnych informacji, do tego są parametry argc i argv. Parametr argc jest typu danych int i zawiera liczbę parametrów przekazanych do funkcji main. Co więcej, argc jest zawsze co najmniej 1, nawet jeśli nie przekazujemy żadnych informacji, ponieważ nazwa funkcji jest uważana za pierwszy parametr. Parametr argv to tablica wskaźników do łańcuchów. W wierszu poleceń można przekazywać tylko dane typu łańcuchowego. Wskaźniki i napisy to dwa duże tematy, dla których utworzono osobne sekcje. Tak więc poprzez parametr argv przesyłane są wszelkie informacje. Stwórzmy program, który uruchomimy z wiersza poleceń Windows i przekażemy do niego pewne informacje.

// argc_argv.cpp: określa punkt wejścia dla aplikacji konsolowej. #include "stdafx.h" #include używając standardowej przestrzeni nazw; int main(int argc, char* argv) ( if (argc ><< argv<

// kod Kod::Bloki

// kod Dev-C++

// argc_argv.cpp: określa punkt wejścia dla aplikacji konsolowej. #włączać używając standardowej przestrzeni nazw; int main(int argc, char* argv) ( if (argc > 1)// jeśli przekażemy argumenty, to argc będzie większe niż 1 (w zależności od liczby argumentów) ( cout<< argv<

Po debugowaniu programu otwórz wiersz poleceń systemu Windows i przeciągnij plik wykonywalny naszego programu do okna wiersza poleceń, pełna ścieżka do programu zostanie wyświetlona w wierszu poleceń (ale możesz ręcznie wpisać ścieżkę do programu), po że możesz nacisnąć WEJŚĆ i program się uruchomi (patrz rysunek 1).

Rysunek 1 - Parametry funkcji głównej

Ponieważ właśnie uruchomiliśmy program i nie przekazaliśmy do niego żadnych argumentów, pojawił się komunikat Not arguments. Rysunek 2 pokazuje uruchomienie tego samego programu z wiersza poleceń, ale z przekazanym argumentem Open.

Rysunek 2 - Parametry funkcji głównej

Argumentem jest słowo Open , jak widać na rysunku, słowo to pojawiło się na ekranie. Możesz przekazać kilka parametrów jednocześnie, oddzielając je przecinkiem. Jeśli konieczne jest przekazanie parametru składającego się z kilku słów, należy je ująć w cudzysłów, a wtedy słowa te będą traktowane jako jeden parametr. Na przykład rysunek pokazuje uruchomienie programu, przekazując mu argument składający się z dwóch słów - To działa .

Rysunek 3 - Parametry funkcji głównej

A jeśli usuniesz cytaty. Wtedy zobaczymy tylko słowo To. Jeśli nie planujesz przekazywać żadnych informacji podczas uruchamiania programu, możesz usunąć argumenty w funkcji main(), możesz również zmienić nazwy tych argumentów. Czasami dochodzi do modyfikacji parametrów argc i argv, ale wszystko zależy od typu tworzonej aplikacji lub środowiska programistycznego.

Podczas automatycznego tworzenia aplikacji konsolowej w języku programowania C++ automatycznie tworzona jest funkcja main, która jest bardzo podobna do tej:

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

Nagłówek funkcji zawiera podpis funkcji głównej main() z argumentami argc i argv .
Jeśli program jest uruchamiany z wiersza poleceń, możliwe jest przesłanie do tego programu dowolnych informacji. Do tego służą argumenty wiersza poleceń argc i argv.
Parametr argc jest typu int i zawiera liczbę parametrów przekazanych do funkcji main. Co więcej, argc jest zawsze co najmniej 1, nawet jeśli do funkcji main nie są przekazywane żadne informacje, ponieważ nazwa aplikacji jest uważana za pierwszy parametr.
Parametr argv to tablica wskaźników do łańcuchów. W wierszu poleceń można przekazywać tylko dane typu łańcuchowego.

Uruchamiając program za pomocą wiersza poleceń systemu Windows, możesz przekazać do niego pewne informacje. W takim przypadku linia poleceń będzie wyglądać tak:
Dysk:\ścieżka\nazwa.exe argument1 argument2 ...

Argumenty wiersza poleceń są oddzielone co najmniej jedną spacją.

Argument argv zawiera w pełni kwalifikowaną nazwę aplikacji:

#włączać
używając standardowej przestrzeni nazw;

Cout<< argv << endl;

zwróć 0;
}

Wynik wykonania

Przykład: obliczanie iloczynu dwóch liczb całkowitych
Program używa ciągu do funkcji konwersji liczb całkowitych StrToInt() stąd .

#włączać
używając standardowej przestrzeni nazw;
int StrToInt(znak*s) (…)
int main(int argc, char * argv) (

Int a = 0, b = 0;

Jeśli (argc > 1)

a = StrToInt(argv);

Jeśli (argc > 2)

b = StrToInt(argv);

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

zwróć 0;
}

Program jest uruchamiany jako

Wynik wykonania

Debugowanie programu za pomocą argumentów wiersza poleceń

Aby przekazać argumenty wiersza poleceń podczas debugowania programu, musisz uzyskać dostęp do menu Nieruchomości projekt.


Na karcie Właściwości konfiguracyjne -> Debugowanie wybierać Argumenty poleceń i ustal ich wartości.

Po uruchomieniu programu w trybie debugowania wprowadzone argumenty będą traktowane przez program jako argumenty wiersza poleceń.

Możesz przekazać pewne argumenty do programów w C. Gdy main() jest wywoływana na początku obliczeń, przekazywane są do niego trzy parametry. Pierwszy z nich określa liczbę argumentów komendy podczas dostępu do programu. Drugi to tablica wskaźników do łańcuchów znaków zawierających te argumenty (jeden argument na łańcuch). Trzecia to również tablica wskaźników do ciągów znaków, służy do uzyskiwania dostępu do parametrów systemu operacyjnego (zmiennych środowiskowych).

Każda taka linia jest reprezentowana jako:

zmienna = wartość\0

Ostatnią linię można znaleźć po dwóch końcowych zerach.

Nazwijmy odpowiednio argumenty funkcji main(): argc, argv i env (możliwe są dowolne inne nazwy). Wtedy dozwolone są następujące opisy:

main(int argc, char *argv)

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

Załóżmy, że na dysku A: znajduje się jakiś program prog.exe. Zajmijmy się tym tak:

A:\>prog.exe plik1 plik2 plik3

Wtedy argv jest wskaźnikiem do łańcucha A:\prog.exe, argv jest wskaźnikiem do pliku łańcucha1 i tak dalej. Na pierwszy rzeczywisty argument wskazuje argv, a na ostatni argv. Jeśli argc=1, to w wierszu poleceń po nazwie programu nie ma żadnych parametrów. W naszym przykładzie argc=4.

rekurencja

Rekurencja to metoda wywoływania, w której funkcja wywołuje samą siebie.

Ważnym punktem w kompilacji programu rekurencyjnego jest organizacja wyjścia. Łatwo tu popełnić błąd, że funkcja będzie konsekwentnie wywoływać siebie w nieskończoność. Dlatego proces rekurencyjny musi krok po kroku uprościć problem, aby w końcu pojawiło się dla niego rozwiązanie nierekurencyjne. Korzystanie z rekurencji nie zawsze jest pożądane, ponieważ może prowadzić do przepełnienia stosu.

Funkcje biblioteczne

W systemach programowania podprogramy do rozwiązywania typowych problemów są łączone w biblioteki. Zadania te obejmują: obliczanie funkcji matematycznych, wprowadzanie/wyprowadzanie danych, przetwarzanie łańcuchów, interakcję z narzędziami systemu operacyjnego itp. Zastosowanie procedur bibliotecznych oszczędza użytkownikowi konieczności rozwijania odpowiednich narzędzi i zapewnia mu dodatkową usługę. Funkcje zawarte w bibliotekach dostarczane są z systemem programowania. Ich deklaracje podawane są w plikach *.h (są to tzw. pliki dołączane lub nagłówkowe). Dlatego jak wspomniano powyżej, na początku programu z funkcjami bibliotecznymi powinny znajdować się wiersze typu:

#włączać<включаемый_файл_типа_h>

Na przykład:

#włączać

Istnieją również udogodnienia do rozbudowy i tworzenia nowych bibliotek z programami użytkownika.

Zmiennym globalnym przypisuje się stałe miejsce w pamięci na czas trwania programu. Zmienne lokalne są przechowywane na stosie. Pomiędzy nimi znajduje się obszar pamięci do dynamicznej alokacji.

Funkcje malloc() i free() służą do dynamicznego przydzielania wolnej pamięci. Funkcja malloc() alokuje pamięć, funkcja free() ją zwalnia. Prototypy tych funkcji są przechowywane w pliku nagłówkowym stdlib.h i wyglądają tak:

void *malloc(rozmiar_rozmiar);

nieważne *wolne(nieważne *p);

Funkcja malloc() zwraca wskaźnik typu void; w celu prawidłowego użycia wartość funkcji musi zostać przekonwertowana na wskaźnik do odpowiedniego typu. Po pomyślnym zakończeniu funkcja zwraca wskaźnik do pierwszego bajta wolnej pamięci o rozmiarze size. Jeśli nie ma wystarczającej ilości pamięci, zwracana jest wartość 0. Operacja sizeof() służy do określenia liczby bajtów potrzebnych dla zmiennej.

Przykład wykorzystania tych funkcji:

#włączać

#włączać

p = (int *) malloc (100 * sizeof(int)); /* Przydziel pamięć na 100

liczby całkowite */

printf("Brak pamięci\n");

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

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

wolny(p); /* Wolna pamięć */

Przed użyciem wskaźnika zwróconego przez malloc() musisz upewnić się, że jest wystarczająco dużo pamięci (wskaźnik nie jest pusty).

Preprocesor

Preprocesor C to program przetwarzający dane wejściowe kompilatora. Preprocesor patrzy na program źródłowy i wykonuje następujące czynności: podłącza do niego podane pliki, dokonuje podstawień, a także zarządza warunkami kompilacji. Preprocesor jest przeznaczony dla linii programu, które zaczynają się od symbolu #. W jednym wierszu dozwolone jest tylko jedno polecenie (dyrektywa preprocesora).

Dyrektywa

#define podstawienie identyfikatora

powoduje, że następujący tekst programu zastępuje nazwany identyfikator tekstem podstawienia (zwróć uwagę na brak średnika na końcu tego polecenia). Zasadniczo dyrektywa ta wprowadza definicję makra (makro), gdzie „identyfikator” to nazwa definicji makra, a „podstawienie” to sekwencja znaków, którą preprocesor zastępuje określoną nazwę, gdy znajdzie ją w tekście programu. Nazwa makra jest zwykle pisana wielkimi literami.

Rozważ przykłady:

Pierwsza linia powoduje, że program zastępuje identyfikator MAX stałą 25. Druga pozwala na użycie w tekście zamiast otwierającego nawiasu klamrowego (() słowa BEGIN.

Należy zauważyć, że ponieważ preprocesor nie sprawdza zgodności między symbolicznymi nazwami definicji makr a kontekstem, w którym są one używane, zaleca się, aby takie identyfikatory były definiowane nie dyrektywą #define, ale słowem kluczowym const z określonym typem wskazanie (jest to bardziej prawdziwe dla C++):

const int MAX = 25;

(typ int można pominąć, ponieważ jest ustawiony domyślnie).

Jeśli dyrektywa #define wygląda tak:

#define identyfikator(identyfikator, ..., identyfikator) podstawienie

i nie ma spacji między pierwszym identyfikatorem a otwierającym nawiasem, to jest to definicja podstawienia makra z argumentami. Na przykład po pojawieniu się linii typu:

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

oświadczenie CZYTAJ(y); jest traktowane tak samo jak scanf("%d",&y);. Tutaj val jest argumentem, a podstawienie makra jest wykonywane za pomocą tego argumentu.

Jeśli w podstawieniu znajdują się długie definicje, które są kontynuowane w następnym wierszu, znak \ jest umieszczany na końcu następnego kontynuowanego wiersza.

W definicji makra można umieszczać obiekty oddzielone znakami ##, na przykład:

#zdefiniuj PR(x, y) x##y

Następnie PR(a, 3) ogłosi zmianę a3. Lub na przykład definicja makra

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

zmieni z(sin, x, +, y) na sin(x+y).

Znak # umieszczony przed argumentem makra wskazuje, że jest on konwertowany na ciąg. Na przykład po dyrektywie

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

kolejny fragment tekstu programu

jest konwertowany w ten sposób:

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

Opiszmy inne dyrektywy preprocesora. Dyrektywa #include była widziana już wcześniej. Może być stosowany w dwóch formach:

#include "nazwa pliku"

#włączać<имя файла>

Efektem obu poleceń jest włączenie do programu plików o określonej nazwie. Pierwszy ładuje plik z bieżącego katalogu lub katalogu określonego jako prefiks. Drugie polecenie wyszukuje plik w standardowych lokalizacjach zdefiniowanych w systemie programowania. Jeśli plik, którego nazwa jest zapisana w cudzysłowach, nie zostanie znaleziony w określonym katalogu, wyszukiwanie będzie kontynuowane w podkatalogach określonych dla polecenia #include<...>. Dyrektywy #include mogą być zagnieżdżane w sobie.

Kolejna grupa dyrektyw pozwala na selektywne kompilowanie części programu. Ten proces nazywa się kompilacją warunkową. Ta grupa obejmuje dyrektywy #if, #else, #elif, #endif, #ifdef, #ifndef. Podstawowa forma dyrektywy #if to:

#if constant_expression instrukcja_sekwencji

Tutaj sprawdzana jest wartość wyrażenia stałego. Jeśli jest prawdziwy, to wykonywana jest dana sekwencja poleceń, a jeśli jest fałszem, to ta sekwencja poleceń jest pomijana.

Działanie dyrektywy #else jest podobne do działania polecenia else w języku C, na przykład:

#jeśli stałe_wyrażenie

statement_sequence_2

Tutaj, jeśli wyrażenie stałe jest prawdziwe, wykonywana jest sekwencja_operatorów_1, a jeśli jest fałszem, wykonywana jest sekwencja_operatorów_2.

Dyrektywa #elif oznacza akcję typu „inaczej, jeśli”. Główną formą jego użycia jest:

#jeśli stałe_wyrażenie

instrukcja_sekwencji

#elif constant_expression_1

statement_sequence_1

#elif stałe_wyrażenie_n

sekwencja_wypowiedzi_n

Ta forma jest podobna do konstrukcji języka C formy: if...else if...else if...

Dyrektywa

#ifdef identyfikator

ustawia, czy podany identyfikator jest aktualnie zdefiniowany, tj. czy został uwzględniony w dyrektywach postaci #define. Zobacz linię

#ifndef identyfikator

sprawdza, czy podany identyfikator jest aktualnie niezdefiniowany. Po każdej z tych dyrektyw może następować dowolna liczba wierszy tekstu, prawdopodobnie zawierająca instrukcję #else (nie można użyć #elif) i kończącą się wierszem #endif. Jeśli sprawdzany warunek jest prawdziwy, wszystkie wiersze między #else i #endif są ignorowane, a jeśli false, to wiersze między sprawdzaniem i #else (jeśli nie ma słowa #else, to #endif). Dyrektywy #if i #ifndef mogą być zagnieżdżone jedna w drugiej.

Zobacz dyrektywę

#identyfikator undef

powoduje, że podany identyfikator jest uważany za niezdefiniowany, tj. niewymienne.

Rozważ przykłady. Trzy dyrektywy to:

sprawdź czy identyfikator WRITE jest zdefiniowany (tzn. było poleceniem postaci #define WRITE...), a jeśli tak, to nazwa WRITE jest uznawana za niezdefiniowaną, tj. niewymienne.

dyrektywy

#define NAPISZ fprintf

sprawdź, czy identyfikator WRITE nie jest zdefiniowany, a jeśli tak, to zamiast nazwy fprintf określany jest identyfikator WRITE.

Dyrektywa #error ma następującą postać:

#error error_message

Jeśli wystąpi w tekście programu, kompilacja zostanie zatrzymana, a na ekranie wyświetlacza pojawi się komunikat o błędzie. To polecenie jest używane głównie w fazie debugowania. Zauważ, że komunikat o błędzie nie musi być ujęty w podwójny cudzysłów.

Dyrektywa #line ma na celu zmianę wartości zmiennych _LINE_ i _FILE_ zdefiniowanych w systemie programowania C. Zmienna _LINE_ zawiera numer wiersza aktualnie wykonywanego programu. Identyfikator _FILE_ jest wskaźnikiem do ciągu znaków z nazwą kompilowanego programu. Dyrektywa #line jest napisana w następujący sposób:

#line number "nazwa pliku"

Tutaj liczba jest dowolną dodatnią liczbą całkowitą, która zostanie przypisana do zmiennej _LINE_, nazwa pliku jest parametrem opcjonalnym, który zastępuje wartość _FILE_.

Dyrektywa #pragma pozwala na przekazanie niektórych instrukcji do kompilatora. Na przykład linia

wskazuje, że w programie C występują łańcuchy języka asemblerowego. Na przykład:

Rozważ kilka globalnych identyfikatorów lub nazw makr (nazwy definicji makr). Zdefiniowano pięć takich nazw: _LINE_, _FILE_, _DATE_, _TIME_, _STDC_. Dwa z nich (_LINE_ i _FILE_) zostały już opisane powyżej. Identyfikator _DATE_ określa ciąg, który przechowuje datę przetłumaczenia pliku źródłowego na kod wynikowy. Identyfikator _TIME_ określa ciąg, który przechowuje czas, w którym plik źródłowy został przetłumaczony na kod wynikowy. Makro _STDC_ ma wartość 1, jeśli używane są standardowe nazwy makr. W przeciwnym razie ta zmienna nie zostanie zdefiniowana.

Zdarza się, że dane są przesyłane do programu z wiersza poleceń podczas jego wywołania. Takie dane nazywane są argumentami wiersza poleceń. Wygląda to na przykład tak:

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

Wywołuje to programy a.out (z bieżącego katalogu) i ls (z tego samego katalogu określonego w zmiennej środowiskowej PATH). Pierwszy program z wiersza poleceń otrzymuje jedno słowo - test.txt, drugi - dwa: -lt i /home/peter/.

Jeśli program jest napisany w C, to po uruchomieniu sterowanie jest natychmiast przekazywane do funkcji main(), dlatego to ona otrzymuje argumenty wiersza poleceń, które są przypisane do jej parametrów zmiennych.

Do tej pory zdefiniowaliśmy funkcję main() tak, jakby nie pobierała żadnych parametrów i niczego nie zwracała. W rzeczywistości w C każda funkcja domyślnie (jeśli nic innego nie jest zdefiniowane) zwraca liczbę całkowitą. Można to zweryfikować. Jeśli piszesz kod w ten sposób:

main() ( printf("Cześć \n") ; zwróć 0 ; )

Wtedy podczas kompilacji nie pojawi się żadne ostrzeżenie ani błąd. To samo stanie się, jeśli napiszemy int main() . Dowodzi to, że funkcja domyślna zwraca liczbę całkowitą, a nie nic (pustka). Chociaż to, co zwraca funkcja, zawsze może być „przesłonięte”, na przykład voidmain() lub float main() .

Kiedy program jest wywoływany z wiersza poleceń, zawsze przekazywana jest do niego para danych:

  1. liczba całkowita, oznaczający liczbę słów (elementów oddzielonych spacjami) w wierszu poleceń po wywołaniu,
  2. wskaźnik do tablicy ciągów, gdzie każdy wiersz jest pojedynczym słowem z wiersza poleceń.

Zauważ, że sama nazwa programu jest również brana pod uwagę. Na przykład, jeśli połączenie wygląda tak:

./a.out 12 motyw 2

Wtedy pierwszym argumentem programu jest 4, a tablica ciągów jest zdefiniowana jako ("./a.out", "12", "theme", "2").

Zwróć uwagę na terminologię, istnieją tylko dwa argumenty programu (liczba i tablica), ale tyle argumentów wiersza poleceń, ile chcesz. Argumenty wiersza poleceń są "tłumaczone" na argumenty programu (na argumenty funkcji main()).
Te dane (liczba i wskaźnik) są przekazywane do programu nawet wtedy, gdy są po prostu wywoływane przez nazwę bez przekazywania do niego niczego: ./a.out. W tym przypadku pierwszym argumentem jest 1, a drugi argument wskazuje tablicę tylko jednego ciągu (""./a.out").

Fakt, że dane są przekazywane do programu, nie oznacza, że ​​funkcja main() powinna je otrzymać. Jeśli funkcja main() jest zdefiniowana bez parametrów, nie można uzyskać dostępu do argumentów wiersza poleceń. Chociaż nic nie stoi na przeszkodzie, aby je wysłać. Nie wystąpi żaden błąd.

Aby uzyskać dostęp do danych przekazywanych do programu, należy je przypisać do zmiennych. Ponieważ argumenty są natychmiast przekazywane do funkcji main() , jej nagłówek powinien wyglądać tak:
main (int n, char *arr)

Pierwsza zmienna (n) zawiera liczbę słów, a druga zmienna zawiera wskaźnik do tablicy łańcuchów. Często drugi parametr jest zapisywany jako **arr . Jest jednak tak samo. Przypomnij sobie, że sama tablica ciągów zawiera wskaźniki do ciągów jako swoich elementów. A w funkcji przekazujemy wskaźnik do pierwszego elementu tablicy. Okazuje się, że przekazujemy wskaźnik do wskaźnika, czyli **przyp.

Ćwiczenie
Napisz taki program:

#włączać int main(int argc, char ** argv) ( int i; printf ("%d \n", argc); dla (i= 0 ; i< argc; i++ ) puts (argv[ i] ) ; }

Wypisuje liczbę słów w wierszu poleceń, gdy jest wywoływana, a każde słowo w nowym wierszu. Wywołaj to bez argumentów wiersza poleceń iz argumentami.

W programie użyliśmy zmiennych parametrów argc i argv. Zwyczajowo używa się właśnie takich nazw, ale w rzeczywistości mogą to być dowolne. Lepiej trzymać się tego standardu, aby Twoje programy były bardziej zrozumiałe nie tylko dla Ciebie, ale także dla innych programistów.

Praktyczne znaczenie przekazywania danych do programu

Jeśli masz doświadczenie z wierszem poleceń GNU/Linux, wiesz, że większość poleceń ma przełączniki i argumenty. Na przykład podczas przeglądania zawartości katalogów, kopiowania, przenoszenia, obiekty systemu plików, na których wykonywane jest polecenie, są określane jako argumenty. Cechy jego realizacji określa się za pomocą kluczy. Na przykład w poleceniu

Cp -r ../les_1 ../les_101

cp to nazwa polecenia, -r to przełącznik, a ../les_1 i ../les_101 to argumenty polecenia.

Generalnie najczęściej podczas uruchamiania programów przekazywane są adresy plików i „modyfikatory” (są to klucze) procesu wykonywania programu.

Napiszmy program, który otwiera pliki określone przez użytkownika w wierszu poleceń do zapisu lub dołączania i zapisuje (dodaje) tam te same informacje, które użytkownik wprowadza z klawiatury podczas wykonywania programu:

#włączać #włączać main (int argc, char ** argv) ( int i, ch; PLIK * f[ 5 ] ; if (argc< 3 || argc >7) ( stawia ( „Nieprawidłowa liczba parametrów”) ; powrót 1 ; ) if (strcmp (argv[ 1 ] , "-w" ) != 0 && strcmp (argv[ 1 ] , "-a" ) != 0 ) ( puts ( "Pierwszym parametrem może być -w lub -a") ; powrót 2 ; ) dla (i= 0 ; i< argc- 2 ; i++ ) { f[ i] = fopen (argv[ i+ 2 ] , argv[ 1 ] + 1 ) ; if (f[ i] == NULL) { printf ("Plik %s nie może być otwarty\n ", argv[ i+ 2 ] ); powrót 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 ; }

Wyjaśnienia do kodu:

  1. Tworzona jest tablica pięciu wskaźników plików. Dlatego jednocześnie nie można otworzyć więcej niż pięciu plików. Wskaźnik pierwszego pliku będzie przechowywany w elemencie tablicy f, drugi - w f i tak dalej.
  2. Sprawdzana jest liczba argumentów wiersza poleceń. Musi być ich co najmniej trzech, ponieważ. pierwszy to nazwa programu, drugi to tryb otwierania pliku, trzeci to pierwszy lub jedyny plik do zapisu. Ponieważ program pozwala otworzyć tylko pięć plików, łączna liczba argumentów wiersza poleceń nie może przekroczyć siedmiu. Dlatego jeśli liczba argumentów jest mniejsza niż 3 lub większa niż 7, program kończy się, ponieważ Instrukcja return powoduje zamknięcie funkcji, nawet jeśli po niej jest więcej kodu. Wartość zwracana przez funkcję, która nie jest równa 0, może zostać zinterpretowana przez proces nadrzędny jako komunikat, że program zakończył działanie z błędem.
  3. Sprawdzana jest poprawność drugiego argumentu wiersza poleceń. Jeśli nie jest to ani "-w", ani "-a", to wyrażenie warunkowe w drugim if zwraca 1 (prawda). Funkcja strcmp() umożliwia porównywanie ciągów i zwraca 0, jeśli są równe.
  4. Pętla for otwiera pliki pod określonymi adresami, które zaczynają się od trzeciego elementu tablicy argv. Dlatego do i dodaje się 2, aby uzyskać elementy tablicy argv, zaczynając od trzeciego. Wyrażenie argc-2 wskazuje liczbę przekazanych nazw plików; dlatego argc przechowuje całkowitą liczbę argumentów wiersza poleceń, z których pierwsze dwa nie są nazwami plików.
  5. Wyrażenie argv+1 pozwala "wyciąć" podłańcuch "w" (lub "a") z łańcucha "-w" (lub "-a"), ponieważ argv jest zasadniczo wskaźnikiem do pierwszego elementu ciągu. Dodając jeden do wskaźnika, przesuwamy go do następnego elementu w tablicy.
  6. Jeśli plik nie może zostać otwarty, funkcja fopen() zwraca NULL. W takim przypadku program się kończy.
  7. Każdy znak wprowadzony przez użytkownika z klawiatury jest zapisywany we wszystkich otwartych plikach.
  8. Na koniec akta są zamykane.