+ All Categories
Home > Documents > 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

Date post: 16-Jan-2016
Category:
Upload: ryo
View: 42 times
Download: 0 times
Share this document with a friend
Description:
8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese: http://www.uai.fme.vutbr.cz/~vdumek/. Typedef. - pro zpřehlednění deklarací nových typů typedef typ identifikátor_typu - PowerPoint PPT Presentation
23
8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese: http://www.uai.fme.vutbr.cz/~vdumek/
Transcript
Page 1: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

8. přednáška27. 3. 2008

-typedef- preprocesor

Studijní materiály najdete na adrese:

http://www.uai.fme.vutbr.cz/~vdumek/

Page 2: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

- pro zpřehlednění deklarací nových typů

typedef typ identifikátor_typu

- pomocí tohoto příkazu nevytvoříme nový sémantický typ, pouze tvoříme nové jméno pro existující datový typ (omezení spojená s původním typem zůstávají)- používá se hlavně pro zvýšení přehlednosti a čitelnosti programů, pro usnadnění změn typů (operátor přetypování) a snazší modifikaci typů

typedef int LENGTH;typedef float *P_FLOAT;

P_FLOAT p_m, p_n; /* použití */

typedef char *STRING;typedef int (*PFI)(); /* ukazatel na funkci */

Typedef

Page 3: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

- dává možnost definovat nové typy, kterým můžeme deklarovat proměnné, zlepší se čitelnost programů, změny se dají dělat z jednoho místa

int f1(); int f1(); funkce vracející int

typedef int *intuk;int *u1; intuk u1; ukazatel na intint *f2(); intuk f2(); fce vracející ukazatel na

inttypedef int far *faruk;

int far *u2; faruk u2; vzdálený ukazatel na intint far *f3(); faruk f3(); funkce vracející vzdálený

ukazatel na inttypedef int (*fnuk1)(int);

int (*fu1)(int); fnuk1 fu1; ukazatel na fci s jedním intparametrem, která vrací int

typedef int (*fnuk2)(intuk);int (*fu2)(int *iu); fnuk2 fu2; ukazatel na fci s parame-

trem směrník na int, kterávrací int

Typedef

Page 4: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

Preprocesor

