Operatører i C og C++

Den aktuelle version af siden er endnu ikke blevet gennemgået af erfarne bidragydere og kan afvige væsentligt fra den version , der blev gennemgået den 13. september 2022; verifikation kræver 1 redigering .

C++ programmeringssproget understøtter alle operatørerne af dets stamfader, C, og er forbedret med nye operatører og funktioner.

Efter at have evalueret den første operand for ikke -overbelastede operatorer " && ", " || ” og “ , ” (“komma”-operatoren, eng.  komma ) compileren indsætter et sekvenspunkt ( eng.  sequence point ), som garanterer, at alle bivirkninger (f.eks. “postfix ++”-operatoren) vil blive udført før den anden operand evalueres.

Sprog med C-lignende syntaks (såsom Java , C# , PHP og andre) låner ofte C/C++-operatorer og bevarer ikke kun deres adfærd, men også deres forrang og associativitet .

Tabeller

Tabellerne bruger følgende notation:

struct T { // eller klasseoperatør float ( ) const ; }; T :: operator float () const { /* implementering */ };
  • "Definition uden for klassen": definere en operator som en funktion; eksempel:
#include <iostream> struct T { // eller klasse /* ... */ }; std :: ostream & operator << ( std :: ostream & a , T const & b ) { /* implementering */ }
  • "N/A" : Ikke tilgængelig .

Aritmetiske operatorer

Betjening (udtryk) Operatør Udtryks syntaks Overbelastbar Implementeret i C Eksempel
T type medlem Definition uden for klassen
Opgave = a = b Ja Ja R& T::operator =(S b); n/a
Tilføjelse + 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 ( resten fra division af heltal) [note 1] % a % b Ja Ja R T::operator %(S b); R operator %(T a, S b);
Forøgelse præfiks ++ ++a Ja Ja R& T::operator ++(); R& operator ++(T a);
suffiks (postfix) ++ a++ Ja Ja R T::operator ++(int); R operator ++(T a, int);
[note 2]
Nedsættelse præfiks -- --a Ja Ja R& T::operator --(); R& operator --(T a);
suffiks (postfix) -- a-- Ja Ja R T::operator --(int); R operator --(T a, int);
[note 2]

Sammenligningsoperatorer

Betjening (udtryk) Operatør Udtryks syntaks Overbelastbar Implementeret i C Eksempel
T type medlem Definition uden for klassen
Lighed == a == b Ja Ja R T::operator ==(S b); R operator ==(T a, S b);
Ulighed != a != b Ja Ja R T::operator !=(S b); R operator !=(T a, S b);
Mere > 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);
Mere eller lige >= a >= b Ja Ja R T::operator >=(S b); R operator >=(T a, S b);
Mindre eller lige <= a <= b Ja Ja R T::operator <=(S b); R operator <=(T a, S b);

Logiske operatorer

Betjening (udtryk) Operatør Udtryks syntaks Overbelastbar Implementeret i C Eksempel
T type medlem Definition uden for klassen
Logisk negation, IKKE ! !a Ja Ja R T::operator !(); R operator !(T a);
Boolesk multiplikation, OG && a && b Ja Ja R T::operator &&(S b); R operator &&(T a, S b);
Logisk tilføjelse, OR || a || b Ja Ja R T::operator ||(S b); R operator ||(T a, S b);

Bitvise operatorer

Betjening (udtryk) Operatør Udtryks syntaks Overbelastbar Implementeret i C Eksempel
T type medlem Definition uden for klassen
bitvis inversion ~ ~a Ja Ja R T::operator ~(); R operator ~(T a);
Bitvis OG & 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);
Bitwise XOR (xor) ^ a ^ b Ja Ja R T::operator ^(S b); R operator ^(T a, S b);
Bitvist venstreskift [note 3] << a << b Ja Ja R T::operator <<(S b); R operator <<(T a, S b);
Bitskift til højre [note 3] [note 4] >> a >> b Ja Ja R T::operator >>(S b); R operator >>(T a, S b);

Sammensat opgave

