Aktyw Forum

Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.

Sprawdź punkty Zarejestruj się

Wstawki #ifndef , #define ,#endif w pliku nagłówkowym

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:
Wstawki #ifndef , #define ,#endif w pliku nagłówkowym

Postautor: Sławek5 » 31 lip 2006, o 13:17

Witam
Potrzebuję małej pomocy - wyjaśnienia.

Jeśli mam program napisany w C i skałda się on z kilku plików powiedzmy main.c oraz funkcje.c, a także dodatkowo jest plik nagłówkowy head.h.
W tym pliku nagłówkowym są takie zapisy:

Kod: Zaznacz cały

#ifndef IDNETYFIKATOR #define IDENTYFIKATOR //treść pliku #endif
To powiedzcie mi po co są te wstawki #ifndef , #define ,#endif.

petersz
-
-
Posty:580
Rejestracja:2 gru 2005, o 18:26
Lokalizacja:---

Postautor: petersz » 31 lip 2006, o 14:12

Coś takiego robi się po to, by nie dołączać kilka tego samego pliku kilka razy. Tylko o to chodzi...

Pozdr.

Awatar użytkownika
tasza
-
-
Posty:456
Rejestracja:17 sty 2005, o 10:52

Postautor: tasza » 31 lip 2006, o 14:15

takimi dyrektywami preprocesora opatrza się często zawartość plików
nagłówkowych, aby nie wystąpiło ryzyko konfliktu z innymi deklaracjami
lub swoiste zapętlenie się includów (pierwszy woła drugi, drugi woła pierwszy)

zrób prosze mały teścik:

potrzeba trzy pliki:
#include "dwa.h"
#define CONST_JEDEN 0x1234
#include "jeden.h"
#define CONST_DWA 0x1234
#include "jeden.h"
#include "dwa.h"
//.....
unsigned short v1 = CONST_JEDEN;
unsigned short v2 = CONST_DWA;
przykładowo w przypadku uC/51 dostaje się:
.\dwa.h 5: .\jeden.h 6: .\dwa.h 5: .\jeden.h 6: .\dwa.h 5: .\jeden.h 6:
.\dwa.h 5: .\jeden.h 6: .\dwa.h 5: .\jeden.h 6: hello.c 2:
Error: #include too deeply nested
gdy te pliki *.h opatrzysz wspomnianymi dyrektywami, podczas kompilacji
po pierwszym napotkaniu danego symbolu, zostanie przyjęte, że on już jest zdefiniowany
i przy drugim wczytaniu takiego pliku *.h zostanie on przetworzony inaczej (zawartość będzie pominięta)
ponieważ tak każą instrukcje ifndef/endif
#ifndef __JEDEN_H__
#define __JEDEN_H__

#include "dwa.h"
#define CONST_JEDEN 0x1234

#endif // __JEDEN_H__
#ifndef __DWA_H__
#define __DWA_H__

#include "jeden.h"
#define CONST_DWA 0x1234

#endif // __DWA_H__
#include "jeden.h"
#include "dwa.h"
//.....
unsigned short v1 = CONST_JEDEN;
unsigned short v2 = CONST_DWA;
a powyższe się skompiluje bez żadnych kłopotów....

tasza

stan24
-
-
Posty:60
Rejestracja:16 lut 2004, o 10:19
Lokalizacja:Łódź

Postautor: stan24 » 31 lip 2006, o 14:39

i oznacza, ze jezeli nie zdefiniowano takiej nazwy to teraz to wlasnie nastapi. :) . Kazda derektywa warunkowama swoj poczatek (#idndef, #ifdef) i koniec (#endif). W obrebie dyrektywy moze rowniez pojawic sie instrukcja #else.

Ale mozemy Twoj przyklad bardziej skaplikowac:

plik head.h

Kod: Zaznacz cały

#ifndef HEAD_H #define HEAD_H .... #endif
Otoz plik naglowkowy moze rowniez zawierac ta sama dyrektywe #include - tzw. zagniezdzenie plikow naglowkowych. Podczas przetwarzania pliku zrodlowego pojawi sie kilkakrotnie dyrektywa dolaczajaca ten sam plik naglowkowy (#include head.h). Zeby rozwiazac ten problem dolacza sie powyzsza dyrektywe warunkowa.
Chyba wszystko jasne :)

[ Dodano: 31-07-2006, 15:46 ]
Widze ze Tasza byla szybsza :)

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:

Postautor: Sławek5 » 31 lip 2006, o 18:56

OK. dziękuję, ale dlaczego jak nie będzie tych dyrektyw to w takich plikach w których są tylko np deklaracje:

Kod: Zaznacz cały

void Delay_500us(void); void Delay_70us(void); void Delay_7us(void);
działa i nie pokazuje błędów a mimo to w tych plikach one się pojawiają

stan24
-
-
Posty:60
Rejestracja:16 lut 2004, o 10:19
Lokalizacja:Łódź

Postautor: stan24 » 31 lip 2006, o 22:32

... powinnienes bardziej uwaznie przeczytac to co zostalo wyzej napisne. Mysle, ze prosciej niz lady Tasza nikt tego nie byl wstanie wyjasnic.
Jezeli pliki naglowkowe nie zaiwraja odwolan do innych plikow naglowkowych (te z literka h po kropce) to podczas laczenia (kompilacji) nie zostanie zgloszony blad:
Error: #include too deeply nested
czyli w tlumaczeniu na nasze: zbyt gleboko zagniezdzona dyrektywa #include

Awatar użytkownika
tasza
-
-
Posty:456
Rejestracja:17 sty 2005, o 10:52

Postautor: tasza » 1 sie 2006, o 08:14

Sławek5, obejmowanie zawartości (lub tylko fragmentu) pliku nagłówkowego
w dyrektywy kompilacji warunkowej nie jest obowiązkowe. To jedna z możliwości
zorganizowania kodu źródłowego, ale nie wymóg.
Nie zmienia to faktu - że taki sposób budowania includów to raczej dobry zwyczaj,
szczególnie gdy są pisane nie tylko na własny użytek, ale też aby inni mogli z nich korzystać.

Jak masz możliwość zerknij na pliki include z pakietu WinAVR....są sobie io.h i interrupt.h
io.h woła includa z avr/io.h
interrupt.h woła include z avr/interrupt.h, a ten na dodatek jeszcze avr/io.h bo do czegoś potrzebuje...

gdy piszesz prosty program, który nie korzysta z przerwań - dołaczasz io.h, tak?
a gdy korzysta z int-ów - to jeszcze dołączasz interrupt.h i gdyby nie te 'zabezpieczenia'
kompilacja byłaby problematyczna.

inny przykład - wracając do io.h - on na bazie typu procesora (też podanego jako symbol
honorowany przez preprocesor) wybiera sobie plik nagłówkowy natywny dla danego MCU...
ale takiego pliku np. io2313.h nie załączysz luzem.... ponieważ dla odmiany:
#ifndef _AVR_IO_H_
# error "Include <avr/io.h> instead of this file."
#endif
to zabezpiecznie przed niezalecanym przez autorów pakietu
sposobem załączania headerów...

pozdrawiam,
tasza

Wróć do „PLD/FPGA i inne zagadnienia techniki cyfrowej”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 9 gości