- úprava zdrojového textu před vlastním překladem- rozvoj maker - náhrada symbolicky označených částí skutečným textem- substituce textu- podmíněný překlad - výběr z různých variant podle podmínek- vložené soubory - možnost před překladem přidat soubor- odstraňuje komentáře, nadbytečné mezery, tabelátory- činnost preprocesoru je řízena direktivami, které jsou na tzv. řídicích řádcích (označení #), řídicí řádek může obsahovat i komentář- u moderních překladačů není fáze předzpracování oddělená, ne- vzniká žádný výstupní text, pokud je potřeba, používá se samo- statný program (CPP -> přípona .I)

Definice konstant a maker- možnost symbolického pojmenování konstant, příkazů, výrazů, … možnost modifikovat textové náhrady pomocí parametrů

Page 5: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

test.cpp 1: void main(void)test.cpp 2: {test.cpp 3:test.cpp 4:test.cpp 5:test.cpp 6:test.cpp 7: if(10 == 9)test.cpp 8: printf("ahoj");test.cpp 9:test.cpp 10:test.cpp 11: }test.cpp 12:

void main(void){// komentar#define DESET 10#define SYMBOL

if(DESET == 9) printf("ahoj");

/* dalsi komentar */}

test.c

test.i

CPP

Page 6: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

#define- používá se k definici konstant a maker

#define symbol

- takto definovaný symbol nemá žádnou hodnotu, pouze existuje, lze jej použít pro řízení podmíněného překladu (direktiva #ifdef)

#define jméno_makra text

- text vzniklý náhradou makra se nazývá rozvoj makra, text po první mezeře za identifikátorem, pozor na poznámky, nahrazování se neprovádí v řetězcích

#define DESET 10 /* konstanta - symbolické jméno pro hodnotu 10 */#define beep putch(7) /* symbolické označení pro výpis znaku BELL */

if (k == DESET) beep; rozvine se if(k == 10) putch(7);

- dosazení hodnoty se provádí na úrovni textu před překladem

Preprocesor

Page 7: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

- při ukončení definice se nepoužívá středník, symbol se nahradí textem při rozvoji, středník se použije v místě použití- definice se dá použít i na více řádků

#define DLOUHY_TEXT “Toto je velmi dlouhy text, který se nevejde ani za nic na \jeden radek “#define CHYBA if (chyba==1) \

printf(“\nstala se nejaka chyba”); \else if (chyba==2) \ printf(“\nstala se nejaka jina chyba”); \else \ printf(“\nstala se uplne jina chyba”);

- definice makra s parametry

#define jmeno_makra(seznam formalnich parametru) text

- pozor na umístění mezer

Preprocesor

Page 8: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

#include <stdio.h>

#define DLOUHY_TEXT "Toto je velmi dlouhy text, kterě se nevejde ani za nic \ na jeden radek"#define CHYBA if (chyba==1) \

printf("\nstala se nejaka chyba"); \else if (chyba==2) \ printf("\nstala se nejaka jina chyba"); \else \ printf("\nstala se uplne jina chyba");

void main(void){ chyba=2;

printf ("%s", DLOUHY_TEXT); CHYBA chyba=1; CHYBA}

Toto je velmi dlouhy text, který se nevejde ani za nic na jeden radekstala se nejaka jina chybastala se nejaka chyba

Page 9: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

Preprocesor

- volání makra je formálně shodné s voláním funkce (mnoho knihovních funkcí jsou ve skutečnosti makra), počet formálních a skutečných parametrů musí souhlasit

- zdánlivě nadbytečné množství závorek zamezí chybám při rozvoji maker v případě použití složených výrazů nebo v souvislosti s prioritou operátorů

#define MAX(a,b) (((a) > (b)) ? (a) : (b))

i=MAX(3, y); i=(((3) > (y)) ? (3) : (y));

#define NA_DRUHOU(x) x*x špatně

i = 6;j = NA_DRUHOU(i); j = 6*6; /* 36 OK */k = NA_DRUHOU(i+2); k = i+2*i+2; /* 20 CHYBA */l = 100/NA_DRUHOU(5); l = 100/5*5; /* 100 CHYBA */

#define NA_DRUHOU(x) ((x)*(x)) správně

Page 10: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

- totožná syntaxe volání funkce a makra může vést k chybám, neboť u maker není prováděna (na rozdíl od funkcí) žádná typová kontrola, není předávána hodnota parametru, ale jeho textová podoba, zrychluje se běh programu

#define NA_DRUHOU(x) ((x)*(x))

int na_druhou(int x){ return x*x;}…..i = 2;j = NA_DRUHOU(i++); /* j=((i++)*(i++))=2*3=6, i=4 */…..i = 2;k = na_druhou(i++); /* k=4, i=3 */

- definovaný symbol nemůže být definován znovu

Preprocesor

Page 11: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

- makra mohou být vnořována, po rozvoji makra projde prepro- cesor vzniklý text ještě jednou, aby mohl provést event. rozvoj dalšího makra

#define NA_DRUHOU(x) ((x)*(x))#define MAX(a,b) (((a)>(b)) ? (a) : (b))

i = MAX(k, NA_DRUHOU(j));po rozvoji:i = (((k) > (NA_DRUHOU(j))) ? (k) : (NA_DRUHOU(j)));i = (((k) > (((j)*(j)))) ? (k) : (((j)*(j))));

- rozvoj makra nesmí vést na další direktivu, která již není pre- procesorem zpracována

#define VLOZENI #include <stdio.h>

VLOZENI se rozvine jako #include <stdio.h> /* chyba */

Preprocesor

Page 12: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

- jako jména maker lze použít i klíčová slova. Využívání této vla- stnosti se nedoporučuje

#define int long /* formálně správně, zcela nevhodné */

- parametry maker se dosazují buď přímo jako text, který se přidá do zdrojového textu programu, nebo mohou být napřed převe- deny na textový řetězec. K tomu se používá symbol #.

#define VYSLEDEK(x) printf(#x “=%f\n”, x)

VYSLEDEK(Obvod); /* printf(“Obvod” “=%f\n”, Obvod);

- při chybné definici makra může dojít k chybné interpretaci zá- měrů programátora

#define VYSLEDEK_1(x) printf(“x=%f\n”, x);…..VYSLEDEK_1(Obvod); /* printf(“x=%f\n”, Obvod); */

Preprocesor

Page 13: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

- symbol definovaný pomocí direktivy #define platí až do konce překládaného modulu (včetně vkládaných modulů), pokud se ne- vyskytne direktiva #undef

#undef jmeno_makra pokud mělo rušené makro parametry, tyto se neuvádějí. Symboly přestávají existovat, vrací se do stavu před použitím #define. Lze testovat pomocí #ifdef, #ifndef u podmíněného překladu.- symbol lze definovat po direktivě #undef zcela jiným způsobem, při pokusu o novou definici bez předchozího použití #undef je hlášena chyba

#define DELKA_BLOKU 512…..delka=pocet*DELKA_BLOKU; /* pocet * 512 */…..#undef DELKA_BLOKU /* dale nelze pouzivat */

Preprocesor

Page 14: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

#define DELKA_BLOKU 128…..delka=pocet*DELKA_BLOKU; /* pocet * 128 */…..

Vložené soubory- lze vložit do zdrojového souboru text, obsažený v jiném souboru samotná direktiva #include je odstraněna

#include <jmeno_souboru> #include “jmeno_souboru”

- jméno souboru může být uvedeno včetně specifikace cesty k souboru, to má význam u syntaxe s uvozovkami, pro úhlové zá- vorky platí předdefinovaný adresář s vkládanými soubory- direktiva include se nepoužívá pouze pro hlavičkové soubory, ale je použitelná i pro zdrojové texty

Preprocesor

Page 15: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

S1.C S2.C

#define KOLIK 20 #include “S1.C”typedef struct { int i,j,k; MOJE_STR a, b, *c;

float d; int p=KOLIK;char a[20];

} MOJE_STR; void main(void){

void moje_funkce(MOJE_STR *x, int a) …..{…..} moje_funkce(&a, KOLIK);

…..}

- vlivem vložení souboru S1.C do souboru S2.C lze používat všechny proměnné a funkce, probíhá zde jeden překlad- ANSI překladače (C++) povolují i vkládání makra- může být i vnoření (8), pozor na cyklické vnoření

#define myinclude “hlavicka.h”#include myinclude /* vkládá se hlavicka.h */#include “myinclude.h” /* vkládá se myinclude.h */

Preprocesor

Page 16: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

- direktiva #include se používá pro vkládání souborů s definicemi maker, konstant, datových typů, deklaracemi globálních promě- nných a prototypy funkcí, hlavičkové soubory, rozdělení pro různé problematické okruhy - zmenšení překládaných objemů

Podmíněný překlad- mechanismus k vyřazení některé části zdrojového textu z přek- ladu na základě splnění nějaké podmínky. Vyřazovaná část je nahrazena prázdnými řádky. Používají se direktivy:#if, #ifdef, #ifndef, #elif, #else, #endif

Nejjednodušší forma:

#if konst_vyraz….. /* podmíněně překládaný text */#endif

Preprocesor

Page 17: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

Preprocesor

- úsek mezi direktivami je překládán pouze tehdy, když má konstantní výraz nenulovou hodnotu, každé if musí mít své endif a musí být obě ve stejném překládaném souboru- výraz, který řídí překlad musí být vyčíslitelný v době překladu, nesmí obsahovat proměnné, sizeof, enum a casting

- jako podmínka pro řízení překladu se často používá test, zda je nějaký symbol definován

#define BLOK 512#define POCET 3…..#if BLOK > 200….. /* preklad OK */#endif….. /* preklad vzdy */#if (BLOK == 128) && (POCET > 2)….. /* nepreklada se */#endif….. /* preklad vzdy */

Page 18: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

#ifdef symbol….. /* preklada se , pokud je symbol definovany */#endif…..#ifndef symbol….. /* preklada se, pokud symbol neni definovany */#endif

#if defined symbol /* totez jako #ifdef symbol */#if defined (symbol) /* totez, zavorky jsou nepovinne */#if !defined symbol /* totez jako #ifndef */

- výhodou direktivy defined je možnost testovat definici více symbolů pomocí jedné direktivy

#define SYMBOL1#define SYMBOL2

#if defined SYMBOL1 && !defined SYMBOL2….. /* nepreklada se */#endif#undef SYMBOL2#if defined SYMBOL1 && !defined SYMBOL2

Page 19: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

- pokud má mít generovaný kód v některém úseku v závislosti na určitých podmínkách více než dvě varianty, používá se vedle if a else ještě elif

#if konst_vyraz1….. /* překládá se pro pravdivý konst_vyraz1 */#elif konst_vyraz2….. /* překládá se pro !konst_vyraz1 && konst_vyraz2 */#elif konst_vyraz3….. /* !konst_vyraz1 && !konst_vyraz2 && konst_vyraz3 */#else….. /* překládá se, pokud není pravdivý žádný výraz */#endif

- počet direktiv elif není omezen, pro každou direktivu if ale může být nejvýše jedna direktiva else, je poslední řídící direktivou před endif- podmíněně překládané sekce mohou být v rámci zdrojového tex- tu vnořovány do libovolné hloubky, každá if musí mít odpoví- dající endif

Preprocesor

Page 20: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

#if SYMBOL<50….. /* překládá se pro <50 */#elif SYMBOL<300….. /* překládá se pro 50<=SYMBOL<300 */#elif SYMBOL<1000….. /* překládá se pro 300<=SYMBOL<1000 */#else….. /* překládá se pro 1000<=SYMBOL */#endif

#define X 10#define Y 80…..#if X<25….. /* překládá se pro X<25 */#if Y>100….. /* překládá se pro (X<25)&&(Y>100) */#endif /* ukončení podmínky Y>100 */…..#endif /* ukončení podmínky X<25 */

Preprocesor

Page 21: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

- podmíněný překlad používáme v případech, kdy potřebujeme generování různých variant kódu z jediného zdrojového textu (různé kompilátory, různé operační systémy, různé paměťové modely)

Ovládání čísel řádků- překladač i preprocesor si během své práce pamatují jméno právě zpracovávaného zdrojového souboru a číslo právě zpra- covávaného řádku tohoto souboru. Tyto informace jsou obsa- ženy ve výstupním textu generovaném preprocesorem, objevují se v chybových hlášeních- direktiva #line umožňuje nastavit jméno souboru i číslo řádku tak, jak programátor potřebuje

#line konstanta [jmeno_souboru]

- konstanta - další číslo, které bude přiřazeno

Preprocesor

Page 22: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

- je-li vynechán nepovinný parametr jmeno_souboru, platí napo- sledy nastavené direktivou line, resp. originální jméno souboru- v běžné programátorské praxi se používá ojediněle

Generování chyb při překladu- slouží k zabránění určitých podmínek při překladu (nevhodný rozsah konstant, nevhodný překladač, nevhodný paměťový model, nevhodný operační systém, …)

#error text

- text je hlášení, které se objeví při překladu

#define BUFFER 2000 #if BUFFER < 1000… #error Buffer je prilis malyifndef __LARGE__ #endif#error Nevhodny pametovy model#endif

Preprocesor

Page 23: 8. přednáška 27. 3. 2008 -typedef - preprocesor Studijní materiály najdete na adrese:

Pragmy- tato direktiva je mlhavě definovaná normou ANSI, pomocí ní se zapisují instrukce pro překladač závislé na implementaci

#pragma jmeno_direktivy

- jména direktiv mají být pro konkrétní překladač navržena tak, aby nedocházelo ke kolizím (pro každý překladač unikátní). Po- kud překladač narazí na direktivu pragma, jejíž název nezná, di- rektivu ignoruje aniž by generoval chybovou zprávu- direktiva pragma se většinou používá pro nastavení některých voleb překladače na úrovni zdrojového textu místo v parame- trech příkazového řádku

#pragma argsused #pragma startup jmeno_fce priorita#pragma inline #pragma saveregs #pragma warn

Preprocesor


Recommended