sizeof biorąc dwa argumenty
W C. 1. 3 C++ IS (2003. Jest w C++11 jest, too), standard wskazuje na różnicę między ISO C i C++; mianowicie, dla
char arr[100];
sizeof(0, arr)
zwraca sizeof(char*)
W C, ale 100
w C++.
Nie mogę znaleźć dokumentacji sizeof
biorąc dwa argumenty. Oczywistym zaletą jest operator przecinka, ale nie sądzę: sizeof(arr)
W C jest 100
; sizeof(0, arr)
is sizeof(char*)
. Zarówno sizeof(0, arr)
jak i sizeof(arr)
są 100
W C++.
Mogę pominąć cały sens IS w tym kontekście. Can ktoś pomoże? Jest to podobne do pytania omawianego w 2009 roku, ale nikt nie odniósł się do IS i nie sądzę, aby została udzielona prawidłowa odpowiedź.
Edit: właściwie, IS mówi o operatorze przecinka. Z jakiegoś powodu (0, arr)
zwraca char*
W C, ale char[100]
W C++. Dlaczego?
7 answers
W C Tablica rozkłada się do wskaźnika, ze względu na inną specyfikację operatora przecinka w odniesieniu do wartości R i lvalues (nie jedyne miejsce, gdzie można znaleźć taką różnicę). W C++ Tablica pozostaje tablicą, dając prawidłowy wynik.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-13 14:16:01
W C operator przecinka nie wytwarza lvalue, w konsekwencji tablica arr
, która jest lvalue rozpada się na typ wskaźnika, który jest rvalue (w tym przypadku). Tak więc sizeof(0,arr)
staje się równoważne sizeof(char*)
, ze względu na konwersję lvalue-to-rvalue.
Ale w C++ operator przecinka tworzy lvalue. Nie ma konwersji lvalue-to-rvalue . Więc sizeof(0,arr)
pozostaje taka sama, co jest równoważne sizeof(char[100])
.
Przy okazji, sizeof
nie jest funkcją, jest operatorem. Tak więc poniższe jest całkowicie poprawne C++ (i C, jeśli sobie wyobrazić printf
zamiast cout
):
int a[100], b[200], c[300], d[400];
cout << sizeof(a,b,c,d) << endl;
Demo: http://www.ideone.com/CtEhn
Możesz pomyśleć, że przekazałem 4 operandy dosizeof
, ale to jest złe. sizeof
operuje na wyniku operatorów przecinków. I to z powodu wielu operatorów przecinków widzisz wiele operandów.
4 operandy z 3 operatorami przecinkowymi; podobnie jak w 1+2+3+4
, są 3 operatory, 4 operandy.
The powyższe jest równoważne następującym (poprawnym w C++0x):
auto & result = (a,b,c,d); //first all comma operators operate on the operands.
cout << sizeof (result) << endl; //sizeof operates on the result
Demo: http://www.ideone.com/07VNf
Więc to przecinek operator sprawia, że czujesz, że istnieje wiele argumentów. Tutaj comma jest operatorem, ale w wywołaniu funkcji comma nie jest operatorem, jego zwykłym separatorem argumentów.
function(a,b,c,d); //here comma acts a separator, not operator.
Więc sizeof(a,b,c,d)
Działa na typie wyniku ,
operatorów, dokładnie w tym samym sposób, sizeof(1+2+3+4)
działa na typie wyniku operatorów +
.
Zauważ również, że nie możesz napisać sizeof(int, char, short)
, właśnie dlatego, że przecinek operator nie może operować na typach . Działa tylko na wartość. Myślę, że {[8] } jest jedynym operatorem w C i C++, który może działać również na typach . W C++ istnieje jeszcze jeden operator, który może operować na typach . Jego nazwa to typeid
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-12 08:26:25
Jest operatorem przecinkowym. A różnica, o której mówisz, nie ma absolutnie nic wspólnego z sizeof
. Różnica jest tak naprawdę w lvalue-to-rvalue, array-to-pointer i podobnych zachowaniach rozpadu między językami C i C++.
Język C jest pod tym względem dość korzystny: tablice rozpadają się na wskaźniki praktycznie natychmiast (z wyjątkiem bardzo niewielu specyficznych kontekstów), dlatego wynik wyrażenia 0, arr
mA typ char *
. Jest odpowiednikiem 0, (char *) arr
.
W języku C++ tablice zachowują "tablice" znacznie dłużej. W przypadku użycia w kontekście ,
tablice operatorów nie rozpadają się na wskaźniki (a wartości LV nie rozpadają się na wartości R), dlatego w C++ typ wyrażenia 0, arr
jest nadal char[100]
.
To wyjaśnia różnicę w zachowaniu sizeof
w tym przykładzie. ?:
operator jest kolejnym przykładem operatora, który demonstruje podobną różnicę w zachowaniu rozkładu, tzn. sizeof(0 ? arr : arr)
Da różne wyniki w C i C++. Zasadniczo wynika to z faktu, że operatory C zwykle nie zachowują wartości swoich operandów. Do zademonstrowania takiego zachowania można użyć wielu operatorów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-13 17:23:59
To nie jest sizeof
przyjmowanie dwóch argumentów. sizeof
jest operatorem, a nie funkcją.
Weź pod uwagę, że (0, arr)
jest wyrażeniem używającym operatora przecinka, a Wszystko inne wypada na swoje miejsce.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-13 14:18:32
sizeof
nie wymaga dwóch argumentów. Ale to też nie jest funkcja,
więc (...)
nie rozgraniczają argumentów funkcji, są tylko
opcjonalna część składni i wymuszenie grupowania. Kiedy piszesz
sizeof(0, arr)
, argument do sizeof
jest pojedynczym wyrażeniem 0,
arr
. Pojedyncze wyrażenie z operatorem przecinka, które ocenia
wyrażenie na lewo od przecinka, wyrzuca jego wartość (ale nie jego
skutki uboczne), następnie oblicza wyrażenie na prawo od przecinka,
i wykorzystuje swoją wartość jako wartość pełnego wyrażenia.
Nie jestem pewien co do C, ale to może być różnica między
langauges. W C++ konwersja tablicy na wskaźnik nie zachodzi, chyba że
jest potrzebne; w C, O ile dobrze pamiętam, standard mówi, że to
zawsze odbywa się z wyjątkiem pewnych kontekstów. W tym jako
operator sizeof
. W tym przypadku, ponieważ operator przecinka nie
mieć ograniczenia w odniesieniu do rodzajów jego operandów,
konwersja tablicy na wskaźnik nie ma miejsca w C++. W C, an
operatand operatora przecinka nie jest wymieniony w wyjątkach, więc
konwersja tablicy na wskaźnik ma miejsce. (W tym przypadku tablica
jest operandem operatora przecinka, a nie sizeof
.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-13 14:44:58
Najlepszym sposobem, aby zobaczyć, co może się tutaj dziać, jest spojrzenie na gramatykę w standardzie. Jeśli spojrzymy na wersję standardową C99 6.5.3
operatory jednoargumentowe paragraf 1 możemy zauważyć, że gramatyka dla sizeof to:
sizeof unary-expression
sizeof ( type-name )
Więc drugi nie ma zastosowania, ale jak ma zastosowanie sizeof unary-expression
w tym przypadku? Jeśli spojrzymy na sekcję A.2.1
wyrażenia ze standardu szkicu i działają przez gramatykę w ten sposób:
unary-expression -> postfix-expression -> primary-expression -> ( expression )
Otrzymujemy nawiasy wokół wyrażenie i teraz wystarczy spojrzeć na gramatykę operator przecinka z sekcji 6.5.17
operator Przecinka i widzimy:
expression:
assignment-expression
expression , assignment-expression
Więc mamy teraz:
sizeof( expression , assignment-expression )
^
|
comma operator
Zarówno wyrażenie jak i assignment-expression mogą doprowadzić nas do primary-expression , które ma następującą gramatykę:
primary-expression:
identifier
constant
string-literal
( expression )
And 0
is a constant and arr
is a identifier so we mieć:
sizeof( constant , identifier )
Więc co robi operator przecinka tutaj? Sekcja 6.5.17
akapit 2 says:
Lewy operand operatora przecinka jest oceniany jako wyrażenie void; jest punkt sekwencji po jego ocenie. Następnie jest obliczany właściwy operand; wynik ma swój typ i wartość.97)
Ponieważ operator przecinka nie jest jednym z WYJĄTKÓW, gdzie tablica nie jest konwertowana na wskaźnik, daje pointer (jest to opisane w sekcji 6.3.2.1
Lvalues, arrays, and function designators ), co oznacza, że kończymy na:
sizeof( char * )
W C++ gramatyka jest dość podobna, więc kończymy w tym samym miejscu, ale operatory przecinków działają inaczej. Sekcja C++ draft standard5.18
operator Przecinka mówi:
[...] Typ i wartość wyniku są typem i wartością prawego operandu; wynik należy do tej samej kategorii wartości, co jej prawy operand[...]
Więc i array-to-pointer konwersja nie jest wymagana i tak kończymy na:
sizeof( char[100] )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-26 04:45:27
Jak już kilka osób powiedziało, i chcę dodać tylko jedną rzecz, sizeof jest operatorem przyjmującym wyrażenie lub wyrażenie cast. Z tego powodu wziąłem zwyczaj pisania parantezy do wielkości tylko, jeśli jest wyrażeniem odlewanym.
char *arr;
struct xxx { ... } v;
Napiszę
sizeof arr
sizeof v
Ale
sizeof (struct xxx) /* Note the space after the sizeof, it's important */
sizeof (char *)
Robię to samo z return
bez nawiasu, ponieważ nie jest to wywołanie funkcji, a jeśli umieszczę nawias, to dlatego, że poniższe wyrażenie ich potrzebuje.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-27 10:18:26