Operatörer i C och C++

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 13 september 2022; verifiering kräver 1 redigering .

Programmeringsspråket C++ stöder alla operatörer av dess stamfader, C, och är förbättrat med nya operatörer och funktioner.

Efter att ha utvärderat den första operanden för icke -överbelastade operatorer " && ", " || ” och “ , ” (“komma”-operatorn, eng.  komma ) kompilatorn infogar en sekvenspunkt ( eng.  sekvenspunkt ), som garanterar att alla biverkningar (till exempel operatorn “postfix ++”) kommer att exekveras innan den andra operanden utvärderas.

Språk med C-liknande syntax (som Java , C# , PHP och andra) lånar ofta C/C++-operatorer, vilket bevarar inte bara deras beteende, utan också deras företräde och associativitet .

Tabeller

Tabellerna använder följande notation:

struct T { // eller klassoperator float () const ; }; T :: operator float () const { /* implementation */ };
  • "Definition utanför klassen": definiera en operator som en funktion; exempel:
#include <iostream> struct T { // eller klass /* ... */ }; std :: ostream & operator << ( std :: ostream & a , T const & b ) { /* implementering */ }
  • "N/A" : Ej tillgängligt .

Aritmetiska operatorer

Operation (uttryck) Operatör Uttryckssyntax Överlastbar Implementerad i C Exempel
T-typ medlem Definition utanför klassen
Uppdrag = a = b Ja Ja R& T::operator =(S b); n/a
Tillägg + a + b Ja Ja R T::operator +(S b); R operator +(T a, S b);
Subtraktion - a - b Ja Ja R T::operator -(S b); R operator -(T a, S b);
unärt plus + +a Ja Ja R T::operator +(); R operator +(T a);
unär minus - -a Ja Ja R T::operator -(); R operator -(T a);
Multiplikation * a * b Ja Ja R T::operator *(S b); R operator *(T a, S b);
Division / a / b Ja Ja R T::operator /(S b); R operator /(T a, S b);
Operationsmodul ( återstoden från division av heltal) [not 1] % a % b Ja Ja R T::operator %(S b); R operator %(T a, S b);
Ökning prefix ++ ++a Ja Ja R& T::operator ++(); R& operator ++(T a);
suffix (postfix) ++ a++ Ja Ja R T::operator ++(int); R operator ++(T a, int);
[anteckning 2]
Minskning prefix -- --a Ja Ja R& T::operator --(); R& operator --(T a);
suffix (postfix) -- a-- Ja Ja R T::operator --(int); R operator --(T a, int);
[anteckning 2]

Jämförelseoperatorer

Operation (uttryck) Operatör Uttryckssyntax Överlastbar Implementerad i C Exempel
T-typ medlem Definition utanför klassen
Jämlikhet == a == b Ja Ja R T::operator ==(S b); R operator ==(T a, S b);
Olikhet != a != b Ja Ja R T::operator !=(S b); R operator !=(T a, S b);
Mer > a > b Ja Ja R T::operator >(S b); R operator >(T a, S b);
Mindre < a < b Ja Ja R T::operator <(S b); R operator <(T a, S b);
Mer eller lika >= a >= b Ja Ja R T::operator >=(S b); R operator >=(T a, S b);
Mindre eller lika <= a <= b Ja Ja R T::operator <=(S b); R operator <=(T a, S b);

Logiska operatorer

Operation (uttryck) Operatör Uttryckssyntax Överlastbar Implementerad i C Exempel
T-typ medlem Definition utanför klassen
Logisk negation, INTE ! !a Ja Ja R T::operator !(); R operator !(T a);
Boolesk multiplikation, AND && a && b Ja Ja R T::operator &&(S b); R operator &&(T a, S b);
Logiskt tillägg, OR || a || b Ja Ja R T::operator ||(S b); R operator ||(T a, S b);

Bitvisa operatorer

Operation (uttryck) Operatör Uttryckssyntax Överlastbar Implementerad i C Exempel
T-typ medlem Definition utanför klassen
bitvis inversion ~ ~a Ja Ja R T::operator ~(); R operator ~(T a);
Bitvis OCH & a & b Ja Ja R T::operator &(S b); R operator &(T a, S b);
Bitvis ELLER (eller) | a | b Ja Ja R T::operator |(S b); R operator |(T a, S b);
Bitvis XOR (xor) ^ a ^ b Ja Ja R T::operator ^(S b); R operator ^(T a, S b);
Vänsterväxling bitvis [not 3] << a << b Ja Ja R T::operator <<(S b); R operator <<(T a, S b);
Bitskift höger [not 3] [not 4] >> a >> b Ja Ja R T::operator >>(S b); R operator >>(T a, S b);

Sammansatt uppgift

Operation (uttryck) Operatör Uttryckssyntax Menande Överlastbar Implementerad i C Exempel
T-typ medlem Definition utanför klassen
Tillägg kombinerat med uppdrag += a += b a = a + b Ja Ja R T::operator +=(S b); R operator +=(T a, S b);
Subtraktion kombinerat med uppgift -= a -= b a = a - b Ja Ja R T::operator -=(S b); R operator -=(T a, S b);
Multiplikation kombinerat med uppgift *= a *= b a = a * b Ja Ja R T::operator *=(S b); R operator *=(T a, S b);
Division kombinerat med uppdrag /= a /= b a = a / b Ja Ja R T::operator /=(S b); R operator /=(T a, S b);
Återstoden av indelningen i kombination med uppdrag [not 1] %= a %= b a = a % b Ja Ja R T::operator %=(S b); R operator %=(T a, S b);
Bitvis "OCH" kombinerat med uppdrag &= a &= b a = a & b Ja Ja R T::operator &=(S b); R operator &=(T a, S b);
Bitvis "ELLER" (eller) kombinerat med uppgift |= a |= b a = a | b Ja Ja R T::operator |=(S b); R operator |=(T a, S b);
Bitvis exklusivt OR (xor) kombinerat med uppdrag ^= a ^= b a = a ^ b Ja Ja R T::operator ^=(S b); R operator ^=(T a, S b);
Bitvis vänsterväxling kombinerat med tilldelning <<= a <<= b a = a << b Ja Ja R T::operator <<=(S b); R operator <<=(T a, S b);
Bitvis högerväxling kombinerat med tilldelning [not 4] >>= a >>= b a = a >> b Ja Ja R T::operator >>=(S b); R operator >>=(T a, S b);

Operatörer för att arbeta med pekare och klassmedlemmar

Operatör Syntax Överlastbar Implementerad i C Exempel
T-typ medlem Definition utanför klassen
Åtkomst till ett arrayelement a[b] Ja Ja R T::operator [](S b);
n/a
Indirekt referens ("objektet som pekas på av en ") *a Ja Ja R T::operator *(); R operator *(T a);
Länk ("adress a ") &a Ja Ja R T::operator &(); R operator &(T a);
Referera till en medlem av en struktur ("medlem b av objektet pekas på av a ") a->b Ja Ja R* T::operator ->();[not 5]
n/a
Referera till en medlem av en struktur ("medlem b av objekt a ") a.b Inte Ja n/a
Medlemmen som pekas på av b i objektet som pekas på av a [not 6] a->*b Ja Inte R T::operator ->*(S b); R operator ->*(T a, S b);
Medlem pekad på av b i objekt a a.*b Inte Inte n/a

Andra operatörer

Operatör Syntax Överlastbar Implementerad i C Exempel
T-typ medlem Definition utanför klassen
Funktionär a(a1, a2) Ja Ja R T::operator ()(S a1, U a2, ...); n/a
Kommaoperatorn a, b Ja Ja R T::operator ,(S b); R operator ,(T a, S b);
Ternär villkorlig operation a ? b : c Inte Ja n/a
Omfattningsförlängningsoperatör a::b Inte Inte n/a
Anpassade bokstaver (introducerade i C++11) "a"_b Ja Inte n/a R operator "" _b(T a)
Storlek på (storlek) sizeof(a)[not 7]
sizeof(type)
Inte Ja n/a
Align-of ( alignment ) alignof(type)eller [not 8]_Alignof(type) Inte Ja n/a
Introspektion typeid(a)
typeid(type)
Inte Inte n/a
Typ gjutning (type) a Ja Ja T::operator R(); n/a
[not 9]
Minnesallokering new type Ja Inte void* T::operator new(size_t x); void* operator new(size_t x);
Minnestilldelning för en array new type[n] Ja Inte void* T::operator new[](size_t x); void* operator new[](size_t x);
Frigör minne delete a Ja Inte void T::operator delete(void* x); void operator delete(void* x);
Frigör minne som upptas av en array delete[] a Ja Inte void T::operator delete[](void* x); void operator delete[](void* x);

Anmärkningar:

  1. 1 2 Operatorn % fungerar bara med heltal. För flyttalstal, använd funktionen () från filen " math.h " .fmod
  2. 1 2 För att skilja mellan prefix- och suffixoperatorer (postfix) har en oanvänd formell typparameter lagts till i postfix-operatorer . Ofta får denna parameter inte ens ett namn.int
  3. 1 2 I iostream- biblioteket används operatorerna " " och " " för att arbeta med strömmande utdata och input.<<>>
  4. 1 2 Enligt C99-standarden är att flytta ett negativt tal åt höger implementeringsdefinierat beteende (se ospecificerat beteende ). Många kompilatorer , inklusive gcc (se dokumentation Arkiverad 22 september 2019 på Wayback Machine  ) implementerar aritmetiskt skift , men standarden förbjuder inte implementering av logiskt skift .
  5. ↑ Returtypen för operatorn " " måste vara en typ som operatorn " " gäller , till exempel en pekare. Om " " är av typen " " och klassen " " överbelastas operatorn " ", utökas uttrycket " " som " ".operator->()->xCCoperator->()x->yx.operator->()->y
  6. Se ett exempel i Wayback Machine- artikeln Arkiverad 17 maj 2013 "Implementing a Smart Pointer Operator " av Scott Myers från Dr. Dobb's journal , oktober 1999 nummer. ->*
  7. Operatören skrivs vanligtvis med parenteser. Om operanden är ett variabelnamn är parentes valfria. Om operanden är ett typnamn krävs parenteser.sizeof
  8. ↑ Språkstandarden C++ definierar alignof. En liknande operator i standardspråket C kallas _Alignof.
  9. För en cast-operatör är returtypen inte explicit specificerad, eftersom den är samma som namnet på operatören.

Operatörsprioritet

Den här tabellen listar operatorföreträde och associativitet. Operatörerna som listas i tabellen ovan (före) har högre prioritet (utvärderingsprioritet). När man överväger ett uttryck kommer operatorer med högre prioritet att utvärderas före operatorer med lägre prioritet. Om flera operatorer anges i samma cell, har de samma prioritet och utvärderas i den sekvens som specificeras av associativitet. Operatörens prioritet ändras inte när de är överbelastade.


Denna prioritetstabell är tillräcklig i de flesta fall, med följande undantag. Den ternära operatorn "?:" kan innehålla en "komma"-operator eller en tilldelning i mittuttrycket, men kompilatorn tolkar " "-koden som " ", och inte som ett meningslöst uttryck " "". Således behandlas uttrycket mellan och som om det vore inom parentes.a ? b, c : da ? (b, c) : d(a ? b), (c : d)?:

En prioritet Operatör Beskrivning Associativitet
ett

Högsta

:: Omfattningsupplösning Inte
2 ++ Suffixökning Från vänster till höger
-- Suffixminskning
() Funktionsanrop _
[] Att ta ett arrayelement
. Välja ett element genom referens
-> Välja ett element med pekaren
typeid() RTTI (endast C++; se typid )
const_cast Typ gjutning (C++) (se konstgjutning )
dynamic_cast Typgjutning (C++) (se dynamisk gjutning )
reinterpret_cast Ordleksskrivning (C++) (se reinterpret_cast )
static_cast Typgjutning (C++) (se statisk gjutning )
3 ++ prefixökning _ Från höger till vänster
-- prefix dekrement
+ unärt plus
- unär minus
! Logisk INTE
~ Bitvis INTE
(type) Typ gjutning
* Pekaravledning _
& Tar objektadress _
sizeof Storlek på (storlek)
new,new[] Dynamisk minnesallokering (C++)
delete,delete[] Avallokera dynamiskt minne (C++)
fyra .* Pekare till medlem (C++) Från vänster till höger
->* Pekare till medlem (C++)
5 * Multiplikation
/ Division
% Få resten av en division
6 + Tillägg
- Subtraktion
7 << Bitskifte vänster
>> Bit shift höger
åtta < Mindre
<= Mindre eller lika
> Mer
>= Mer eller lika
9 == Jämlikhet
!= Olikhet
tio & Bitvis OCH (och)
elva ^ Bitvis XOR (xor)
12 | Bitvis ELLER (eller)
13 && logiskt OCH
fjorton || Logisk ELLER
femton ?: Ternär villkorlig operation Från höger till vänster
= Uppdrag
+= Tillägg kombinerat med uppdrag
-= Subtraktion kombinerat med uppgift
*= Multiplikation kombinerat med uppgift
/= Division kombinerat med uppdrag
%= Beräkning av resten av en division, kombinerat med en uppgift
<<= Bitvis vänsterväxling kombinerat med tilldelning
>>= Bitvis högerväxling kombinerat med tilldelning
&= Bitvis "OCH" kombinerat med uppdrag
|= Bitvis "ELLER" kombinerat med uppdrag
^= Bitvis exklusivt OR (xor) kombinerat med uppdrag
throw Kasta undantagsoperatör ( C++)
16 , Kommaoperatorn Från vänster till höger

Beskrivning

Kompilatorn använder en prioritetstabell för att bestämma i vilken ordning operatörer utvärderas.

  • Det skulle till exempel ++x*3vara tvetydigt utan några företrädesregler. Från tabellen kan vi säga att x först associeras med ++ operatorn , och först sedan med * operatorn , så oavsett åtgärden av ++ operatorn är denna åtgärd bara på x (och inte på x*3). Således är uttrycket ekvivalent med ( ++x, x*3).
  • Likaså med koden 3*x++där tabellen anger att inkrementet endast gäller x och inte 3*x. Funktionellt sett är detta uttryck ekvivalent med ( ) om du uttrycker den temporära variabeln som tmp .tmp=x, x++, tmp=3*tmp, tmp

Operatörsbindning i C- och C++-standarderna definieras i termer av språkets grammatik, inte i termer av en tabell. Detta kan skapa konflikter. Till exempel, i C är syntaxen för ett villkorligt uttalande:

logiskt - ELLER - uttryck ? uttryck : villkorligt - uttryck

Och i C++:

logiskt - ELLER - uttryck ? uttryck : uppdrag - uttryck

På grund av detta, uttrycket:

e = a < d? a++: a = d

kommer att uppfattas olika på de två språken. I C är uttrycket syntaktiskt felaktigt eftersom resultatet av en villkorlig sats inte kan fungera som ett lvärde (det vill säga den vänstra sidan av en tilldelningssats).

I C++ kommer uttrycket att tolkas som giltigt: [1]

e = ( a < d ? a ++ : ( a = d ))

Företrädet för bitvis logiska operatorer är något icke-intuitivt [2] . Begreppsmässigt &är och |samma aritmetiska operatorer som *respektive +.

Uttrycket behandlas syntaktiskt som , men uttrycket motsvarar . På grund av detta är det ofta nödvändigt att använda parenteser för att explicit specificera utvärderingsordningen. a & b == 7a & (b == 7)a + b == 7(a + b) == 7

Operatörssynonymer i C++

C++-standarden definierar [3] digrafer för vissa operatorer:

Digraph Motsvarande sträng
och &&
bitand &
and_eq &=
eller ||
bitor |
or_eq |=
xor ^
xor_eq ^=
inte !
not_eq !=
kompl ~

Digrafer kan användas på samma sätt som operatorer, de är synonymer för operatorer. Till exempel kan digrafen " " användas för att ersätta operatorerna "bitvis AND" och "get adress", eller i definitionen av referenstyper. Således är koden " " ekvivalent med koden " ". bitandint bitand ref = n;int & ref = n;

ANSI/ISO C-standarden definierar de listade digraferna som konstanter #define(se förprocessor ). Konstanterna definieras i rubrikfilen " iso646.h". För C-kompatibilitet definierar C++-standarden en dummy-huvudfil " ciso646".

Anteckningar

  1. Har den ternära operatorn C/C++ faktiskt samma prioritet som tilldelningsoperatorer? . stack overflow. Hämtad 22 september 2019. Arkiverad från originalet 6 augusti 2020.
  2. Chistory (nedlänk) . Hämtad 11 januari 2013. Arkiverad från originalet 22 juni 2013. 
  3. ISO/IEC JTC1/SC22/WG21 - C++ Standards Committee . ISO/IEC 14882:1998(E) Programmeringsspråket C  ++ . - International Group for the Standardization of the C++ Programming Language, 1998. - S. 40-41.

Länkar