CPP (preprocesor): Różnice pomiędzy wersjami

[wersja przejrzana][wersja przejrzana]
Usunięta treść Dodana treść
są dwa rodzaje instrukcji warunkowych - preprocesora i kompilatora
Przeredagowałem trochę tekst, fragment wkleiłem z ogólnego artykułu o preprocesorze, bo był moim zdaniem lepszy.
Linia 1:
<tt>cpp</tt> ('' '''C''' '''P'''re'''p'''rocessor'') to standardowyjest [[preprocesor]]em dla [[język programowania|języków]] [[C (język programowania)|C]] i [[C++]]. Odpowiada za wstępną obróbką kodu źródłowego zanim rozpocznie się właściwy proces kompilowania. Jest jednak dość prostym narzędziem i w żaden sposób nie rozpoznaje składni języka przetwarzanego programu.
 
==Opis działania==
CPP udostępnia jedynie bardzo prostą funkcjonalność i w żaden sposób nie rozpoznaje składni języka przetwarzanego tekstu.
{{wikibooks2|link=C/Preprocesor|książka=C|rozdział=Preprocesor}}
Dyrektywy preprocesora mogą występować w ogólności w dowolnym miejscu programu, a rozróżnienie ich reszty kodu źródłowego dokonywane jest poprzez poprzedzenie ich znakiem hash [[#]] <ref name="c">[[Jan Bielecki]], '''''Od C do C++, programowanie obiektowe w języku C''''', [[Wydawnictwa Naukowo-Techniczne]], [[Warszawa]] [[1990]], ISBN 83-204-1332-X</ref><ref>[[Jan Bielecki]], '''''Turbo C z grafiką na IBM PC''''', [[Wydawnictwa Naukowo-Techniczne]], [[Warszawa]] [[1990]], Seria: [[Mikrokomputery]], ISBN 83-204-1101-7</ref>.
 
Do najważniejszych dyrektyw należą:
Ważniejsze funkcje to:
* #include … - dyrektywa włączająca tekst innego pliku źródłowego w miejscu jej wystąpienia w pliku podlegającym aktualnie przetwarzaniu, przy czym możliwe jest zagłębione występowanie dyrektywy include,
* #define … - definiuje stałe i makroinstrukcje (pseudofunkcje)
* #undef … - usuwa definicje stałej lub makra
* #if … - dyrektywy kompilacji warunkowej
* #elif … - działa podobnie jak ''else if'' w języku C
* #endif … - oznacza koniec bloku kompilacji warunkowej
* #ifdef … - znaczy to samo co #if defined(…)
* #ifndef … - znaczy to samo co #if !defined(…)
* #error … - generuje błąd wraz z opisem
 
Dyrektywy preprocesora pozwalają na ukrywanie różnic między różnymi architekturami procesorów, systemami operacyjnymi, kompilatorami a nawet samymi standardami języka. Popularnym zastosowaniem jest też tworzenie uniwersalnych nagłówków dla bibliotek C, które mogą być wstawione bezpośrednio do kodu C i C++. W przypadku tego pierwszego preprocesor wytnie konstrukcję extern.
* Zdefiniuj stałą:
<source lang="c">#define X Y</source>
* Zdefiniuj makro:
<source lang="c">#define X(argument) deasygnat</source>
* Skasuj definicję:
<source lang="c">#undef X</source>
* Włącz plik (poszukiwany wg ścieżki standardowej, zdefiniowanej w konfiguracji programu <tt>cpp</tt>):
<source lang="c">#include <stdlib.h></source>
* Włącz plik (poszukiwany wg ścieżki dodatkowej, definiowanej przez użytkownika):
<source lang="c">#include "foo.h"</source>
* Kompilacja warunkowa
<source lang="c">#if warunek
Kod jeśli warunek jest spełniony
#else
Kod jeśli warunek nie jest spełniony
#endif</source>
 
<source lang="c">#define X Y</source>
W języku C bardzo wiele ważnej funkcjonalności zależy od preprocesora. Użycie preprocesora może być jednak źródłem wielu problemów i pomyłek programistycznych. Poza szczególnymi przypadkami nie jest on też zintegrowany z językiem.
#ifdef __cplusplus
extern "C" {
#endif
 
/* Definicje */
 
#ifdef __cplusplus
}
#endif
#endif</source>
 
Innym zastosowaniem jest zabezpieczenie plików nagłówkowych przed wielokrotnym dołączaniem do tego samego projektu. Jeżeli treść pliku nagłówkowego <code>nazwa.h</code> obejmie się instrukcjami:
 
<source lang="c">#undef X</source>
#ifndef _NAZWA_H_ /* (1) */
#define _NAZWA_H_ /* (2) */
 
/* Definicje */
 
#endif /* (3) */
</source>
 
to przy pierwszej próbie dołączenia pliku, kompilator najpierw sprawdzi, czy zdefiniowano stałą _NAZWA_H_ (może ona mieć dowolną nazwę, ten sposób jest jednak dobrym zwyczajem promowanym przez programistów) (1) - jeżeli nie, zostanie ona zdefiniowana (2) i do programu zostanie dołączona treść między (2) i (3), oznaczający koniec części dodawanej tylko przy spełnieniu warunku (1).
 
Niektóre kompilatory obsługują także następującą konstrukcję:
<pre>#pragma once</pre>
Zapobiega ona ponownemu załączeniu treści całego pliku, w którym została użyta. Metoda ta jednak nie ma oparcia w oficjalnym standardzie. Podobnie, jak wszystkie użycia dyrektywy <code>#pragma</code>, jej ewentualna obsługa jest rozszerzeniem wprowadzonym przez dany kompilator i nie jest przenośna pomiędzy różnymi narzędziami.
 
==Zastosowanie w C++==
Z tego powodu w języku C++ dodano wiele funkcjonalności mającej na celu zastąpienie preprocesora.
Brak rozpoznawania składni języka przez preprocesor jest potencjalnym źródłem wielu błędów programistycznych. Z tego powodu w języku C++ dodano wiele elementów mających na celu jego zastąpienie. Część tych rozwiązań została też zaimplementowana w C.
Część tej funkcjonalności została potem dodana również do języka C.
 
Są to między innymi:
Linia 49 ⟶ 72:
</source>
Nadal jednak konieczne jest użycie preprocesora do włączania nagłówków bibliotek.
{{Przypisy}}
 
<!-- [[tr:C önişlemcisi]] -- "chwilowo" skasowany -->