Betjening (udtryk) Operatør Udtryks syntaks Betyder Overbelastbar Implementeret i C Eksempel
T type medlem Definition uden for klassen
Tilføjelse kombineret med opgave += a += b a = a + b Ja Ja R T::operator +=(S b); R operator +=(T a, S b);
Subtraktion kombineret med opgave -= a -= b a = a - b Ja Ja R T::operator -=(S b); R operator -=(T a, S b);
Multiplikation kombineret med opgave *= a *= b a = a * b Ja Ja R T::operator *=(S b); R operator *=(T a, S b);
Division kombineret med opgave /= a /= b a = a / b Ja Ja R T::operator /=(S b); R operator /=(T a, S b);
Resten af ​​division kombineret med opgave [note 1] %= a %= b a = a % b Ja Ja R T::operator %=(S b); R operator %=(T a, S b);
Bitvis "OG" kombineret med opgave &= a &= b a = a & b Ja Ja R T::operator &=(S b); R operator &=(T a, S b);
Bitvist "ELLER" (eller) kombineret med opgave |= a |= b a = a | b Ja Ja R T::operator |=(S b); R operator |=(T a, S b);
Bitwise exclusive OR (xor) kombineret med opgave ^= a ^= b a = a ^ b Ja Ja R T::operator ^=(S b); R operator ^=(T a, S b);
Bitvist venstreskift kombineret med tildeling <<= a <<= b a = a << b Ja Ja R T::operator <<=(S b); R operator <<=(T a, S b);
Bitvist højreskift kombineret med tildeling [note 4] >>= a >>= b a = a >> b Ja Ja R T::operator >>=(S b); R operator >>=(T a, S b);

Operatorer til at arbejde med pointere og klassemedlemmer

Operatør Syntaks Overbelastbar Implementeret i C Eksempel
T type medlem Definition uden for klassen
Adgang til et array-element a[b] Ja Ja R T::operator [](S b);
n/a
Indirekte reference ("objektet peget på af et ") *a Ja Ja R T::operator *(); R operator *(T a);
Link ("adresse a ") &a Ja Ja R T::operator &(); R operator &(T a);
Henvisning til et medlem af en struct ("medlem b af objektet peget på af a ") a->b Ja Ja R* T::operator ->();[note 5]
n/a
Henvisning til et medlem af en struktur ("medlem b af objekt a ") a.b Ikke Ja n/a
Medlemmet, der peges på af b i objektet, der peges på af a [note 6] a->*b Ja Ikke R T::operator ->*(S b); R operator ->*(T a, S b);
Medlem peget på af b i objekt a a.*b Ikke Ikke n/a

Andre operatører

Operatør Syntaks Overbelastbar Implementeret i C Eksempel
T type medlem Definition uden for klassen
Funktionær a(a1, a2) Ja Ja R T::operator ()(S a1, U a2, ...); n/a
Kommaoperatoren a, b Ja Ja R T::operator ,(S b); R operator ,(T a, S b);
Ternær betinget operation a ? b : c Ikke Ja n/a
Omfangsudvidelsesoperatør a::b Ikke Ikke n/a
Brugerdefinerede bogstaver (introduceret i C++11) "a"_b Ja Ikke n/a R operator "" _b(T a)
Størrelse af (størrelse) sizeof(a)[note 7]
sizeof(type)
Ikke Ja n/a
Justering af ( justering ) alignof(type)eller [note 8]_Alignof(type) Ikke Ja n/a
Introspektion typeid(a)
typeid(type)
Ikke Ikke n/a
Type støbning (type) a Ja Ja T::operator R(); n/a
[note 9]
Hukommelsestildeling new type Ja Ikke void* T::operator new(size_t x); void* operator new(size_t x);
Hukommelsestildeling for et array new type[n] Ja Ikke void* T::operator new[](size_t x); void* operator new[](size_t x);
Frigør hukommelsen delete a Ja Ikke void T::operator delete(void* x); void operator delete(void* x);
Frigør hukommelse optaget af et array delete[] a Ja Ikke void T::operator delete[](void* x); void operator delete[](void* x);

Bemærkninger:

  1. 1 2 % operatoren virker kun med heltal . For flydende kommatal skal du bruge funktionen () fra filen " math.h " .fmod
  2. 1 2 For at skelne mellem præfiks- og suffiksoperatorer (postfix) er der tilføjet en ubrugt formel typeparameter til postfix-operatorer . Ofte får denne parameter ikke engang et navn.int
  3. 1 2 I iostream- biblioteket bruges operatørerne " " og " " til at arbejde med streaming output og input.<<>>
  4. 1 2 Ifølge C99-standarden er skift af et negativt tal til højre implementeringsdefineret adfærd (se uspecificeret adfærd ). Mange compilere , inklusive gcc (se dokumentation Arkiveret 22. september 2019 på Wayback Machine  ) implementerer aritmetisk skift , men standarden forbyder ikke implementering af logisk skift .
  5. ↑ Returtypen for " "-operatoren skal være en type, som " "-operatoren gælder for , såsom en pointer. Hvis " " er af typen " ", og klassen " " overbelaster operatoren " ", udvides udtrykket " " som " ".operator->()->xCCoperator->()x->yx.operator->()->y
  6. Se et eksempel i Wayback Machine- artiklen Arkiveret 17. maj 2013 "Implementing a Smart Pointer Operator " af Scott Myers fra Dr. Dobb's journal , oktober 1999 udgave. ->*
  7. Operatøren skrives normalt med parenteser. Hvis operanden er et variabelnavn, er parentes valgfri. Hvis operanden er et typenavn, kræves parenteserne.sizeof
  8. C++ sprogstandarden definerer alignof. En lignende operator i standard C-sproget kaldes _Alignof.
  9. For en cast-operatør er returtypen ikke eksplicit angivet, da den er det samme som navnet på operatøren.

Operatør forrang

Denne tabel viser operatørpræference og associativitet. Operatørerne anført i tabellen ovenfor (før) har en højere prioritet (evalueringsprioritet). Når man overvejer et udtryk, vil operatorer med højere prioritet blive evalueret før operatorer med lavere prioritet. Hvis flere operatorer er angivet i den samme celle, har de samme forrang og evalueres i den rækkefølge, der er angivet af associativitet. Operatørprioritet ændres ikke, når de overbelastes.


Denne prioritetstabel er tilstrækkelig i de fleste tilfælde med følgende undtagelser. Den ternære operator "?:" kan indeholde en "komma"-operator eller en tildeling i det midterste udtryk, men compileren fortolker " "-koden som " ", og ikke som et meningsløst udtryk " "". Således behandles udtrykket mellem og , som var det i parentes. a ? b, c : da ? (b, c) : d(a ? b), (c : d)?:

En prioritet Operatør Beskrivelse Associativitet
en

Højest

:: Anvendelsesområde Opløsning Ikke
2 ++ Suffiks stigning Fra venstre mod højre
-- Suffiks formindskelse
() Funktionsopkald _
[] Tager et array-element
. Valg af et element ved reference
-> Valg af et element ved hjælp af markøren
typeid() RTTI (kun C++; se typeid )
const_cast Type støbning (C++) (se konst cast )
dynamic_cast Type casting (C++) (se dynamisk cast )
reinterpret_cast Ordspilsskrivning (C++) (se reinterpret_cast )
static_cast Typestøbning (C++) (se statisk støbning )
3 ++ præfiks stigning Fra højre til venstre
-- præfiks dekrement
+ unært plus
- unær minus
! Logisk IKKE
~ Bitvis IKKE
(type) Type støbning
* Pointer dereferencing
& Tager objektadresse _
sizeof Størrelse af (størrelse)
new,new[] Dynamisk hukommelsesallokering (C++)
delete,delete[] Deallokering af dynamisk hukommelse (C++)
fire .* Pointer til medlem (C++) Fra venstre mod højre
->* Pointer til medlem (C++)
5 * Multiplikation
/ Division
% Får resten af ​​en division
6 + Tilføjelse
- Subtraktion
7 << Bitskift til venstre
>> Bit skift til højre
otte < Mindre
<= Mindre eller lige
> Mere
>= Mere eller lige
9 == Lighed
!= Ulighed
ti & Bitvis OG (og)
elleve ^ Bitwise XOR (xor)
12 | Bitvis ELLER (eller)
13 && logisk OG
fjorten || Logisk ELLER
femten ?: Ternær betinget operation Fra højre til venstre
= Opgave
+= Tilføjelse kombineret med opgave
-= Subtraktion kombineret med opgave
*= Multiplikation kombineret med opgave
/= Division kombineret med opgave
%= Beregning af resten af ​​en division kombineret med en opgave
<<= Bitvist venstreskift kombineret med tildeling
>>= Bitvist højreskift kombineret med tildeling
&= Bitvis "OG" kombineret med opgave
|= Bitvis "ELLER" kombineret med opgave
^= Bitwise exclusive OR (xor) kombineret med opgave
throw Kast undtagelsesoperatør (C++)
16 , Kommaoperatoren Fra venstre mod højre

Beskrivelse

Compileren bruger en præcedenstabel til at bestemme rækkefølgen, som operatører evalueres i.

  • For eksempel ++x*3ville være tvetydig uden nogen forrangsregler. Fra tabellen kan vi sige, at x først er knyttet til ++ operatoren , og først derefter med * operatoren , så uanset handlingen af ​​++ operatoren er denne handling kun på x (og ikke på x*3). Udtrykket svarer således til ( ++x, x*3).
  • Ligeledes med koden, 3*x++hvor tabellen angiver, at stigningen kun gælder for x og ikke for 3*x. Funktionelt svarer dette udtryk til ( ), hvis du udtrykker den midlertidige variabel som tmp .tmp=x, x++, tmp=3*tmp, tmp

Operatørbinding i C- og C++-standarderne er defineret i form af sprogets grammatik, ikke i form af en tabel. Dette kan skabe konflikt. For eksempel i C er syntaksen for en betinget sætning:

logisk - ELLER - udtryk ? udtryk : betinget - udtryk

Og i C++:

logisk - ELLER - udtryk ? udtryk : opgave - udtryk

På grund af dette er udtrykket:

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

vil blive opfattet forskelligt på de to sprog. I C er udtrykket syntaktisk forkert, fordi resultatet af en betinget sætning ikke kan tjene som en lværdi (det vil sige venstre side af en tildelingssætning).

I C++ vil udtrykket blive parset som gyldigt: [1]

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

Forrangen af ​​bitvise logiske operatorer er noget ikke-intuitiv [2] . Begrebsmæssigt &, og |er de samme aritmetiske operatorer som *hhv +.

Udtrykket behandles syntaktisk som , men udtrykket svarer til . På grund af dette er det ofte nødvendigt at bruge parenteser til eksplicit at angive rækkefølgen af ​​evalueringen. a & b == 7a & (b == 7)a + b == 7(a + b) == 7

Operatørsynonymer i C++

C++-standarden definerer [3] digrafer for nogle operatorer:

Digraph Tilsvarende streng
og &&
bitand &
and_eq &=
eller ||
bitor |
or_eq |=
xor ^
xor_eq ^=
ikke !
ikke_eq !=
kompl ~

Digrafer kan bruges på samme måde som operatorer, de er synonymer for operatorer. For eksempel kan digrafen " " bruges til at erstatte operatorerne "bitwise AND" og "get address" eller i definitionen af ​​referencetyper. Således svarer koden " " til koden " ". bitandint bitand ref = n;int & ref = n;

ANSI/ISO C-standarden definerer de anførte digrafer som konstanter #define(se præprocessor ). Konstanterne er defineret i overskriftsfilen " iso646.h". For C-kompatibilitet definerer C++-standarden en dummy-header-fil " ciso646".

Noter

  1. Har den ternære C/C++-operator faktisk den samme forrang som tildelingsoperatorer? . stak overløb. Hentet 22. september 2019. Arkiveret fra originalen 6. august 2020.
  2. Historie (downlink) . Hentet 11. januar 2013. Arkiveret fra originalen 22. juni 2013. 
  3. ISO/IEC JTC1/SC22/WG21 - C++ Standards Committee . ISO/IEC 14882:1998(E) C++-  programmeringssproget . - International Group for the Standardization of the C++ Programming Language, 1998. - S. 40-41.

Links