Niedawno przystąpiłem do testu programowania dla średnio zaawansowanych i jedno z pytań, które pomyliłem, brzmiało następująco:
Po deklaracji funkcji nie jest potrzebny średnik („;”).
Prawda czy fałsz.
Wybrałem „fałsz” (i popraw mnie, jeśli się mylę, ponieważ czuję, że oszalałem), deklaracja funkcji jest tym, co piszesz przed definicją (na górze kodu), aby kompilator znał funkcję call jeszcze przed jej wywołaniem, a definicja funkcji jest tym, co składa się na funkcję jako całość.
To znaczy,
Deklaracja:
int func();
Definicja:
int func() {
return 1;
}
Czy odpowiedź na to pytanie nie powinna być fałszywa?
c++
function
syntax
declaration
Logan
źródło
źródło
Odpowiedzi:
Możesz mieć sytuację, w której deklarujesz i definiujesz funkcję w jednym kroku, tj. Jeśli umieścisz definicję funkcji w miejscu, w którym ją deklarujesz. Więc technicznie myślę, że prawda jest poprawna. Ale pytanie jest sformułowane w taki sposób, że odpowiedziałbym na nie tak, jak ty.
źródło
Oprócz tego, że „definicja jest również deklaracją”, poniżej przedstawiono poprawne C ++:
To deklaruje dwie funkcje
f
ig
obie bez argumentów i ze zwracanym typemint
, ale po definicjif
nie występuje (natychmiast) średnik. Podobnie jest to legalne:Ale w rzeczywistości nie jest dozwolone całkowite pominięcie średnika w tych przypadkach, więc byłoby nieco zaskakujące, gdyby jeden z nich został wzięty jako przykład deklaracji bez następującego średnika. W rzeczywistości następujące działania są nielegalne:
Inaczej niż (zwykła) deklaracja funkcji, definicji funkcji nie można łączyć z żadną inną deklaracją lub definicją do tego samego specyfikatora typu . (Gdyby to było zgodne z prawem, zdefiniowałoby zarówno a, jak
void *p
i avoid f() {}
.)W każdym razie wydaje się, że jest to pytanie typu „gotcha”, które nie powinno być przedmiotem pośredniego testu programowania.
(A tak przy okazji, proszę nie pisać takiego kodu
int f(), i = 42;
).źródło
typedef int fooProc(int); fooProc a,b.c.d.e;
Nie jestem pewien, dlaczego standardowe nagłówki dla kompilatorów opartych na dyskietkach nie robiły tego w dnia, ponieważ wydaje mi się, że pozwoliłoby to plikom nagłówkowym na znacznie mniejsze, a tym samym szybsze przetwarzanie.int f(int(&g)(),int(*h)()){return g()+h();}
To ma trzy deklaracje funkcji, z których po jednej następuje otwarty nawias klamrowy, po drugiej przecinek, a po trzeciej zamknięty nawias.int f(stuff)
. Nawet w zakresie funkcjig
jest automatyczną zmienną typu odniesienia do funkcji ih
jest wskaźnikiem do funkcji .Inne odpowiedzi i komentarze wskazują na kilka z wielu sposobów, na jakie jest to okropne, mylące i źle napisane pytanie. Ale jest inny problem, którego nikt inny jeszcze nie zidentyfikował. Pytanie brzmi:
OK, spójrzmy na deklarację funkcji:
To wszystko jest deklaracją . Deklaracja nie jest
int func()
, a potem następuje;
. Deklaracja jestint func();
zakończona białymi znakami.Pytanie brzmi więc: czy po deklaracji potrzebny jest średnik ? Oczywiście nie. Deklaracja zawiera już średnik, który ją kończy. Średnik po deklaracji byłby bezcelowy. Z
int func(); ;
kolei po deklaracji funkcji byłby średnik .Pytanie prawie na pewno miało na celu zadanie pytania „prawda czy fałsz: ostatnim tokenem w deklaracji funkcji jest zawsze średnik”. Ale to nie jest pytanie, które napisali, ponieważ autor quizu nie myślał jasno o problemie.
Radzę całkowicie unikać quizów z języka programowania. Są okropne.
Zabawny fakt, skoro już jesteśmy na ten temat. W C # to wszystko jest legalne:
W języku C # deklaracja klasy lub struktury może kończyć się średnikiem lub nie, według własnego uznania. Ta dziwna mała funkcja została dodana z korzyścią dla programistów C / C ++ przybywających do C #, którzy mają na wyciągnięcie ręki, że deklaracje typu kończą się bezcelowym średnikiem; zespół projektantów nie chciał ich karać za ten nawyk. :-)
źródło
Możesz również zadeklarować taką funkcję:
Stwierdzenie jest bardzo niejednoznaczne. Prawidłowa odpowiedź powinna brzmieć: to zależy od tego, jak zadeklarujesz funkcję.
W każdym razie wybrałbym też fałsz i może możesz zgłosić komuś pytanie.
źródło
Prawda . Po żadnej deklaracji nie jest potrzebny średnik. Ani po żadnej definicji. Ani po żadnym oświadczeniu.
Wiele rodzajów deklaracji musi kończyć się średnikiem, jak określa składnia w sekcji 7 [dcl.dcl]. Ale po tym nigdy nie ma potrzeby pisać drugiego.
źródło
Zależy to od tego, czy deklarujemy, czy definiujemy funkcję. Jeśli deklarujemy funkcję, musimy dołączyć średnik (
;
), a jeśli definiujemy funkcję, średnik nie jest potrzebny.Deklaracja wygląda tak:
A definicja jest taka:
źródło
Chociaż zgadzam się z prawie wszystkimi pozostałymi odpowiedziami, stwierdzając, że pytanie jest sformułowane bardzo niejednoznacznie, a twoja odpowiedź jest poprawna technicznie, pozwól mi przyjąć inną perspektywę:
Tak je zawsze nazywałam:
Zakładam, że pytanie zostało sformułowane z myślą o tej terminologii.
Definicja i deklaracja to dla mnie ta sama koncepcja. "Definiuję x = y" == "Deklaruję x = y".
Ale oczywiście istnieje duża różnica między prototypem funkcji (na górze) a rzeczywistą definicją funkcji.
źródło
void func();
są dokładnie równoważne zvoid func(void);
. To bardzo różni się od C , gdzievoid func();
nie mówi kompilatorowi nic o argumentach i nie jest tym samym, covoid func(void);
. Późniejszy prototyp lub definicja są dobrym pomysłem, w przeciwnym razie wywołujący musi zastosować domyślne promocje arg (np. Float -> double i wąskie typy całkowite doint
. Te same zasady, co dla argumentów do funkcji wariadycznych).Szkoda, że pytanie, które zadałeś, nie mówi „bezpośrednio po”. Moglibyśmy na przykład napisać to:
Albo mógłbym napisać:
W pierwszym przypadku średnik nie znajduje się bezpośrednio po deklaracji, ale byłoby OK.
W drugim przypadku średnik znajduje się „po” zgłoszeniu, ale nie bezpośrednio po nim.
Myślę, że Eric Lippert ma słuszny pomysł w swojej odpowiedzi .
To tak, jakby powiedzieć „czy po angielsku powinna być kropka?”. Prawdopodobnie zdanie ma już na końcu kropkę (w przeciwnym razie nie byłoby to zdanie) i dlatego po zdaniu nie powinno być kropki.
źródło
int func() int a=42;
nie kompiluje się. Potrzebujesz przecinka, a nie innegoint
. Zobacz odpowiedź @ Arne opublikowaną dzień wcześniej. Jedyną nowością w tej odpowiedzi jest ostatni akapit, z analogią do zdań angielskich.Możesz używać
;
tylko do prototypów.źródło
To trochę trudne pytanie, ale użyli deklaracji słowa, które oznacza coś takiego:
Więc to prawda w tym przypadku.
Gdyby użyli słowa „ implementacja”, to byłoby fałszywe.
źródło
Średnik (;) służy do informowania kompilatora, że po tym średniku (;) rozpoczyna się nowa instrukcja.
Myślę więc, że średnik (;) jest wymagany tylko podczas deklaracji funkcji. Więc według mnie odpowiedź będzie prawdziwa.
źródło
Gdy funkcje są zdefiniowane przed main () :
Gdy funkcje są zdefiniowane po main () :
źródło