Operaattorit C- ja C++-kielillä

Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 13.9.2022 tarkistetusta versiosta . vahvistus vaatii 1 muokkauksen .

C++-ohjelmointikieli tukee kaikkia sen C:n operaattoreita, ja sitä on täydennetty uusilla operaattoreilla ja ominaisuuksilla.

Kun ensimmäinen operandi on arvioitu ei -ylikuormitetuille operaattoreille " && ", " || " ja " , " ("pilkku"-operaattori, eng.  comma ) kääntäjä lisää sekvenssipisteen ( eng.  sequence point ), joka takaa, että kaikki sivuvaikutukset (esim. "postfix ++" -operaattori) suoritetaan ennen kuin toinen operandi arvioidaan.

Kielet, joissa on C-kaltainen syntaksi (kuten Java , C# , PHP ja muut) lainaavat usein C/C++-operaattoreita säilyttäen paitsi niiden käyttäytymisen, myös niiden ensisijaisuuden ja assosiatiivisuuden .

Taulukot

Taulukoissa käytetään seuraavaa merkintää:

struct T { // tai luokkaoperaattori float ( ) const ; }; T :: operaattori float () const { /* toteutus */ };
  • "Määritelmä luokan ulkopuolella": operaattorin määritteleminen funktiona; esimerkki:
#include <iostream> struct T { // tai luokka /* ... */ }; std :: ostream & operaattori << ( std :: ostream & a , T const & b ) { /* toteutus */ }
  • "N/A" : Ei saatavilla .

Aritmeettiset operaattorit

Operaatio (lauseke) Operaattori Lausekkeen syntaksi Ylikuormitettava Toteutettu C Esimerkki
T-tyypin jäsen Määritelmä luokan ulkopuolella
Tehtävä = a = b Joo Joo R& T::operator =(S b); n/a
Lisäys + a + b Joo Joo R T::operator +(S b); R operator +(T a, S b);
Vähennyslasku - a - b Joo Joo R T::operator -(S b); R operator -(T a, S b);
yksipuolinen plus + +a Joo Joo R T::operator +(); R operator +(T a);
yksipuolinen miinus - -a Joo Joo R T::operator -(); R operator -(T a);
Kertominen * a * b Joo Joo R T::operator *(S b); R operator *(T a, S b);
Division / a / b Joo Joo R T::operator /(S b); R operator /(T a, S b);
Operaatiomoduuli ( jäännös kokonaislukujen jaosta) [huomautus 1] % a % b Joo Joo R T::operator %(S b); R operator %(T a, S b);
Lisäys etuliite ++ ++a Joo Joo R& T::operator ++(); R& operator ++(T a);
jälkiliite (postfix) ++ a++ Joo Joo R T::operator ++(int); R operator ++(T a, int);
[muistio 2]
Vähennys etuliite -- --a Joo Joo R& T::operator --(); R& operator --(T a);
jälkiliite (postfix) -- a-- Joo Joo R T::operator --(int); R operator --(T a, int);
[muistio 2]

Vertailuoperaattorit

Operaatio (lauseke) Operaattori Lausekkeen syntaksi Ylikuormitettava Toteutettu C Esimerkki
T-tyypin jäsen Määritelmä luokan ulkopuolella
Tasa-arvo == a == b Joo Joo R T::operator ==(S b); R operator ==(T a, S b);
Epätasa-arvo != a != b Joo Joo R T::operator !=(S b); R operator !=(T a, S b);
Lisää > a > b Joo Joo R T::operator >(S b); R operator >(T a, S b);
Vähemmän < a < b Joo Joo R T::operator <(S b); R operator <(T a, S b);
Enemmän tai yhtä paljon >= a >= b Joo Joo R T::operator >=(S b); R operator >=(T a, S b);
Vähemmän tai yhtä suuret <= a <= b Joo Joo R T::operator <=(S b); R operator <=(T a, S b);

Loogiset operaattorit

Operaatio (lauseke) Operaattori Lausekkeen syntaksi Ylikuormitettava Toteutettu C Esimerkki
T-tyypin jäsen Määritelmä luokan ulkopuolella
Looginen kieltäminen, EI ! !a Joo Joo R T::operator !(); R operator !(T a);
Boolen kertolasku, AND && a && b Joo Joo R T::operator &&(S b); R operator &&(T a, S b);
Looginen lisäys, TAI || a || b Joo Joo R T::operator ||(S b); R operator ||(T a, S b);

Bittioperaattorit

Operaatio (lauseke) Operaattori Lausekkeen syntaksi Ylikuormitettava Toteutettu C Esimerkki
T-tyypin jäsen Määritelmä luokan ulkopuolella
bittikohtainen inversio ~ ~a Joo Joo R T::operator ~(); R operator ~(T a);
Bitittain JA & a & b Joo Joo R T::operator &(S b); R operator &(T a, S b);
Bitittain TAI (tai) | a | b Joo Joo R T::operator |(S b); R operator |(T a, S b);
Bittikohtainen XOR (xor) ^ a ^ b Joo Joo R T::operator ^(S b); R operator ^(T a, S b);
Bittisuuntainen vasen siirto [huomautus 3] << a << b Joo Joo R T::operator <<(S b); R operator <<(T a, S b);
Bittisiirto oikealle [huomautus 3] [huomautus 4] >> a >> b Joo Joo R T::operator >>(S b); R operator >>(T a, S b);

Yhdistelmätehtävä

Operaatio (lauseke) Operaattori Lausekkeen syntaksi Merkitys Ylikuormitettava Toteutettu C Esimerkki
T-tyypin jäsen Määritelmä luokan ulkopuolella
Lisäys yhdistettynä toimeksiantoon += a += b a = a + b Joo Joo R T::operator +=(S b); R operator +=(T a, S b);
Vähennys yhdistettynä tehtävään -= a -= b a = a - b Joo Joo R T::operator -=(S b); R operator -=(T a, S b);
Kertominen yhdistettynä tehtävään *= a *= b a = a * b Joo Joo R T::operator *=(S b); R operator *=(T a, S b);
Jako yhdistettynä toimeksiantoon /= a /= b a = a / b Joo Joo R T::operator /=(S b); R operator /=(T a, S b);
Loput jaosta yhdistettynä toimeksiantoon [huomautus 1] %= a %= b a = a % b Joo Joo R T::operator %=(S b); R operator %=(T a, S b);
Bittikohtainen "AND" yhdistettynä tehtävään &= a &= b a = a & b Joo Joo R T::operator &=(S b); R operator &=(T a, S b);
Bitittainen "OR" (tai) yhdistettynä tehtävään |= a |= b a = a | b Joo Joo R T::operator |=(S b); R operator |=(T a, S b);
Bittikohtainen poissulkeva TAI (xor) yhdistettynä tehtävään ^= a ^= b a = a ^ b Joo Joo R T::operator ^=(S b); R operator ^=(T a, S b);
Bittisuuntainen vasen siirto yhdistettynä tehtävään <<= a <<= b a = a << b Joo Joo R T::operator <<=(S b); R operator <<=(T a, S b);
Bitittainen siirto oikealle yhdistettynä tehtävään [huom. 4] >>= a >>= b a = a >> b Joo Joo R T::operator >>=(S b); R operator >>=(T a, S b);

Operaattorit osoittimien ja luokan jäsenten kanssa työskentelemiseen

Operaattori Syntaksi Ylikuormitettava Toteutettu C Esimerkki
T-tyypin jäsen Määritelmä luokan ulkopuolella
Matriisielementin käyttäminen a[b] Joo Joo R T::operator [](S b);
n/a
Epäsuora viittaaminen ("objekti, johon on osoittanut ") *a Joo Joo R T::operator *(); R operator *(T a);
Linkki ("osoite a ") &a Joo Joo R T::operator &(); R operator &(T a);
Viittaus rakenteen jäseneen (" objektin jäsen b , johon a osoittaa ") a->b Joo Joo R* T::operator ->();[huomautus 5]
n/a
Viittaus rakenteen jäseneen (" objektin a jäsen b ") a.b Ei Joo n/a
B:n osoittama jäsen objektissa, johon a osoittaa [huomautus 6] a->*b Joo Ei R T::operator ->*(S b); R operator ->*(T a, S b);
B: n osoittama jäsen objektissa a a.*b Ei Ei n/a

Muut operaattorit

Operaattori Syntaksi Ylikuormitettava Toteutettu C Esimerkki
T-tyypin jäsen Määritelmä luokan ulkopuolella
Functor a(a1, a2) Joo Joo R T::operator ()(S a1, U a2, ...); n/a
Pilkuoperaattori a, b Joo Joo R T::operator ,(S b); R operator ,(T a, S b);
Kolminkertainen ehdollinen toiminta a ? b : c Ei Joo n/a
Laajennusoperaattori a::b Ei Ei n/a
Mukautetut literaalit (otettu käyttöön C++11:ssä) "a"_b Joo Ei n/a R operator "" _b(T a)
Koko (koko) sizeof(a)[huomautus 7]
sizeof(type)
Ei Joo n/a
Tasaus ( tasaus ) alignof(type)tai [huomautus 8]_Alignof(type) Ei Joo n/a
Itsetutkiskelu typeid(a)
typeid(type)
Ei Ei n/a
Tyyppivalu (type) a Joo Joo T::operator R(); n/a
[huomautus 9]
Muistin varaus new type Joo Ei void* T::operator new(size_t x); void* operator new(size_t x);
Muistin varaus taulukolle new type[n] Joo Ei void* T::operator new[](size_t x); void* operator new[](size_t x);
Vapauttaa muistia delete a Joo Ei void T::operator delete(void* x); void operator delete(void* x);
Vapautetaan taulukon varaama muisti delete[] a Joo Ei void T::operator delete[](void* x); void operator delete[](void* x);

Huomautuksia:

  1. 1 2 % -operaattori toimii vain kokonaislukujen kanssa . Käytä liukulukuille () -funktiota " math.h " -tiedostosta .fmod
  2. 1 2 Etuliite- ja pääteoperaattoreiden (postfix) erottamiseksi toisistaan, käyttämätön muodollinen tyyppiparametri on lisätty postfix-operaattoreihin . Usein tälle parametrille ei edes anneta nimeä.int
  3. 1 2 iostream- kirjastossa operaattoreita " " ja " " käytetään työskentelemään suoratoiston lähdön ja tulon kanssa.<<>>
  4. 1 2 C99-standardin mukaan negatiivisen luvun siirtäminen oikealle on toteutuksen määrittelemää toimintaa (katso määrittelemätön käyttäytyminen ). Monet kääntäjät , mukaan lukien gcc (katso dokumentaatio , joka on arkistoitu 22. syyskuuta 2019 Wayback Machinessa  ) , käyttävät aritmeettista muutosta , mutta standardi ei estä loogisen siirron toteuttamista .
  5. Operaattorin " " palautustyypin on oltava tyyppi, jota operaattori " " koskee , kuten osoitin. Jos " " on tyyppiä " " ja luokka " " ylikuormittaa operaattoria " ", lauseke " " laajenee muotoon " ".operator->()->xCCoperator->()x->yx.operator->()->y
  6. Katso esimerkki Wayback Machine -artikkelista , arkistoitu 17. toukokuuta 2013 "Implementing a Smart Pointer Operator ", kirjoittaja Scott Myers of Dr. Dobb's Journal , lokakuun 1999 numero. ->*
  7. Operaattori kirjoitetaan yleensä hakasulkeilla. Jos operandi on muuttujan nimi, sulut ovat valinnaisia. Jos operandi on tyypin nimi, sulut ovat pakollisia.sizeof
  8. C++-kielistandardi määrittelee alignof. Samanlaista operaattoria tavallisessa C-kielessä kutsutaan nimellä _Alignof.
  9. Cast-operaattorille palautustyyppiä ei ole erikseen määritelty, koska se on sama kuin operaattorin nimi.

Operaattorin etusija

Tässä taulukossa luetellaan operaattorien ensisijaisuus ja assosiaatio. Yllä olevassa taulukossa (ennen) luetelluilla operaattoreilla on korkeampi prioriteetti (arviointiprioriteetti). Kun tarkastellaan lauseketta, operaattorit, joilla on korkeampi prioriteetti, arvioidaan ennen operaattoreita, joilla on pienempi prioriteetti. Jos samassa solussa on määritetty useita operaattoreita, niillä on sama etusija ja ne arvioidaan assosiatiivisuuden määrittämässä järjestyksessä. Käyttäjän etusija ei muutu, kun ne ovat ylikuormitettuja.


Tämä prioriteettitaulukko riittää useimmissa tapauksissa seuraavin poikkeuksin. Kolmiosainen operaattori "?:" voi sisältää "pilkun" operaattorin tai määrityksen keskimmäisessä lausekkeessa, mutta kääntäjä tulkitsee " " koodin " ", ei merkityksettömäksi lausekkeeksi " ". Siten ja välissä olevaa lauseketta käsitellään ikään kuin se olisi suluissa. a ? b, c : da ? (b, c) : d(a ? b), (c : d)?:

Prioriteetti Operaattori Kuvaus Assosiatiivisuus
yksi

Korkein

:: Laajuuden resoluutio Ei
2 ++ Suffiksin lisäys Vasemmalta oikealle
-- Suffiksin vähennys
() Toimintokutsu _
[] Matriisielementin ottaminen
. Elementin valitseminen viittauksella
-> Elementin valitseminen osoittimella
typeid() RTTI (vain C++; katso tyyppitunnus )
const_cast Tyyppivalu (C++) (katso const cast )
dynamic_cast Tyyppivalu (C++) (katso dynaaminen suoratoisto )
reinterpret_cast Pun-kirjoitus (C++) (katso reinterpret_cast )
static_cast Tyyppivalu (C++) (katso staattinen valu )
3 ++ etuliitteen lisäys Oikealta vasemmalle
-- etuliitteen vähennys
+ yksipuolinen plus
- yksipuolinen miinus
! Loogista EI
~ Bitittain EI
(type) Tyyppivalu
* Osoittimen viittauksen poisto
& Otetaan kohteen osoite
sizeof Koko (koko)
new,new[] Dynaaminen muistin varaus (C++)
delete,delete[] Dynaamisen muistin varauksen purkaminen (C++)
neljä .* Osoitin jäseneen (C++) Vasemmalta oikealle
->* Osoitin jäseneen (C++)
5 * Kertominen
/ Division
% Jaon loppuosan saaminen
6 + Lisäys
- Vähennyslasku
7 << Bittinen siirto vasemmalle
>> Hieman siirto oikealle
kahdeksan < Vähemmän
<= Vähemmän tai yhtä suuret
> Lisää
>= Enemmän tai yhtä paljon
9 == Tasa-arvo
!= Epätasa-arvo
kymmenen & Bitittain JA (ja)
yksitoista ^ Bittikohtainen XOR (xor)
12 | Bitittain TAI (tai)
13 && looginen JA
neljätoista || Looginen TAI
viisitoista ?: Kolminkertainen ehdollinen toiminta Oikealta vasemmalle
= Tehtävä
+= Lisäys yhdistettynä toimeksiantoon
-= Vähennys yhdistettynä tehtävään
*= Kertominen yhdistettynä tehtävään
/= Jako yhdistettynä toimeksiantoon
%= Jaon loppuosan laskenta yhdistettynä toimeksiantoon
<<= Bittisuuntainen vasen siirto yhdistettynä tehtävään
>>= Bittisuuntainen oikea siirto yhdistettynä tehtävään
&= Bittikohtainen "AND" yhdistettynä tehtävään
|= Bittikohtainen "OR" yhdistettynä tehtävään
^= Bittikohtainen poissulkeva TAI (xor) yhdistettynä tehtävään
throw Heittopoikkeusoperaattori (C++ )
16 , Pilkuoperaattori Vasemmalta oikealle

Kuvaus

Kääntäjä käyttää etusijataulukkoa määrittääkseen järjestyksen, jossa operaattoreita arvioidaan.

  • Olisi esimerkiksi ++x*3epäselvä ilman etusijasääntöjä. Taulukosta voidaan sanoa, että x liittyy ensin ++- operaattoriin ja vasta sitten * -operaattoriin , joten riippumatta ++- operaattorin toiminnasta tämä toiminto on vain x :llä (eikä päällä x*3). Näin ollen lauseke vastaa ( ++x, x*3).
  • Samoin koodin kanssa, 3*x++jossa taulukossa todetaan, että lisäys koskee vain x :ää , ei 3*x. Toiminnallisesti tämä lauseke vastaa ( ), jos väliaikainen muuttuja ilmaistaan ​​muodossa tmp .tmp=x, x++, tmp=3*tmp, tmp

Operaattorisidonta C- ja C++-standardeissa määritellään kielen kieliopin, ei taulukon, perusteella. Tämä voi aiheuttaa konflikteja. Esimerkiksi C:ssä ehdollisen lauseen syntaksi on:

looginen - TAI - lauseke ? lauseke : ehdollinen - lauseke

Ja C++:ssa:

looginen - TAI - lauseke ? lauseke : tehtävä - lauseke

Tästä johtuen ilmaus:

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

havaitaan eri tavalla näillä kahdella kielellä. C:ssä lauseke on syntaktisesti virheellinen, koska ehdollisen lauseen tulos ei voi toimia lv- arvona (eli osoituskäskyn vasen puoli).

C++:ssa lauseke jäsennetään kelvollisesti: [1]

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

Bittikohtaisten loogisten operaattoreiden ensisijaisuus on jokseenkin epäintuitiivinen [2] . Käsitteellisesti &, ja |ovat samat aritmeettiset operaattorit kuin *ja +vastaavasti.

Lauseketta käsitellään syntaktisesti muodossa , mutta lauseke vastaa sanaa . Tästä johtuen on usein tarpeen käyttää sulkeita määrittämään tarkasti arviointijärjestys. a & b == 7a & (b == 7)a + b == 7(a + b) == 7

Operaattorin synonyymit C++:ssa

C++-standardi määrittelee [3] digrafia joillekin operaattoreille:

Digraph Vastaava merkkijono
ja &&
bitand &
ja_eq &=
tai ||
bitor |
or_eq |=
xor ^
xor_eq ^=
ei !
not_eq !=
kompl ~

Digrafeja voidaan käyttää samalla tavalla kuin operaattoreita, ne ovat operaattoreiden synonyymejä. Esimerkiksi digrafia " " voidaan käyttää korvaamaan "bittisesti AND" ja "get address" -operaattorit tai viittaustyyppien määrittelyssä. Siten koodi " " vastaa koodia " ". bitandint bitand ref = n;int & ref = n;

ANSI/ISO C -standardi määrittelee luetellut digrafit vakioiksi #define(katso esiprosessori ). Vakiot määritellään otsikkotiedostossa " iso646.h". C-yhteensopivuutta varten C++-standardi määrittelee valeotsikkotiedoston " ciso646".

Muistiinpanot

  1. Onko C/C++-kolmiooperaattorilla sama etusija kuin osoitusoperaattoreilla? . pinon ylivuoto. Haettu 22. syyskuuta 2019. Arkistoitu alkuperäisestä 6. elokuuta 2020.
  2. Historia (downlink) . Haettu 11. tammikuuta 2013. Arkistoitu alkuperäisestä 22. kesäkuuta 2013. 
  3. ISO/IEC JTC1/SC22/WG21 - C++-standardikomitea . ISO/IEC 14882:1998(E) C++-  ohjelmointikieli . - International Group for the Standardization of the C++ Programming Language, 1998. - S. 40-41.

Linkit