LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> C/C++ (13) - Preprocesor podruhé

V dnešním dílu povídání o preprocesoru dokončíme. Probereme makra s parametry, standardní předdefinovaná makra a některé méně používané direktivy.

1.2.2005 15:00 | Jan Němec | Články autora | přečteno 31244×

Makro s parametry

Minule jsem si ukázali, jak definovat jednoduché makro bez parametrů, nicméně podobně jako funkce i makro může mít parametry.

#define moje_gets(s, size) fgets((s), (size), stdin)

V dílu o standardním vstupu jsem haněl funkci gets a doporučoval místo ní fgets. Pokud programátora nebaví opisovat parametr stdin, může si pomoci výše uvedeným makrem. Je dobrým zvykem dávat parametry makra do závorek. Kdybychom třeba definovali makro pro násobení

#define KRAT(a, b) a * b
/*
Správně je
#define KRAT(a, b) ((a) * (b))
*/

Rozvine se při volání

KRAT(1 + 2, 3 + 4)

na

1 + 2 * 3 + 4

Občas se hodí makro pro menší ze dvou čísel. Zde pomůže ternární operátor.

#define MINIMUM(a, b) ((a) < (b) ? (a) : (b))

Zejména v souvislosti s makry se často vyskytuje také operátor zapomenutí, čárka.

Výraz x, y znamená nejprve vyhodnoť podvýraz x a hodnotu zapomeň, potom vyhodnoť podvýraz y a jeho hodnota bude výsledkem celého výrazu x, y. Celá konstrukce má smysl, pokud je na výrazu x podstatný jen jeho vedlejší efekt. Pokud nás například z ladících důvodu zajímá celkový počet volání putchar, můžeme jej volat prostřednictvím následujícího makra.

int pocet_volani = 0;

#define VOLEJ_PUTCHAR(c) (pocet_volani++, putchar((c)))

Je dobré si uvědomit, že takto definované makro umožňuje přístup i k návratové hodnotě volání putchar, což by definice pomocí dvou příkazů ukončených středníkem neumožňovala. V programu tedy můžeme makro volat i takhle.

int c = VOLEJ_PUTCHAR('A');
if (c == EOF) {
  puts("Chyba");
}

Parametry makra samozřejmě nemusejí být jen proměnné nebo výrazy.

#define PROHOD(typ, a, b) {typ c; c = a; a = b; b = c;}

Uvedené makro prohodí obsah dvou proměnných libovolného typu. Volalo by se například

int i = 1, j = 2;

PROHOD(int, i, j)

Rušení makra

Při běžném způsobu programování v C není obvykle třeba definici makra rušit. Výjimka může nastat, pokud chceme definovat makro jen pro použití v hlavičkovém souboru, ale nechceme, aby bylo platné i v souboru, který jej inkluduje. Také se může stát, že nám vadí makro z nějakého hlavičkového souboru, jehož obsah nemůžeme ovlivnit. Zde pomůže příkaz #undef

#undef MAKRO

/* nebo obecněji */

#ifdef MAKRO
#undef MAKRO
#endif

Drobnosti

Některé direktivy preprocesoru často neznají ani ostřílení C programátoři. Sem patří #, ## a #line. Pomocí # lze parametr makra po rozvinutí obalit uvozovkami a udělat z něj řetězcovou konstantu, ## zase spojuje 2 tokeny do jednoho identifikátoru.

#include <stdio.h>
#define PRINT_TOKEN(x) puts(#x)
#define PRINT_I(x) printf("%i\n", i##x)

int main(void) {

  int i1 = 7, i2 = 8, i3 = 9;

/* Pokud uhodnete, co vypíše PRINT_TOKEN(1 + 1); rozumíte preprocesoru */

  PRINT_TOKEN(1 + 1);
  PRINT_I(1); /* printf("%i\n", i1); */
  PRINT_I(2); /* printf("%i\n", i2); */
  PRINT_I(3); /* printf("%i\n", i3); */
  return 0;
}

O něco častěji se používá #pragma, tato direktiva má obvykle ještě parametr. Pokud mu překladač nerozumí, musí podle normy celou direktivu ignorovat. V opačném případě ji implementačně závislým způsobem zpracuje. Například pomocí #pragma warning( disable : 4507 ) můžeme v MS Visual C++ zakázat jedno konkrétní varovné hlášení při překladu kódu, který se zdá překladači podezřelý. Při použití jiného překladače (např. gcc), který tuto syntaxi direktivy #pragma nezná, nedojde k chybě, pouze bude celá direktiva ignorována.

Standardní makra

ANSI C definuje několik maker

  • __LINE__
    aktuální řádek ve zdrojovém souboru
  • __FILE__
    jméno zdrojového souboru
  • __TIME__
    čas překladu souboru
  • __DATE__
    datum překladu souboru
  • __TIMESTAMP__
    datum a čas modifikace souboru
  • __STDC__
    1, pokud překládáme jako ANSI C (a ne např. C++), jinak nedefinováno

Direktiva #line ovlivňuje předdefinovaná makra __LINE__ a __FILE__.

#line 174 "soubor.c"

