Witam, czy mógłby mi ktoś napisać po co używa się dyrektywy #ifndef w taki sposób:
#ifndef _NazwaPliku_H_
#define _NazwaPliku_H_
jeśli nigdzie dalej nie jest to w żaden sposób wykorzystywane?
Takie użycie jest w pliku z końcówką .h
Wątek zablokowany 2018-12-13 13:34 przez furious programming.
Witam, czy mógłby mi ktoś napisać po co używa się dyrektywy #ifndef w taki sposób:
#ifndef _NazwaPliku_H_
#define _NazwaPliku_H_
jeśli nigdzie dalej nie jest to w żaden sposób wykorzystywane?
Takie użycie jest w pliku z końcówką .h
Bo każde #include powoduje wklejenie zawartości pliku dołączanego do tego pliku gdzie jest include. W efekcie mogłoby się zdarzyć ze jakiś plik jest includowany dwa razy w tym samym pliku źródłowym i pojawiłby się problem, bo masz na przykład dwie definicje tej samej klasy. To co pokazałeś to jest tzw strażnik nagłówka który przed tym zabezpiecza.
wyobraź sobie plik NazwaPliku.h
o takiej właśnie treści:
#ifndef _NazwaPliku_H_
#define _NazwaPliku_H_
void foo();
#endif _NazwaPliku_H_
a potem plik Program.c
o takiej treści:
#include "NazwaPliku.h"
#include "NazwaPliku.h"
gdyby nie było strażników, plik nagłówkowy wklejony by został dwa razy:
void foo();
void foo();
co tu może nie zaszkodzi, ale czasami jest to zdecydowanie nie na rękę.
Jednak dzięki ifdef
om, rozwija się to do
#ifndef _NazwaPliku_H_
#define _NazwaPliku_H_
void foo();
#endif _NazwaPliku_H_
#ifndef _NazwaPliku_H_
#define _NazwaPliku_H_
void foo();
#endif _NazwaPliku_H_
co po rozwiązaniu dyrektyw daje
#define _NazwaPliku_H_
void foo();
i mamy treść pliku .h wklejoną tylko raz.
Czasami nie możemy zapobiec wielokrotnemu inkludowaniu tego samego nagłówka, albo za dużo zachodu by to wymagało — a dzięki tej sztuczce mamy problem z głowy.
Uuu, czytałem o tym i niestety źle to zinterpretowałem. Masz rację! już to rozumiem :)
Dzięki
Witam. Wiem, że odświeżam wątek z 2012, ale moim zdaniem nie ma sensu zakładać oddzielnie nowego tematu, bo mam tylko jedno pytanie odnośnie dzielenia kodu na kilka plików, a powyżej już część została wytłumaczona. Mam takie pliki:
//Plik: main.cpp
#include <iostream>
#include <conio.h>
#include "nazwaPliku.hpp"
using namespace std;
int main()
{
cout << "Wynik dodawania to: " << dodajLiczby( 10, 15 ) << endl;
getch();
return( 0 );
}
//#ifndef nazwaPliku_hpp
//#define nazwaPliku_hpp
int dodajLiczby( int a, int b );
//#endif
//Plik: nazwaPliku.cpp
#include "nazwaPliku.hpp"
int dodajLiczby( int a, int b )
{
return( a + b );
}
Jak widzicie, instrukcje #ifndef i #endif umieściłem w komentarz, czyli tak naprawdę usunąłem je z kodu, a mimo to program się kompiluje i działa, nawet jeżeli w pliku głównym dwa razy wpiszę
#include "nazwaPliku.hpp". Dlaczego?
Bo masz szczęście i akurat przy redefinicji redeklaracji nic nie wybucha. W ogólności może jednak tak nie być.
Althorion napisał(a):
Bo masz szczęście i akurat przy redefinicji nic nie wybucha. W ogólności może jednak tak nie być.
Przy redefinicji właśnie wybucha. :) @kario97 ma deklaracje, a deklaracje mogą się powtarzać. int dodajLiczby( int a, int b );
jest deklaracją.
koszalek-opalek napisał(a):
Althorion napisał(a):
Bo masz szczęście i akurat przy redefinicji nic nie wybucha. W ogólności może jednak tak nie być.
Przy redefinicji właśnie wybucha. :) @kario97 ma deklaracje, a deklaracje mogą się powtarzać.
int dodajLiczby( int a, int b );
jest deklaracją.
Hmm, a mógłbyś zmodyfikować ten program tak, aby nadal był prosty jak budowa cepa i jednocześnie "wybuchł"? xd
@kario97: Dopisz w pliku nagłówkowym jakąś zmienną globalną, na przykład int liczba;
(bo to już jest definicja a nie deklaracja) i już chyba będzie źle.
PS. Oczywiście zmiennych globalnych nie wolno używać. :)
Zmieniłem na coś takiego:
#ifndef nazwaPliku_hpp
#define nazwaPliku_hpp
int liczba;
int dodajLiczby( int a, int b );
#endif
Jak widzisz tym razem są już instrukcje ifndef i endif, ale program i tak się nie kompiluje. xD
Kompiluje się u mnie (bo wyrzuceniu conio
i getch
), może u Ciebie się nie linkuje, bo masz złe ustawienia projektu...? Jakie dostajesz komunikaty?
A, nie linkuje się teraz przez tę liczbę... :) Zaraz pomyślę nad inną "poprawką". :)