Dlaczego jest sizeof
uważany za operator, a nie funkcję?
Jaka właściwość jest konieczna, aby zostać operatorem?
Odpowiedzi:
Ponieważ norma C tak mówi i otrzymuje jedyny głos.
Jako konsekwencje:
sizeof (int)
zamiast wyrażeniem obiektowym.int a; printf("%d\n", sizeof a);
porządku. Są często widoczne, po pierwsze dlatego, że są potrzebne jako część wyrażenia rzutowania typu, a po drugie, ponieważ sizeof ma bardzo wysoki priorytet, więc sizeof a + b
nie jest tym samym, co sizeof (a+b)
. Ale nie są częścią wywołania sizeof, są częścią operandu.sizeof a++
nie modyfikuje a).Funkcja różniłaby się we wszystkich tych punktach. Prawdopodobnie istnieją inne różnice między funkcją a operatorem jednoargumentowym, ale myślę, że to wystarczy, aby pokazać, dlaczego sizeof nie może być funkcją, nawet jeśli istniał powód, aby tak było.
sizeof
na efekty uboczne, jeśli w wyrażeniu jest VLA.
sizeof
: sizeof unary-expression
i sizeof ( type-name )
- tak więc w standardzie C11 nie jest uważany za „rzutowanie”, ale nazwę typu w nawiasach. Wynik netto jest bardzo podobny. (Dla porównania, wyrażenie to ( type-name ) cast-expression
.) I nienawidzę tego, że komentarz Markdown działa inaczej niż Q&A Markdown!
Może być używany jako stała czasu kompilacji, co jest możliwe tylko wtedy, gdy jest operatorem, a nie funkcją. Na przykład:
union foo {
int i;
char c[sizeof(int)];
};
Składniowo, gdyby nie był to operator, musiałoby to być makro preprocesora, ponieważ funkcje nie mogą przyjmować typów jako argumentów. Byłoby to trudne do zaimplementowania makro, ponieważ sizeof
może przyjmować zarówno typy, jak i zmienne jako argument.
Ponieważ norma C tak mówi i otrzymuje jedyny głos.
A standard jest prawdopodobnie poprawny, ponieważ sizeof
przyjmuje typ i
Ogólnie rzecz biorąc, jeśli domena lub kodomena (lub obie) funkcji zawiera elementy znacznie bardziej złożone niż liczby rzeczywiste, funkcja ta jest określana jako operator. I odwrotnie, jeśli ani domena, ani kodomena funkcji nie zawierają elementów bardziej skomplikowanych niż liczby rzeczywiste, funkcja ta będzie prawdopodobnie nazywana po prostu funkcją. Funkcje trygonometryczne, takie jak cosinus, są przykładami tego ostatniego przypadku.
Dodatkowo, gdy funkcje są używane tak często, że ewoluowały szybciej lub łatwiej niż ogólna forma F (x, y, z, ...), wynikające z nich formy specjalne są również nazywane operatorami. Przykłady obejmują operatory wrostkowe, takie jak dodawanie „+” i dzielenie „/”, oraz operatory przyrostków, takie jak silnia „!”. To użycie nie ma związku ze złożonością zaangażowanych podmiotów.
Ponieważ to nie jest funkcja. Możesz go używać w ten sposób:
int a;
printf("%d\n", sizeof a);
Funkcja ma punkt wejścia, kod itp. Funkcja ma być uruchamiana w czasie wykonywania (lub wbudowana), sizeof musi być określone w czasie kompilacji.
Operator sizeof jest jednostką czasu kompilacji, a nie uruchomieniem i nie potrzebuje nawiasów jak funkcja. Kiedy kod jest kompilowany, zastępuje wartość rozmiarem tej zmiennej w czasie kompilacji, ale w funkcji po wykonaniu funkcji będziemy znać zwracaną wartość.
Dlatego:
sizeof
„funkcja” nie miałaby możliwości określenia rozmiaruJest mała różnica w stosunku do funkcji - wartość sizeof jest rozwiązywana w czasie kompilacji, ale nie w czasie wykonywania!
Ponieważ jest to operator czasu kompilacji, który w celu obliczenia rozmiaru obiektu wymaga informacji o typie, które są dostępne tylko w czasie kompilacji. To nie dotyczy C ++.
Sizeof (), myślę, że oczywiście jest to zarówno funkcja, jak i operator. Czemu? Ponieważ funkcja zawiera nawiasy do wpisywania na etapie wprowadzania. Ale głównie operatory powodują, że operatory są znakami akcji, dlatego sizeof jest instrukcją akcji, która działa na operandzie w nawiasach.