Tato direktiva může být použita v generátorech C kódu z nějakého metazdrojáku, případná chybová hlášení (využívající __LINE__ a __FILE__) přeloženého vygenerovaného C kódu tak mohou být nastavena na původní metakód. Běžný programátor tedy #line asi nikdy nevyužije.

Příklad pro dnešní díl

Při vývoji větších projektů je dobrým zvykem umožnit logování událostí za běhu programu. V distribuční verzi může (ale nemusí) být žádoucí logování potlačit a logovací kód vůbec nepřekládat a nelinkovat do programu. V příkladu definuji makro ZALOGUJ, které se rozvine buď na prázdný řetězec, nebo na výpis logovací hlášky v závislosti na symbolu LOGOVAT. Všimněte si použití standardních maker __FILE__ a __LINE__.

/*
  gcc program.c -o program -DLOGOVAT
*/
#include <stdio.h>
#ifdef LOGOVAT
#define ZALOGUJ(s) printf("%s:%i %s\n", __FILE__, __LINE__, (s))
#else
#define ZALOGUJ(s)
#endif

int main(void) {
  ZALOGUJ("Začátek programu");
  return 0;
}

Pokračování příště

Příště se podíváme podrobněji na funkce. Postupně se také začneme zabývat projekty s větším počtem zdrojových souborů.

Verze pro tisk

pridej.cz

 

DISKUZE

Nejsou žádné diskuzní příspěvky u dané položky.



Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

14.11.2017 16:56 /František Kučera

Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt – tradičně první čtvrtek před třetím pátkem v měsíci: 16. listopadu od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).


Přidat komentář

12.11.2017 11:06 /Redakce Linuxsoft.cz
PR: 4. ročník odborné IT konference na téma Datová centra pro business proběhne již ve čtvrtek 23. listopadu 2017 v konferenčním centru Vavruška, v paláci Charitas, Karlovo náměstí 5, Praha 2 (u metra Karlovo náměstí) od 9:00. Konference o návrhu, budování, správě a efektivním využívání datových center nabídne odpovědi na aktuální a často řešené otázky, např Jaké jsou aktuální trendy v oblasti datových center a jak je využít pro vlastní prospěch? Jak zajistit pro firmu či jinou organizaci odpovídající služby datových center? Podle jakých kritérií vybrat dodavatele služeb? Jak volit součásti infrastruktury při budování či rozšiřování vlastního datového centra? Jak efektivně spravovat datové centrum? Jak eliminovat možná rizika? apod.
Přidat komentář

13.9.2017 8:00 /František Kučera
Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt – tentokrát netradičně v pondělí: 18. září od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).
Přidat komentář

3.9.2017 20:45 /Redakce Linuxsoft.cz
PR: Dne 21. září 2017 proběhne v Praze konference "Mobilní řešení pro business". Hlavní tématy konference budou: nejnovější trendy v oblasti mobilních řešení pro firmy, efektivní využití mobilních zařízení, bezpečnostní rizika a řešení pro jejich omezení, správa mobilních zařízení ve firmách a další.
Přidat komentář

15.5.2017 23:50 /František Kučera
Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt, který se bude konat ve čtvrtek 18. května od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).
Přidat komentář

12.5.2017 16:42 /Honza Javorek
PyCon CZ, česká konference o programovacím jazyce Python, se po dvou úspěšných ročnících v Brně bude letos konat v Praze, a to 8. až 10. června. Na konferenci letos zavítá např. i Armin Ronacher, známý především jako autor frameworku Flask, šablon Jinja2/Twig, a dalších projektů. Těšit se můžete na přednášky o datové analytice, tvorbě webu, testování, tvorbě API, učení a mentorování programování, přednášky o rozvoji komunity, o použití Pythonu ve vědě nebo k ovládání nejrůznějších zařízení (MicroPython). Na vlastní prsty si můžete na workshopech vyzkoušet postavit Pythonem ovládaného robota, naučit se učit šestileté děti programovat, efektivně testovat nebo si v Pythonu pohrát s kartografickým materiálem. Kupujte lístky, dokud jsou.
Přidat komentář

2.5.2017 9:20 /Eva Rázgová
Putovní konference československé Drupal komunity "DrupalCamp Československo" se tentokrát koná 27. 5.2017 na VUT FIT v Brně. Můžete načerpat a vyměnit si zkušenosti z oblasti Drupalu 7 a 8, UX, SEO, managementu týmového vývoje, využití Dockeru pro Drupal a dalších. Vítáni jsou nováčci i experti. Akci pořádají Slovenská Drupal Asociácia a česká Asociace pro Drupal. Registrace na webu .
Přidat komentář

1.5.2017 20:31 /Pavel `Goldenfish' Kysilka
PR: 25.5.2017 proběhne v Praze konference na téma Firemní informační systémy. Hlavními tématy jsou: Informační systémy s vlastní inteligencí, efektivní práce s dokumenty, mobilní přístup k datům nebo využívání cloudu.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

18.9.2017 14:37 / Rojas
high security vault

15.9.2017 7:33 / Wilson
new zealand childcare jobs

31.8.2017 12:11 / Jaromir Obr
Re: ukůládání dat ze souboru

30.7.2017 11:12 / Jaromir Obr
Národní znaky

27.7.2017 12:24 / Jaromir Obr
Cteni/zapis

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2017) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze