Znaczenie obu mi umyka.
c
declaration
terminology
definition
c++-faq
Maciek
źródło
źródło
Odpowiedzi:
Deklaracja wprowadza identyfikator i opisuje jej typ, czy to typ obiektu lub funkcji. Deklaracja jest tym, czego kompilator potrzebuje, aby zaakceptować odwołania do tego identyfikatora. Są to deklaracje:
Definicja faktycznie instancję / narzędzia tego identyfikatora. Właśnie tego linker potrzebuje , aby połączyć referencje z tymi jednostkami. Są to definicje odpowiadające powyższym deklaracjom:
Zamiast deklaracji można zastosować definicję.
Identyfikator może być deklarowany tak często, jak chcesz. Dlatego w C i C ++ dozwolone są następujące czynności:
Jednak musi być zdefiniowany dokładnie raz. Jeśli zapomnisz zdefiniować coś, co gdzieś zostało zadeklarowane i do którego się odwołuje, linker nie wie, do czego prowadzić link i narzeka na brakujące symbole. Jeśli zdefiniujesz coś więcej niż jeden raz, linker nie wie, do której definicji odwołuje się odwołanie, i skarży się na powielone symbole.
Ponieważ wciąż pojawia się debata na temat deklaracji klasy a definicji klasy w C ++ (w odpowiedziach i komentarzach do innych pytań), tutaj wkleję cytat ze standardu C ++.
W wersji 3.1 / 2 C ++ 03 mówi:
3.1 / 3 następnie podaje kilka przykładów. Pośród nich:
Podsumowując: standard C ++ uważa
struct x;
się zgłoszenie i definicja . (Innymi słowy, „deklaracja przekazania” jest myląca , ponieważ w C ++ nie ma innych form deklaracji klas.)struct x {};
Dzięki litb (Johannes Schaub), który wykopał właściwy rozdział i werset w jednej ze swoich odpowiedzi.
źródło
extern int i
jest deklaracją, ponieważ po prostu wprowadza / określai
. Wextern int i
każdej jednostce kompilacyjnej możesz mieć tyle, ile chcesz.int i
jest jednak definicją. Oznacza miejsce na liczbę całkowitą w tej jednostce tłumaczeniowej i radzi linkerowi, aby powiązał wszystkie odniesieniai
z tym podmiotem. Jeśli masz więcej niż jedną z tych definicji, linker narzeka.int i;
w zakresie pliku / zasięgu globalnym lub zasięgu funkcji jest definicją zarówno w C, jak i C ++. W C, ponieważ alokuje pamięć, aw C ++, ponieważ nie ma specyfikatora zewnętrznego ani specyfikacji powiązania. Sprowadza się to do tego samego, co mówi sbi: w obu przypadkach deklaracja określa obiekt, z którym muszą być powiązane wszystkie odniesienia do „i” w tym zakresie.struct A { double f(int, double); double f(int, double); };
oczywiście nieważne. Jest to dozwolone gdzie indziej. Istnieje kilka miejsc, gdzie można zadeklarować rzeczy, ale nie określają też:void f() { void g(); }
ważny, ale nie dodaje się:void f() { void g() { } };
. Co to jest definicja, a co deklaracja ma subtelne reguły, jeśli chodzi o szablony - uwaga! +1 za dobrą odpowiedź.Ze standardowej sekcji C ++ sekcja 3.1:
Następny akapit stwierdza (moje podkreślenie), że deklaracja jest definicją, chyba że ...
... deklaruje funkcję bez określania jej treści:
... deklaruje element statyczny w definicji klasy:
... deklaruje nazwę klasy:
... zawiera
extern
słowo kluczowe bez inicjatora lub treści funkcji:... lub jest oświadczeniem
typedef
lubusing
.Teraz z ważnego powodu, dla którego ważne jest zrozumienie różnicy między deklaracją a definicją: Reguła One Definition . Z sekcji 3.2.1 standardu C ++:
źródło
struct x {static int b = 3; };
?b
zostanie również zadeklarowanaconst
. Zobacz stackoverflow.com/a/3536513/1858225 i daniweb.com/software-development/cpp/threads/140739/... .Deklaracja: „Gdzieś istnieje foo”.
Definicja: „... i oto jest!”
źródło
W C ++ są interesujące przypadki krawędzi (niektóre z nich również w C). Rozważać
Może to być definicja lub deklaracja, w zależności od typu
T
:W C ++, gdy używasz szablonów, istnieje inny przypadek krawędzi.
Ostatnia deklaracja nie była definicją. Jest to deklaracja wyraźnej specjalizacji statycznego członka
X<bool>
. Mówi kompilatorowi: „Jeśli chodzi o tworzenie instancjiX<bool>::member
, nie twórz instancji definicji elementu członkowskiego z podstawowego szablonu, ale użyj definicji znalezionej gdzie indziej”. Aby była to definicja, musisz podać inicjatorźródło
Deklaracja
Definicja
źródło
class foo {};
czy to definicja klasy , prawda?Ze standardu C99 6,7 (5):
Deklaracja określa interpretację i atrybuty zestawu identyfikatorów. Definicja identyfikatora jest deklaracja dla tego identyfikatora, że:
Ze standardu C ++ 3.1 (2):
Deklaracja jest definicją, chyba że deklaruje funkcję bez określania treści funkcji, zawiera specyfikator zewnętrzny lub specyfikację powiązania i nie jest inicjatorem ani ciałem funkcji, deklaruje element danych statycznych w deklaracji klasy, jest to deklaracja nazwy klasy lub deklaracja typedef, deklaracja użycia lub dyrektywa użytkowania.
Następnie jest kilka przykładów.
Tak interesująco (lub nie, ale jestem nieco zaskoczony),
typedef int myint;
to definicja w C99, ale tylko deklaracja w C ++.źródło
typedef
, czy to nie znaczy, że można to powtórzyć w C ++, ale nie w C99?Z wiki.answers.com:
Termin deklaracja oznacza (w C), że informujesz kompilator o typie, rozmiarze, aw przypadku deklaracji funkcji, typie i rozmiarze jej parametrów dowolnej zmiennej lub typu lub funkcji zdefiniowanej przez użytkownika w twoim programie. W deklaracji nie ma miejsca w pamięci dla żadnej zmiennej. Jednak kompilator wie, ile miejsca zarezerwować, na wypadek utworzenia zmiennej tego typu.
na przykład następujące są wszystkie deklaracje:
Z drugiej strony definicja oznacza, że oprócz wszystkich rzeczy, które robi deklaracja, miejsce jest również zarezerwowane w pamięci. Możesz powiedzieć „DEFINICJA = DEKLARACJA + REZERWACJA PRZESTRZENI” poniżej to przykłady definicji:
patrz odpowiedzi .
źródło
struct foo {};
to definicja , a nie deklaracja. Deklaracjafoo
byłabystruct foo;
. Na tej podstawie kompilator nie wie, ile miejsca zarezerwować dlafoo
obiektów.struct foo;
jest deklaracją, ale nie informuje kompilatora o wielkości foo. Dodałbym, żestruct _tagExample { int a; int b; };
to definicja. Dlatego w tym kontekście mylące jest nazywanie tego deklaracją. Oczywiście jest jedna, ponieważ wszystkie definicje są deklaracjami, ale wydaje się, że sugerujesz, że nie jest to definicja. Jest to definicja _tagExample.Aktualizacja C ++ 11
Ponieważ nie widzę odpowiedzi dotyczącej C ++ 11, oto jedna.
Deklaracja jest definicją, chyba że deklaruje a / n:
enum X : int;
template<typename T> class MyArray;
int add(int x, int y);
using IntVector = std::vector<int>;
static_assert(sizeof(int) == 4, "Yikes!")
;
Dodatkowe klauzule odziedziczone po C ++ 03 z powyższej listy:
int add(int x, int y);
extern int a;
lubextern "C" { ... };
class C { static int x; };
struct Point;
typedef int Int;
using std::cout;
using namespace NS;
Deklaracja szablonu jest deklaracją. Deklaracja szablonu jest również definicją, jeśli jej deklaracja definiuje funkcję, klasę lub element danych statycznych.
Przykłady ze standardu, który odróżnia deklarację od definicji, które okazały się pomocne w zrozumieniu niuansów między nimi:
źródło
Definicja:
Definicja kojarzy zmienną z typem i przydziela pamięć, podczas gdy deklaracja tylko określa typ, ale nie przydziela pamięci. Deklaracja jest bardziej przydatna, gdy chcesz odwołać się do zmiennej przed definicją.
* Nie myl definicji z inicjalizacją. Oba są różne, inicjalizacja nadaje wartość zmiennej. Zobacz powyższy przykład.
Poniżej podano kilka przykładów definicji.
Teraz deklaracja funkcji:
Zwróć uwagę na średnik na końcu funkcji, więc jest to tylko deklaracja. Kompilator wie, że gdzieś w programie funkcja ta zostanie zdefiniowana za pomocą tego prototypu. Teraz, jeśli kompilator otrzyma funkcję, należy wywołać coś takiego
Kompilator zgłosi błąd informujący, że nie ma takiej funkcji. Ponieważ nie ma żadnego prototypu dla tej funkcji.
Zwróć uwagę na różnicę między dwoma programami.
Program 1
W tym zadeklarowana i zdefiniowana jest również funkcja drukowania. Ponieważ wywołanie funkcji przychodzi po definicji. Teraz zobacz następny program.
Program 2
Jest to niezbędne, ponieważ wywołanie funkcji poprzedza definicję, więc kompilator musi wiedzieć, czy istnieje taka funkcja. Dlatego deklarujemy funkcję, która poinformuje kompilator.
Definicja:
Ta część definiowania funkcji nazywa się Definicja. Mówi, co robić wewnątrz funkcji.
źródło
int a; //declaration; a=10; //definition
To jest całkowicie błędne. Kiedy mówimy o obiektach automatycznego czasu przechowywania (obiekty zadeklarowane w definicji funkcji, które nie są zadeklarowane innym specyfikatorem klasy pamięci, takim jak extern), są to zawsze definicje.definicja oznacza zapisaną rzeczywistą funkcję, a deklaracja oznacza prostą funkcję deklarującą np
i
to jest definicja funkcji myfunction
źródło
Praktyczna zasada:
Deklaracja informuje kompilator, jak interpretować dane zmiennej w pamięci. Jest to potrzebne przy każdym dostępie.
Definicja rezerwuje pamięć, aby zmienna istniejących. To musi się zdarzyć dokładnie raz przed pierwszym dostępem.
źródło
Aby zrozumieć rzeczowniki, najpierw skupmy się na czasownikach.
deklarować - ogłaszać oficjalnie; głosić
Zdefiniuj - aby pokazać lub opisać (ktoś lub coś) jasno i całkowicie
Więc kiedy coś deklarujesz, po prostu mówisz, co to jest .
Ta linia deklaruje wywołaną funkcję C,
sum
która pobiera dwa argumenty typuint
i zwraca anint
. Jednak nie możesz go jeszcze użyć.Kiedy podajesz, jak to naprawdę działa , to jest to jego definicja.
źródło
Aby zrozumieć różnicę między deklaracją a definicją, musimy zobaczyć kod asemblera:
a to tylko definicja:
Jak widać nic się nie zmienia.
Deklaracja różni się od definicji, ponieważ zawiera informacje używane tylko przez kompilator. Na przykład uint8_t mówi kompilatorowi, aby używał funkcji asm movb.
Zobaczyć, że:
Deklaracja nie ma równoważnej instrukcji, ponieważ nie można jej wykonać.
Ponadto deklaracja informuje kompilator o zakresie zmiennej.
Można powiedzieć, że deklaracja jest informacją używaną przez kompilator do ustalenia poprawnego użycia zmiennej i czasu, przez jaki część pamięci należy do określonej zmiennej.
źródło
Czy nie można powiedzieć w sposób najbardziej ogólny, że deklaracja jest identyfikatorem, w którym pamięć nie jest przydzielana, a definicja faktycznie alokuje pamięć od zadeklarowanego identyfikatora?
Jedna interesująca myśl - szablon nie może przydzielić pamięci, dopóki klasa lub funkcja nie zostaną połączone z informacjami o typie. Czy identyfikator szablonu jest deklaracją czy definicją? Powinna to być deklaracja, ponieważ nie przydzielono pamięci, a Ty po prostu „prototypujesz” klasę lub funkcję szablonu.
źródło
template<class T> struct foo;
jest to deklaracja szablonu , podobnie jak totemplate<class T> void f();
. Definicje szablonów odzwierciedlają definicje klas / funkcji w ten sam sposób. (Pamiętaj, że nazwa szablonu nie jest nazwą typu ani funkcji . Jednym z miejsc, w których można to zobaczyć, jest to, że nie można przekazać szablonu jako parametru typu innego szablonu. Jeśli chcesz przekazać szablony zamiast typów, potrzebujesz parametrów szablonu szablonu. )Znajdź podobne odpowiedzi tutaj: Wywiad Pytania techniczne w C .
Deklaracja stanowi nazwę do programu; definicji zapewnia unikalny opis jednostki (na przykład typu, przykład i) w funkcji programu. Deklaracje mogą się powtarzać w danym zakresie, wprowadza nazwę w danym zakresie.
Deklaracja jest definicją, chyba że:
Definicja jest deklaracją, chyba że:
źródło
To zabrzmi naprawdę kiepsko, ale to najlepszy sposób, w jaki udało mi się zachować proste warunki w mojej głowie:
Deklaracja: Obraz Thomas Jefferson wygłasza przemówienie ... „OŚWIADCZAM, ŻE TO GŁOWIE ISTNIEJE W KODZIE ŹRÓDŁA !!!”
Definicja: wyobraź sobie słownik, szukasz Foo i co to właściwie znaczy.
źródło
Deklaracja przedstawia kompilatorowi nazwę symbolu. Definicja to deklaracja, która przydziela miejsce dla symbolu.
źródło
Zgodnie z podręcznikiem biblioteki GNU C ( http://www.gnu.org/software/libc/manual/html_node/Header-Files.html )
źródło
Pojęcie Deklaracja i definicja będzie stanowić pułapkę, gdy używasz zewnętrznej klasy pamięci, ponieważ twoja definicja będzie w innym miejscu i deklarujesz zmienną w lokalnym pliku kodu (stronie). Jedną różnicą między C i C ++ jest to, że w C deklaracje są wykonywane normalnie na początku funkcji lub strony kodowej. W C ++ tak nie jest. Możesz zadeklarować w wybranym przez siebie miejscu.
źródło
Moim ulubionym przykładem jest „int Num = 5” tutaj twoja zmienna jest 1. zdefiniowana jako int 2. zadeklarowana jako Num i 3. utworzona instancja z wartością pięciu. My
Klasa lub struktura pozwala zmienić sposób definiowania obiektów, gdy zostaną później użyte. Na przykład
Kiedy uczymy się programowania, te dwa terminy są często mylone, ponieważ często robimy oba jednocześnie.
źródło
Etapy generowania wykonywalnego:
W etapie 2 (tłumacz / kompilator) instrukcje deklaracji w naszym kodzie informują kompilator, że tych rzeczy będziemy używać w przyszłości, a definicję można znaleźć później:
i (3) etap (linker) potrzebuje definicji, aby powiązać rzeczy
źródło
W K&R (2. edycja) istnieje kilka bardzo wyraźnych definicji; pomaga umieścić je w jednym miejscu i czytać je jako jedno:
źródło
Deklaracja oznacza podanie nazwy i typu zmiennej (w przypadku deklaracji zmiennej), np .:
lub podaj nazwę, typ zwracany i typ parametru (parametrów) funkcji bez treści (w przypadku deklaracji funkcji), np .:
podczas gdy definicja oznacza przypisanie wartości do zmiennej (w przypadku definicji zmiennej), np .:
lub dostarczenie / dodanie treści (funkcji) do funkcji nazywa się definicją funkcji, np .:
wiele deklaracji czasowych i definicji można wykonać razem jako:
i:
W powyższych przypadkach definiujemy i deklarujemy zmienne
i
ifunction max()
.źródło
int x;