@Kostya: moja kopia K&R (najwcześniejszy opis języka C, jaki mam) jest bardzo odległa i nie mogę jej teraz sprawdzić, ale jestem w 110% pewna, że sizeofzasadniczo opisuje to samo, co C99 Standard dzisiaj. sizeofjest dostępny, zanim C został znormalizowany przez ANSI w 1989 r.
pmg
Odpowiedzi:
120
Zgodnie z 6.5.3 istnieją dwa formularze sizeof:
sizeof unary-expression
sizeof( type-name )
Ponieważ arrw twoim kodzie jest a type-name, musi być umieszczony w nawiasach.
+1 i, żeby podkreślić, że sizeofjest to operator: nawias „należy” do typu, a nie do operatora.
pmg
@pmg: Dzięki za wyjaśnienie! Tak, jak wspomniałeś, standard oznacza sizeofoperatora.
Ise Wisteria
4
@pmg: Nie wydaje mi się, żeby było jasne, do czego „należą” nawiasy. Składni drugiej postaci składa się z trzech znaczników i jeden nie-końcowy: sizeof ( type-name ). Ale dla pierwszej postaci, to może napisać, na przykład, sizeof(x)i choć wygląda wywołania funkcji (jeśli sizeofnie były kluczowe), to naprawdę operator stosowane do ekspresji w nawiasy. Czy to miałeś na myśli?
Keith Thompson,
3
Chodzi mi o to, że sizeofsyntaktycznie sizeof <SOMETHING>w przeciwieństwie do funkcji, na przykład a, printfktóre jest printf ( <SOMETHING> ). Nawiasy należą do, printfale nie do sizeof. Kiedy sizeofjest stosowany do nazwy typu w nawiasach, lubię myśleć o tym jako o rzucie niczego - „zwracaniu” tylko typu.
pmg,
2
@pmg: Z pewnością możesz o tym myśleć w ten sposób, ale uważam to za mylące. Jedynym prawdziwym podobieństwem do rzutowania jest to, że ma nazwę typu w nawiasach, a to tylko zbieg okoliczności ze składniowej wygody. Wolę myśleć o tym sizeof ( type-name )jako o swoim własnym rodzaju ekspresji. (Standard nazywa go operatorem, ale ( type-name )tak naprawdę nie jest operandem w zwykłym sensie).
Keith Thompson,
44
W ten sposób określa się język, nazwy typów muszą być tutaj umieszczone w nawiasach.
Załóżmy, że gramatyka wyglądała tak:
sizeof unary-expressionsizeof type-name
Teraz np. Następujące wyrażenie byłoby niejednoznaczne:
sizeofint * + 0
Może to być albo sizeof(int *) + 0albosizeof(int) * +0 . Ta niejednoznaczność nie występuje w przypadku wyrażeń jednoargumentowych, ponieważ gwiazdka dołączona do wyrażenia nie jest wyrażeniem (ale w przypadku niektórych nazw typów dołączenie jednego jest ponownie nazwą typu).
Coś musiało zostać tutaj określone, a wymaganie, aby nazwy typów były umieszczane w nawiasach, jest sposobem na rozwiązanie niejednoznaczności.
Myślę, że to dlatego, że masz typedef. Jeśli go usuniesz, powinien się skompilować.
Przykład z wikipedii:
/* the following code fragment illustrates the use of sizeof
* with variables and expressions (no parentheses needed),
* and with type names (parentheses needed)
*/char c;
printf("%zu,%zu\n", sizeof c, sizeof (int));
sizeof
zasadniczo opisuje to samo, co C99 Standard dzisiaj.sizeof
jest dostępny, zanim C został znormalizowany przez ANSI w 1989 r.Odpowiedzi:
Zgodnie z 6.5.3 istnieją dwa formularze
sizeof
:sizeof unary-expression sizeof ( type-name )
Ponieważ
arr
w twoim kodzie jest atype-name
, musi być umieszczony w nawiasach.źródło
sizeof
jest to operator: nawias „należy” do typu, a nie do operatora.sizeof
operatora.sizeof ( type-name )
. Ale dla pierwszej postaci, to może napisać, na przykład,sizeof(x)
i choć wygląda wywołania funkcji (jeślisizeof
nie były kluczowe), to naprawdę operator stosowane do ekspresji w nawiasy. Czy to miałeś na myśli?sizeof
syntaktyczniesizeof <SOMETHING>
w przeciwieństwie do funkcji, na przykład a,printf
które jestprintf ( <SOMETHING> )
. Nawiasy należą do,printf
ale nie dosizeof
. Kiedysizeof
jest stosowany do nazwy typu w nawiasach, lubię myśleć o tym jako o rzucie niczego - „zwracaniu” tylko typu.sizeof ( type-name )
jako o swoim własnym rodzaju ekspresji. (Standard nazywa go operatorem, ale( type-name )
tak naprawdę nie jest operandem w zwykłym sensie).W ten sposób określa się język, nazwy typów muszą być tutaj umieszczone w nawiasach.
Załóżmy, że gramatyka wyglądała tak:
sizeof unary-expression
sizeof type-name
Teraz np. Następujące wyrażenie byłoby niejednoznaczne:
sizeof int * + 0
Może to być albo
sizeof(int *) + 0
albosizeof(int) * +0
. Ta niejednoznaczność nie występuje w przypadku wyrażeń jednoargumentowych, ponieważ gwiazdka dołączona do wyrażenia nie jest wyrażeniem (ale w przypadku niektórych nazw typów dołączenie jednego jest ponownie nazwą typu).Coś musiało zostać tutaj określone, a wymaganie, aby nazwy typów były umieszczane w nawiasach, jest sposobem na rozwiązanie niejednoznaczności.
źródło
Myślę, że to dlatego, że masz
typedef
. Jeśli go usuniesz, powinien się skompilować.Przykład z wikipedii:
/* the following code fragment illustrates the use of sizeof * with variables and expressions (no parentheses needed), * and with type names (parentheses needed) */ char c; printf("%zu,%zu\n", sizeof c, sizeof (int));
źródło