Operatori in C e C++: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
m Bot: inserimento portale (via JWB)
 
(21 versioni intermedie di 2 utenti non mostrate)
Riga 1:
Questa è una lista degli [[Operatore (informatica)|operatori]] nei [[Linguaggio di programmazione|linguaggi di programmazione]] [[C (linguaggio di programmazione)|C]] e [[C++]]. Tutti gli operatori seguenti sono implementabili in quest'ultimo linguaggio, mentre invece altri non lo sono in C, come nel caso degli operatori di [[conversione di tipo]] (casting), ossia <code>const_cast</code>, <code>static_cast</code>, <code>dynamic_cast</code>, e <code>reinterpret_cast</code><ref name=":0">{{Cita libro|autore=Luis Joyanes Aguilar|titolo=Fondamenti di programmazione in C++. Algoritmi, strutture dati e oggetti|edizione=II edizione in lingua italiana|anno=2008|editore=[[McGraw-Hill Education]]|città=[[Madrid]]-[[Milano]]|ISBN=978-88-386-6477-9}}</ref><ref>{{Cita libro|autore=Stanley Lippman|autore2=Josée Lajoie|autore3=Barbara Moo|titolo=C++ Primer|anno=2013|url=https://archive.org/details/cprimer0000lipp_5thed|edizione=V edizione|editore=Addison-Wesley Professional|ISBN=978-0321714114}}</ref><ref>{{Cita web|url=https://www.html.it/pag/72598/conversione-di-tipo/|titolo=Conversione di tipo|sito=HTML.it|accesso=2024-09-14}}</ref>.
Questa è una lista degli [[Operatore (informatica)|operatori]] nei [[Linguaggio di programmazione|linguaggi di programmazione]] [[C (linguaggio di programmazione)|C]] e [[C++]]. Tutti gli operatori elencati di seguito (eccetto ''typeof'') esistono nel linguaggio C++, mentre in C solo quelli indicati nella colonna “Incluso in C”.
 
Molti degli operatori disponibili in C e C++ sono implementabili pure in altri linguaggi della cosiddetta “famiglia C”, quali [[C sharp|C#]], [[D (linguaggio di programmazione)|D]], ma anche [[Java (linguaggio di programmazione)|Java]], [[Perl]] e [[PHP]], mantenendo le medesime caratteristiche mostrate (arietà, posizione e associatività)<ref>{{Cita web|url=https://www.andreaminini.com/programmazione/c/c-sharp|titolo=Il linguaggio C#|sito=www.andreaminini.com|lingua=it-IT|accesso=2024-08-30}}</ref><ref>{{Cita web|url=https://dlang.org/spec/operatoroverloading.html|titolo=Operator Overloading - D Programming Language|sito=dlang.org|accesso=2024-08-30}}</ref>.
C++ include inoltre gli operatori ''type conversion'' (): <code>const_cast</code>, <code>static_cast</code>, <code>dynamic_cast</code>, e <code>reinterpret_cast</code>. La formattazione di questi operatori intende che il livello di precedenza è irrilevante.
 
== Sintassi degli operatori ==
Molti degli operatori disponibili in C e C++ sono implementabili anche in altri linguaggi della “C family”, quali [[C sharp|C#]], [[D (linguaggio di programmazione)|D]], ma anche [[Java (linguaggio di programmazione)|Java]], [[Perl]] e [[PHP]], con le medesime caratteristiche mostrate (precedenze, associatività e semantica).
Nelle tabelle seguenti, <code>a</code>, <code>b</code> e <code>c</code> rappresentano valori validi qualsiasi (''literals'', valori da variabili, oppure ''return value'') o, in alcuni casi specifici, nomi di oggetti o ''lvalues''. <code>R</code>, <code>S</code> e <code>T</code> indicano qualsiasi tipo, mentre <code>K</code> indica un tipo di classe o un tipo ''enum''<ref>{{Cita web|url=https://www.math.unipd.it/~sperduti/CORSO-C++/Operatori.htm|titolo=1.3 Operatori.|sito=www.math.unipd.it|accesso=2024-08-30}}</ref><ref>{{Cita web|url=https://www.html.it/pag/15482/operatori-booleani/|titolo=Operatori booleani|sito=HTML.it|accesso=2024-08-30}}</ref>.
 
== Overloading degli operatori ==
[[C++]] possiede molti operatori già predefiniti in grado di operare su vari [[Tipo di dato|tipi di dato]], perciò si può parlare di “operatori già sovraccaricati”. Per esempio l’operatore <code>+</code> può essere implementato per sommare sia due variabili di tipo <code>int</code> (interi), sia due variabili di tipo <code>float</code> o <code>double</code> (variabili a virgola mobile).
 
Oltre a quando detto in precedenza, il programmatore può anche “estendere” l’operatività di ciascuno di essi; per esempio operandi complessi definiti con le classi, si potrebbero trattare anche come se fossero dati semplici.
 
In C++ è possibile sovraccaricare tutti gli operatori predifiniti, con l’eccezione su accesso al membro <code>(.)</code>, indirezione di accesso al membro <code>(.*)</code> e risoluzione di ambito <code>(::)</code>.
 
Nel caso degli operatori, il numero degli operandi e la priorità dell’operatore sovraccaricato sono le stesse dell’operatore predefinito, mentre il nuovo operatore può essere definito come una funzione membro oppure come una ''funzione friend'' (funzione amica).
 
== Tabella degli operatori ==
Nelle tabelle seguenti, <code>a</code>, <code>b</code> e <code>c</code> rappresentano valori validi qualsiasi (''literals'', valori da variabili, oppure ''return value'') o, in alcuni casi specifici, nomi di oggetti o ''lvalues''. <code>R</code>, <code>S</code> e <code>T</code> indicano qualsiasi tipo, mentre <code>K</code> indica un tipo di classe o un tipo ''enum''.
 
=== Operatori aritmetici ===
Tutti gli operatori aritmetici esistono sia in [[C (linguaggio di programmazione)|C]] e C++ e possono essere, come già indicato, sovraccaricati solo in [[C++]]<ref>{{Cita web|url=https://www.britannica.com/technology/C-computer-language|titolo=C++ {{!}} Definition, History, & Facts {{!}} Britannica|sito=www.britannica.com|lingua=en|accesso=2024-08-30}}</ref>.
{| class="wikitable"
|+
Riga 25 ⟶ 14:
! colspan="2" |Esempi di implementazione in C++
|-
!Come membro di unadella classe K
!Fuori dalla classe
|-
Riga 90 ⟶ 79:
|}
 
=== Operatori di confronto/operatori relazionali ===
Tutti gli operatori di confronto possono essere sovraccaricati solo in [[C++]]. Dal [[C++20]], l'operatore di [[Disuguaglianza (matematica)|disuguaglianza]] viene generato automaticamente se viene definito <code>operator==</code> e tutti e quattro gli operatori relazionali vengono generati automaticamente se viene definito <code>operator<=></code>.
{| class="wikitable"
Riga 99 ⟶ 88:
! colspan="2" |Esempi di implementazione in C++
|-
!Come membro di unadella classe K
!Fuori dalla classe
|-
!Uguale
|<code>a '''a="='''" b</code> | <code>a = b</code>
|{{Sit}}
|<code>bool K::operator ==(S const& b) const;</code>
Riga 132 ⟶ 121:
|<code>bool K::operator <=(S const& b) const;</code>
|<code>bool operator <=(K const& a, S const& b);</code>
|-
|
|
|
|
|
|}
 
=== Operatori logici (o booleani) ===
Tutti gli operatori logici (o [[Booleano (informatica)|booleani]]<ref>L'accezione ''booleana'' è stata coniata in onore del matematico [[George Boole]]. </ref>) sono esistenti sia in [[C (linguaggio di programmazione)|C]] che in [[C++]] e possono essere chiaramente sovraccaricati solo in quest'ultimo linguaggio di programmazione.
 
Nonostante la possibilità di sovraccarico in C++, tale operazione è sconsigliata con AND logico e OR logico sia sconsigliato perché, come operatori sovraccaricati, si comporterebbero come normali chiamate di funzione, il che significa che ''entrambi'' i loro operandi verrebbero valutati, perdendo di conseguenza la loro importante [[valutazione di McCarthy]]. <ref>{{Cita web|url=https://isocpp.org/wiki/faq/operator-overloading}}</ref>
{| class="wikitable" style="width:100%"
! colspan="2" rowspan="2" |OperatorNome namedell'operatore
! rowspan="2" |SyntaxSintassi
! colspan="2" | Esempi di implementazione in C++
! rowspan="2" |Included<br /><br />in [[C (linguaggio di programmazione)|C]]
! colspan="2" |Prototype examples
|-
! Come membro della classe K
!As member of K
! Fuori dalla classe
!Outside class definitions
|-
!NOT logico
| class="table-rh" colspan="2" {{rh}} width="23%" |Equal to
| align="center" width="11%" | <code>a '''==!''' ba</code>
|<code>bool K::operator !();</code>
| width="8%" {{Sit}}
| width="25%" |{{cpp|1=<code>bool K::operator ==!(SK const& ba) const;}}</code>
| width="25%" |{{cpp|1=bool operator ==(K const& a, S const& b);}}
|-
!AND logico
| class="table-rh" colspan="2" {{rh}} |Not equal to
| style="text-align:center;" | <code>a '''!=&&''' b</code>|| {{Sit}}
|{{cpp|1=<code>bool K::operator !=&&(S const& b) const;}}</code>
|{{cpp|1=<code>bool operator !=&&(K const& a, S const& b);}}</code>
|-
| class="table-rh" colspan="2" {{rh}} |Greater than
| style="text-align:center;" |<code>a '''>''' b</code>|| {{Sit}}
|{{cpp|bool K::operator >(S const& b) const;}}
|{{cpp|bool operator >(K const& a, S const& b);}}
|-
!OR logico
| class="table-rh" colspan="2" {{rh}} |Less than
| style="text-align:center;" | <code>a '''<nowiki>||</nowiki>''' b</code>|| {{Sit}}
|{{cpp|<code><nowiki>bool K::operator <||(S const& b) const;}}</nowiki></code>
|{{cpp|<code><nowiki>bool operator <||(K const& a, S const& b);}}</nowiki></code>
|}
 
=== Operatori bit a bit ===
Tutti gli operatori bit a bit (o di manipolazione dei bit) esistono sia [[C (linguaggio di programmazione)|C]] che [[C++]] e possono essere sovraccaricati soltanto nel linguaggio inventato da [[Bjarne Stroustrup]]<ref>{{Cita web|url=https://www.treccani.it/enciclopedia/linguaggio-c_(Enciclopedia-della-Scienza-e-della-Tecnica)/|titolo=Linguaggio c++ - Enciclopedia|sito=Treccani|lingua=it|accesso=2024-08-30}}</ref>.
{| class="wikitable"
|+
! rowspan="2" |Nome dell'operatore
! rowspan="2" |Sintassi
! colspan="2" |Esempi di implementazione in C++
|-
!Come membro della classe K
| class="table-rh" colspan="2" {{rh}} |Greater than or equal to
!Fuori dalla classe
| style="text-align:center;" |<code>a '''>=''' b</code>|| {{Sit}}
|{{cpp|1=bool K::operator >=(S const& b) const;}}
|{{cpp|1=bool operator >=(K const& a, S const& b);}}
|-
!Complemento a uno (inversione di tutti i bit)
| class="table-rh" colspan="2" {{rh}} |Less than or equal to
| style="text-align:center;" |<code>a '''<=~''' ba</code>|| {{Sit}}
|{{cpp|1=bool<code>R K::operator <=~(S const& b) const;}}</code>
|{{cpp|1=bool<code>R operator <=~(K const& a, S const& b);}}</code>
|-
!AND bit a bit
| class="table-rh" colspan="2" rowspan="2" {{rh}} |[[Three-way comparison]]<ref name="threewaycomparison" group="lower-alpha" />
| rowspan="2" style="text-align:center;" |<code>a '''&#x3C;=&#x3E;''' b</code>|| rowspan="2"{{Not}}
|{{cpp|1=auto<code>R K::operator <=>&(const S &b);}}</code>
|{{cpp|1=auto<code>R operator <=>&(const K &a, const S &b);}}</code>
|-
!OR inclusivo bit a bit
| class="table-rh" colspan="2" {{rh}} |The operator has a total of 3 possible return types: <code>std::weak_ordering</code>, <code>std::strong_ordering</code> and <code>std::partial_ordering</code> to which they all are convertible to.
|<code>a '''<nowiki>|</nowiki>''' b</code>
|<code><nowiki>R K::operator |(S b);</nowiki></code>
|<code><nowiki>R operator |(K a, S b);</nowiki></code>
|-
!OR esclusivo bit a bit (OR exclusive, XOR)
|<code>a '''^''' b</code>
|<code>R K::operator ^(S b);</code>
|<code>R operator ^(K a, S b);</code>
|-
!Spostamento di tutti i bit verso sinistra
|<code>a '''<<''' b</code>
|<code>R K::operator <<(S b);</code>
|<code>R operator <<(K a, S b);</code>
|-
!Spostamento di tutti i bit verso destra
|<code>a '''>>''' b</code>
|<code>R K::operator >>(S b);</code>
|<code>R operator >>(K a, S b);</code>
|}
 
=== Operatori logicied espressioni di assegnamento ===
Tutti gli operatori e le espressioni di assegnamento sono esistenti sia in [[C (linguaggio di programmazione)|C]] che in [[C++]] e possono essere chiaramente sovraccaricate solo in quest'ultimo linguaggio di programmazione.
Tutti gli operatori logici esistono in C e C++ e possono essere sovraccaricati in C++, sebbene il sovraccarico dell'AND logico e dell'OR logico sia sconsigliato, perché come operatori sovraccaricati si comportano come normali chiamate di funzione, il che significa che ''entrambi'' i loro operandi vengono valutati, quindi perdono la loro proprietà [[Valutazione a corto circuito|di valutazione del cortocircuito,]] ben utilizzata e attesa. <ref>{{Cita web|url=https://isocpp.org/wiki/faq/operator-overloading}}</ref>
 
{| class="wikitable" style="width:100%"
Per gli operatori indicati, la semantica dell'espressione di assegnazione combinata incorporata <code>a ⊚= b</code> è equivalente a <code>a = a ⊚ b</code>, eccetto per il fatto che <code>a</code> viene valutata una sola volta.
! colspan="2" rowspan="2" |Nome dell'operatore
{| class="wikitable"
! rowspan="2" | Sintassi
|+
! colspan="2" | Esempi di prototipi C++
! rowspan="2" |Tipologia assegnamento
! rowspan="2" |Sintassi
! colspan="2" |Esempi di implementazione in C++
|-
! Come membro didella classe K
!Fuori Definizioni didalla classe esterna
|-
!Espressione semplice di assegnamento
| class="table-rh" colspan="2" {{rh}} width="23%" | [[Negation|Negazione logica (NOT)]]
|{{Tutto alignattaccato|1="center" width="11%" | <code>a '''!=''' ab</code>}}
| width="25%" | bool<code>R& K :: '''operator''' !=(S (b);</code>
|{{ND}}
| width="25%" | bool operator ! ( K a );
|-
! rowspan="10" |Assegnamenti composti
| class="table-rh" colspan="2" {{rh}} |[[Logical conjunction|Logico AND]]
| style="text-align:center;" | <code>a '''&&+=''' b</code>
| bool<code>R& K :: operator && +=( S b );</code>
| bool<code>R& operator && +=( K& a , S b );</code>
|-
|<code>a '''-=''' b</code>
| class="table-rh" colspan="2" {{rh}} |[[Logical disjunction|Logico OR]]
| style="text-align:center;" | <code>aR& '''<nowiki>||</nowiki>'''K::operator -=(S b);</code>
|<code>R& {{Codice|bool K::operator {{!!}}-=(K& a, S b);|linguaggio=cpp}}</code>
|-
| {{Codice|bool operator {{!!}}(K a, S b);|linguaggio=cpp}}
|<code>a '''*=''' b</code>
|<code>R& K::operator *=(S b);</code>
|<code>R& operator *=(K& a, S b);</code>
|-
|<code>a '''/=''' b</code>
|<code>R& K::operator /=(S b);</code>
|<code>R& operator /=(K& a, S b);</code>
|-
|<code>a '''%=''' b</code>
|<code>R& K::operator %=(S b);</code>
|<code>R& operator %=(K& a, S b);</code>
|-
|<code>a '''&=''' b</code>
|<code>R& K::operator &=(S b);</code>
|<code>R& operator &=(K& a, S b);</code>
|-
|<code>a '''<nowiki>|</nowiki>=''' b</code>
|<code><nowiki>R& K::operator |=(S b);</nowiki></code>
|<code><nowiki>R& operator |=(K& a, S b);</nowiki></code>
|-
|<code>a '''^=''' b</code>
|<code>R& K::operator ^=(S b);</code>
|<code>R& operator ^=(K& a, S b);</code>
|-
|<code>a '''<<=''' b</code>
|<code>R& K::operator <<=(S b);</code>
|<code>R& operator <<=(K& a, S b);</code>
|-
|<code>a '''>>=''' b</code>
|<code>R& K::operator >>=(S b);</code>
|<code>R& operator >>=(K& a, S b);</code>
|}
 
=== Operatori bitmembro ae bitpuntatore ===
{| class="wikitable"
Tutti gli operatori bit a bit esistono in C e C++ e possono essere sovraccaricati in C++.
|+
{| class="wikitable" style="width:100%"
! rowspan="2" |Nome operatore<ref name=":1">{{Cita libro|autore=Andrea Domenici|autore2=Graziano Frosini|titolo=Introduzione alla programmazione ed elementi di strutture dati con il linguaggio [[C++]]|edizione=VIII edizione|collana="Informatica", diretta da A. L. Frisiani|città=[[Milano]]/[[Pisa]]|ISBN=978-8846462022}}</ref>
! colspan="2" rowspan="2" |Operator name
! rowspan="2" |SyntaxSintassi
! rowspan="2" |Ammette overload (sovraccarico) in C++
! colspan="2" |Prototype examples
! rowspan="2" |Implementabile in C
! colspan="2" |Esempi di implementazione in C++
|-
!Come membro della classe K
!As member of K
!Fuori dalla classe
!Outside class definitions
|-
!Indicizzazione
| class="table-rh" colspan="2" {{rh}} width="23%" |[[Bitwise operation#NOT|Bitwise NOT]]
| align="center" width="11%" |<code>a'''~['''b''']'''a</code><br /><br />
|{{Sit}}
| width="25%" |{{cpp|R K::operator ~();}}
|{{Sit}}
| width="25%" |{{cpp|R operator ~(K a);}}
|<code>R& K::operator [](S b);</code>
<code>R& K::operator [](S b, ...); // since C++23</code>
|{{ND}}
|-
!Deferenziazione
| class="table-rh" colspan="2" {{rh}} |[[Bitwise operation#AND|Bitwise AND]]
| style="text-align:center;" |<code>a '''&*''' ba</code>
|{{Sit}}
|{{cpp|R K::operator &(S b);}}
|{{Sit}}
|{{cpp|R operator &(K a, S b);}}
|R& K::'''operator''' *();
|R& '''operator''' *(K a);
|-
!Indirizzo
| class="table-rh" colspan="2" {{rh}} |[[Bitwise operation#OR|Bitwise OR]]
| style="text-align:center;" |<code>a '''<nowiki>|</nowiki>&''' ba</code>
|{{Sit}}
|{{cpp|R K::operator {{!}}(S b);|lang=cpp}}
|{{Sit}}
|{{cpp|R operator {{!}}(K a, S b);|lang=cpp}}
|R* K::'''operator''' &();
|R* '''operator''' &(K a);
|-
!Deferenziazione e selezione
| class="table-rh" colspan="2" {{rh}} |[[Bitwise operation#XOR|Bitwise XOR]]
| style="text-align:center;" |<code>a '''^->''' b</code>
|{{Sit}}
|{{cpp|R K::operator ^(S b);}}
|{{Sit}}
|{{cpp|R operator ^(K a, S b);}}
|R* K::'''operator''' ->();
|-
|{{ND}}
| class="table-rh" colspan="2" {{rh}} |[[Bitwise shift|Bitwise left shift]]<ref name="bitshift" group="lower-alpha" />
| style="text-align:center;" |<code>a '''<<''' b</code>
|{{cpp|R K::operator <<(S b);}}
|{{cpp|R operator <<(K a, S b);}}
|-
!Selezione (object.member)
| class="table-rh" colspan="2" {{rh}} |[[Bitwise shift|Bitwise right shift]]<ref name="bitshift" group="lower-alpha" />{{Refn|name="rightbitshift"|group="lower-alpha"|According to the C99 standard, the right shift of a negative number is implementation defined. Most implementations, e.g., the GCC,<ref name="Integers">{{Citation | contribution = Integers implementation | url = //gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Integers-implementation.html#Integers-implementation | title = GCC 4.3.3 | publisher = GNU}}.</ref> use an [[arithmetic shift]] (i.e., sign extension), but a [[logical shift]] is possible.}}
| style="text-align:center;" |<code>a '''>>.''' b</code>
|{{Not}}
|{{cpp|R K::operator >>(S b);}}
|{{Sit}}
|{{cpp|R operator >>(K a, S b);}}
|{{ND}}
|{{ND}}
|-
!Deferenziazione e selezione con puntatore a membro
|<code>a'''->*'''b</code>
|{{Sit}}
|{{Not}}
|R& K::'''operator''' ->*(S b);
|R& '''operator''' ->*(K a, S b);
|-
!Selezione con puntatore a membro
|<code>a'''.*'''b</code>
|{{Not}}
|{{Not}}
|{{ND}}
|{{ND}}
|}
 
=== OperatoriAltri di assegnazioneoperatori ===
{| class="wikitable"
Tutte le espressioni di assegnazione esistono in C e C++ e possono essere sovraccaricate in C++.
|+
! rowspan="2" |Nome operatore
! rowspan="2" |Sintassi
! rowspan="2" |Ammette overload (sovraccarico) in C++
! rowspan="2" |Implementabile in C
! colspan="2" |Esempi di implementazione in C++
|-
!Come membro della classe K
!Fuori dalla classe
|-
!Chiamata di funzione
|<code>a'''('''a1, a2''')'''</code>
|{{Sit}}
|{{Sit}}
|R K::operator ()(S a, T b, ...);
|
|-
!Virgola
|<code>a''',''' b</code>
|{{Sit}}
|{{Sit}}
|<code>R K::'''operator''' ,(S b);</code>
|<code>R '''operator''' ,(K a, S b);</code>
|-
!Espressione condizionale
|<code>a '''?''' b ''':''' c</code>
|{{Not}}
|{{Sit}}
|{{ND}}
|{{ND}}
|-
!Risolutore di visibilità
|<code>a'''::'''b</code>
|{{Not}}
|{{Not}}
|{{ND}}
|{{ND}}
|-
!Dimensione di oggetto o di tipo (''sizeof'')
|<code>'''sizeof''' a</code>
<code>'''sizeof''' (R)</code>
|{{Not}}
|{{Sit}}
|{{ND}}
|{{ND}}
|-
!Conversione di tipo ''static_cast''
|<code>'''static_cast'''<R>(a)</code>
|{{Sit}}
|{{Not}}
|<code>K::'''operator''' R();</code>
<code>'''explicit''' K::'''operator''' R();</code> ''since C++11''<ref>Per le conversioni definite dall'utente, il tipo di ritorno corrisponde implicitamente e necessariamente al nome dell'operatore, a meno che il tipo non sia dedotto. (es. <code>'''operator''' '''auto'''(), '''operator''' '''decltype'''('''auto''')()</code> etc.).</ref>
|{{ND}}
|-
!Conversione const ''const_cast''
|<code>'''const_cast'''<R>(a)</code>
|{{Not}}
|{{Not}}
|{{ND}}
|{{ND}}
|-
!Allocazione
|<code>'''new''' R</code>
|{{Sit}}
|{{Not}}
|<code>void* K::'''operator''' '''new'''(size_t x);</code>
|<code>void* '''operator''' '''new'''(size_t x);</code>
|-
!Allocazione di array
|<code>'''new''' R'''['''n''']'''</code>
|{{Sit}}
|{{Not}}
|<code>void* K::'''operator''' '''new'''[](size_t a);</code>
|<code>void* '''operator''' '''new'''[](size_t a);</code>
|-
!Deallocazione
|<code>'''delete''' a</code>
|{{Sit}}
|{{Not}}
|<code>void K::'''operator''' delete(void* a);</code>
|<code>void '''operator''' '''delete'''(void* a);</code>
|-
!Deallocazione di array
|<code>'''delete[]''' a</code>
|{{Sit}}
|{{Not}}
|<code>void K::'''operator''' '''delete'''[](void* a);</code>
|<code>void '''operator''' '''delete'''[](void* a);</code>
|}
 
== Overloading degli operatori ==
Per gli operatori indicati, la semantica dell'espressione di assegnazione combinata incorporata <code>a ⊚= b</code> è equivalente a <code>a = a ⊚ b</code>, eccetto per il fatto che <code>a</code> viene valutata una sola volta.
[[C++]] possiede molti operatori già predefiniti in grado di operare su vari [[Tipo di dato|tipi di dato]], perciò si può parlare di “operatori già sovraccaricati”. Per esempio l’operatore <code>+</code> può essere implementato per sommare sia due variabili di tipo <code>int</code> (interi), sia due variabili di tipo <code>float</code> o <code>double</code> (variabili a virgola mobile).
{| class="wikitable" style="width:100%"
 
! rowspan="2" |Operator name
Oltre a quando detto in precedenza, il programmatore può anche “estendere” l’operatività di ciascuno di essi; per esempio operandi complessi definiti con le classi, si potrebbero trattare anche come se fossero dati semplici<ref name=":0" />.
! rowspan="2" |Syntax
 
! colspan="2" |C++ prototype examples
In C++ è possibile sovraccaricare tutti gli operatori predefiniti, con l’eccezione su accesso al membro <code>(.)</code>, indirezione di accesso al membro <code>(.*)</code> e risoluzione di ambito <code>(::)</code>.
 
Nel caso degli operatori, il numero degli operandi e la priorità dell’operatore sovraccaricato sono le stesse dell’operatore predefinito, mentre il nuovo operatore può essere definito come una ''funzione membro'' oppure come una ''funzione friend'' (funzione amica)<ref>{{Cita pubblicazione|autore=Marco Cococcioni|titolo=Le classi nel linguaggio C++|editore=Dipartimento di Ingegneria dell'Informazione dell'[[Università di Pisa]]|url=http://docenti.ing.unipi.it/m.cococcioni/FdP/parte_2.pdf}}</ref>.
 
== Proprietà degli operatori ==
Ogni operatore possiede delle proprietà, in modo tale da permettere l'interpretazione univoca del significato di ogni singola espressione. Gli esempi che seguono sono tutti applicabili al linguaggio [[C++]] e, a seconda dei casi, anche al [[C (linguaggio di programmazione)|C]]<ref>{{Cita pubblicazione|autore=Marco Cococcioni|titolo=Programmazione in stile C, utilizzando il linguaggio C++|editore=Dipartimento di Ingegneria dell'Informazione dell'[[Università di Pisa]]|url=http://docenti.ing.unipi.it/m.cococcioni/FdP/parte_1.pdf}}</ref>.
 
=== Posizione ===
Un operatore può precedere gli operandi (o argomenti), seguirli oppure né precederli né seguirli<ref name=":1" />. In questi casi parleremo rispettivamente di operatori ''prefissi'', ''postfissi'' oppure ''infissi''.
 
=== Numero di operandi ===
Ogni operatore può avere un numero diverso di operandi (arietà). <syntaxhighlight lang="c++">
a[b]
</syntaxhighlight>Nel caso riportato, l'operatore di indicizzazione possiede due operandi, ossia le parentesi quadre. L'arietà può essere anche di tre operandi, come nel caso degli operatori condizionali, riportato di seguito:<syntaxhighlight lang="c++">
e1 ? e2 : e3
</syntaxhighlight>
 
=== Precedenza degli operatori ===
Ogni operatore possiede una propria precedenza<ref>''The ISO C 1999 standard, section 6.5.6 note 71'' (Technical report). ISO. 1999.</ref><ref name=":2">{{Cita pubblicazione|autore=Marco Cococcioni|titolo=Priorità degli operatori|editore=Dipartimento di Ingegneria dell'Informazione dell'[[Università di Pisa]]|url=http://docenti.ing.unipi.it/m.cococcioni/FdP/priorita_degli_operatori.pdf}}</ref>, rappresentata attraverso un numero naturale tra 1 e 18 in ordine decrescente, dove più è piccolo il numero, maggiore sarà la priorità; per esempio un operatore con priorità 1 avrà maggiore priorità su un operatore con priorità 13.
 
Nell'esempio che segue è possibile osservare una semplice applicazione pratica delle precedenze: <syntaxhighlight lang="c++" line="1">
#include <iostream>
using namespace std;
 
int main () {
int a = 5;
int b = 6;
int c = 8;
 
int op = a+b*c;
cout << op << endl; // Stampa a schermo
 
return 0;
}
</syntaxhighlight>L'operatore moltiplicazione (<code>*</code>) possiede priorità 5, mentre l'operatore addizione (<code>+</code>) possiede priorità 6; pertanto il risultato a schermo sarà '''53''' e non 19.
 
=== Associatività degli operatori ===
L'associatività indica l'ordine in cui vengono eseguiti gli operatori aventi la stessa priorità tra loro<ref name=":1" />. Viene riportato un semplice esempio con gli operatori di divisione (priorità 5). <syntaxhighlight lang="c++" line="1">
#include <iostream>
using namespace std;
 
int main (){
float a = 5.0;
float b = 6.0;
float c = 8.0;
 
float div = a/b/c;
cout << div << endl; // Stampa a schermo
 
return 0;
}
</syntaxhighlight>Nell'esempio precedente la stampa a schermo sarà '''0.104167''' perché l'operatore di divisione segue associatività a sinistra e, quindi, il calcolatore avrà eseguito la seguente equazione: <math>div = {(a/b) \over c}</math>.
 
=== Tabella delle precedenze e delle associatività ===
Nella tabella seguente sono elencati gli operatori di [[C (linguaggio di programmazione)|C]] e [[C++]] in ordine di priorità con le loro rispettive associatività. Essi sono sempre implementabili su C++, mentre, quelli appositamente indicati nella penultima colonna da sinistra, non lo sono in C<ref name=":1" /><ref name=":2" />.
{| class="wikitable"
|+
!Priorità
!Operatore
!Nome
!Implementabile in C
!Associatività
|-
! rowspan="2" |1
!As member of K
(priorità massima)
!Outside class definitions
|<code>class-name :: member</code>
<code>namespace-name :: member</code>
|'''Risolutore di visibilità'''
|{{Not}}
|sinistra
|-
|<code>:: member</code>
!Direct assignment
|'''Risolutore globale di visibilità'''
| style="text-align:center;" |{{Tutto attaccato|1=<code>a '''=''' b</code>}}
|{{Not}}
|{{cpp|1=R& K::operator =(S b);}}
|destra
| {{ND}}
|-
! rowspan="8" |2
!Addition assignment
| align="center" |<code>aobject '''+='''. bmember</code>
|'''Selezione'''
|{{cpp|1=R& K::operator +=(S b);}}
|{{Sit}}
|{{cpp|1=R& operator +=(K& a, S b);}}
|sinistra
|-
|<code>pointer -> member</code>
!Subtraction assignment
|'''Deferenziazione e selezione'''
| style="text-align:center;" |<code>a '''-=''' b</code>
|{{Sit}}
|{{cpp|1=R& K::operator -=(S b);}}
|sinistra
|{{cpp|1=R& operator -=(K& a, S b);}}
|-
|<code>array[ rvalue ]</code>
!Multiplication assignment
|'''Indicizzazione'''
| style="text-align:center;" |<code>a '''*=''' b</code>
|{{Sit}}
|{{cpp|1=R& K::operator *=(S b);}}
|sinistra
|{{cpp|1=R& operator *=(K& a, S b);}}
|-
|<code>function ( actual-argument-list )</code>
!Division assignment
|'''Chiamata di funzione'''
| style="text-align:center;" |<code>a '''/=''' b</code>
|{{Sit}}
|{{cpp|1=R& K::operator /=(S b);}}
|sinistra
|{{cpp|1=R& operator /=(K& a, S b);}}
|-
|<code>lvalue ++</code>
!Modulo assignment
|'''Postincremento'''
| style="text-align:center;" |<code>a '''%=''' b</code>
|{{Sit}}
|{{cpp|1=R& K::operator %=(S b);}}
|destra
|{{cpp|1=R& operator %=(K& a, S b);}}
|-
|<code>lvalue --</code>
!Bitwise AND assignment
|'''Postdecremento'''
| style="text-align:center;" |<code>a '''&=''' b</code>
|{{Sit}}
|{{cpp|1=R& K::operator &=(S b);}}
|destra
|{{cpp|1=R& operator &=(K& a, S b);}}
|-
|<code>static_cast type<rvalue></code>
!Bitwise OR assignment
|'''Conversione di tipo'''
| style="text-align:center;" |<code>a '''<nowiki>|</nowiki>=''' b</code>
|{{Not}}
|{{cpp|1=R& K::operator {{!}}=(S b);|lang=cpp}}
|sinistra
|{{cpp|1=R& operator {{!}}=(K& a, S b);|lang=cpp}}
|-
|<code>const_cast type<rvalue></code>
!Bitwise XOR assignment
|'''Conversione const'''
| style="text-align:center;" |<code>a '''^=''' b</code>
|{{Not}}
|{{cpp|1=R& K::operator ^=(S b);}}
|sinistra
|{{cpp|1=R& operator ^=(K& a, S b);}}
|-
! rowspan="13" |3
!Bitwise left shift assignment
| style="text-align:center;" |<code>a '''<<='''sizeof bobject</code>
<code>sizeof (type)</code>
|{{cpp|1=R& K::operator <<=(S b);}}
|'''Dimensione'''
|{{cpp|1=R& operator <<=(K& a, S b);}}
'''''di oggetto'''''
'''''di tipo'''''
|{{Sit}}
|destra
|-
|<code>++ lvalue</code>
!Bitwise right shift assignment
|'''Preincremento'''
| style="text-align:center;" |<code>a '''>>=''' b</code>
|{{Sit}}
|{{cpp|1=R& K::operator >>=(S b);}}
|destra
|{{cpp|1=R& operator >>=(K& a, S b);}}
|-
|<code>-- lvalue</code>
|'''Predecremento'''
|{{Sit}}
|destra
|-
|<code>~ rvalue</code>
|'''Complemento bit a bit'''
|{{Sit}}
|destra
|-
|<code>! rvalue</code>
|'''Negazione'''
|{{Sit}}
|destra
|-
|<code>- rvalue</code>
|'''Meno unitario'''
|{{Sit}}
|destra
|-
|<code>+ rvalue</code>
|'''Più unitario'''
|{{Sit}}
|destra
|-
|<code>& rvalue</code>
|'''Indirizzo'''
|{{Sit}}
|destra
|-
|<code>* rvalue</code>
|'''Deferenziazione'''
|{{Sit}}
|destra
|-
|<code>new type</code>
|'''Allocazione'''
|{{Not}}
|destra
|-
|<code>new type[]</code>
|'''Allocazione di array'''
|{{Not}}
|destra
|-
|<code>delete pointer</code>
|'''Deallocazione'''
|{{Not}}
|destra
|-
|<code>delete[] pointer</code>
|'''Deallocazione di array'''
|{{Not}}
|destra
|-
! rowspan="2" |4
|<code>object .* pointer-to-member</code>
|'''Selezione con puntatore a membro'''
|{{Not}}
|sinistra
|-
|<code>pointer ->* pointer-to-member</code>
|'''Deferenziazione e selezione con puntatore a membro'''
|{{Not}}
|sinistra
|-
! rowspan="3" |5
|<code>rvalue * rvalue</code>
|'''Moltiplicazione'''
|{{Sit}}
|sinistra
|-
|<code>rvalue / rvalue</code>
|'''Divisione'''
|{{Sit}}
|sinistra
|-
|<code>rvalue % rvalue</code>
|'''Modulo'''
|{{Sit}}
|sinistra
|-
! rowspan="2" |6
|<code>rvalue + rvalue</code>
|'''Addizione'''
|{{Sit}}
|sinistra
|-
|<code>rvalue - rvalue</code>
|'''Sottrazione'''
|{{Sit}}
|sinistra
|-
! rowspan="2" |7
|<code>rvalue << rvalue</code>
|'''Traslazione sinistra'''
|{{Sit}}
|sinistra
|-
|<code>rvalue >> rvalue</code>
|'''Traslazione destra'''
|{{Sit}}
|sinistra
|-
! rowspan="4" |8
|<code>rvalue < rvalue</code>
|'''Minore'''
|{{Sit}}
|sinistra
|-
|<code>rvalue <= rvalue</code>
|'''Minore o uguale'''
|{{Sit}}
|sinistra
|-
|<code>rvalue > rvalue</code>
|'''Maggiore'''
|{{Sit}}
|sinistra
|-
|<code>rvalue >= rvalue</code>
|'''Maggiore o uguale'''
|{{Sit}}
|sinistra
|-
! rowspan="2" |9
|<code>rvalue == rvalue</code>
|'''Uguale'''
|{{Sit}}
|sinistra
|-
|<code>rvalue != rvalue</code>
|'''Diverso'''
|{{Sit}}
|sinistra
|-
!10
|<code>rvalue & rvalue</code>
|'''AND bit a bit'''
|{{Sit}}
|sinistra
|-
!11
|<code>rvalue ^ rvalue</code>
|'''OR esclusivo bit a bit'''
|{{Sit}}
|sinistra
|-
!12
|<code><nowiki>rvalue | rvalue</nowiki></code>
|'''OR bit a bit'''
|{{Sit}}
|sinistra
|-
!13
|<code>rvalue && rvalue</code>
|'''AND logico'''
|{{Sit}}
|sinistra
|-
!14
|<code><nowiki>rvalue || rvalue</nowiki></code>
|'''OR logico'''
|{{Sit}}
|sinistra
|-
!15
|<code>co_await</code>
<code>co_yield</code>
|'''Coroutine'''
|{{Not}}
|destra
|-
!16
|<code>rvalue ? rvalue : rvalue</code>
|'''Espressione condizionale'''
|{{Sit}}
|sinistra
|-
! rowspan="11" |17
|<code>lvalue = rvalue</code>
|'''Assegnamento'''
|{{Sit}}
|destra
|-
|<code>lvalue += rvalue</code>
|'''Addizione e assegnamento'''
|{{Sit}}
|destra
|-
|<code>lvalue -= rvalue</code>
|'''Sottrazione e assegnamento'''
|{{Sit}}
|destra
|-
|<code>lvalue *= rvalue</code>
|'''Moltiplicazione e assegnamento'''
|{{Sit}}
|destra
|-
|<code>lvalue /= rvalue</code>
|'''Divisione e assegnamento'''
|{{Sit}}
|destra
|-
|<code>lvalue %= rvalue</code>
|'''Modulo e assegnamento'''
|{{Sit}}
|destra
|-
|<code>lvalue &= rvalue</code>
|'''AND bit a bit e assegnamento'''
|{{Sit}}
|destra
|-
|<code><nowiki>lvalue |= rvalue</nowiki></code>
|'''OR bit a bit e assegnamento'''
|{{Sit}}
|destra
|-
|<code>lvalue ^= rvalue</code>
|'''OR esclusivo bit a bit e assegnamento'''
|{{Sit}}
|destra
|-
|<code>lvalue <<= rvalue</code>
|'''Traslazione a sinistra e assegnamento'''
|{{Sit}}
|destra
|-
|<code>lvalue =>> rvalue</code>
|'''Traslazione a destra e assegnamento'''
|{{Not}}
|destra
|-
!18
(priorità minima)
|<code>expression , expression</code>
|'''Virgola'''
|{{Sit}}
|sinistra
|}
 
=== OperatoriCritiche membrosulle eprecedenze puntatoredegli operatori ===
La precedenza degli operatori logici bitwise è stata al centro di numerose critiche<ref>{{Cita web|url=https://www.bell-labs.com/usr/dmr/www/chist.html|titolo=Chistory|sito=www.bell-labs.com|accesso=2024-08-30}}</ref><ref>{{Cita web|url=https://www.perlmonks.org/?node_id=1159769|titolo=Re^10: next unless condition|sito=www.perlmonks.org|accesso=2024-08-30}}</ref>, poiché concettualmente, <code>&</code> e <code>|</code> sono operatori aritmetici come <code>*</code> e <code>+</code>.
{| class="wikitable" style="width:100%"
 
! colspan="2" rowspan="2" |Operator name
Per esempio, l'espressione <code>a & b == 7</code> viene sintatticamente analizzata come <code>a & (b == 7)</code>, mentre l'espressione <code>a + b == 7</code> viene analizzata come <code>(a + b) == 7</code>. Ciò richiede l'uso delle parentesi più spesso di quanto sarebbe altrimenti necessario.
! rowspan="2" |Syntax
 
! rowspan="2" |Can overload in C++
Storicamente, non esisteva una distinzione sintattica tra gli operatori bit a bit e quelli logici. Nei linguaggi [[BCPL]], [[B (linguaggio di programmazione)|B]] e nelle prime versioni di [[C (linguaggio di programmazione)|C]], gli operatori && e || non esistevano proprio; invece, <code>& |</code> aveva un significato diverso a seconda che venisse usato in un “contesto di valore di verità” (cioè quando ci si aspettava il ritorno di un valore [[Booleano (informatica)|booleano]], come in <code>if (a==b & c) {...}</code> e si comportava come un operatore logico, ma in <code>c = a & b</code> si comportava invece come un operatore bit a bit).
! rowspan="2" |Included<br /><br />in [[C (linguaggio di programmazione)|C]]
 
! colspan="2" |C++ prototype examples
La sintassi attuale è stata mantenuta soltanto per consentire la retrocompatibilità con le installazioni già esistenti.
 
Peraltro, in C++ (e nelle versioni successive di C) le operazioni di uguaglianza, con l'eccezione dell'operatore di confronto logico a tre, producono valori di tipo bool che sono concettualmente un singolo bit (1 o 0) e come tali non appartengono propriamente alle operazioni bit a bit.
 
== Sinonimi in C++ ==
[[C++]] definisce una serie di ''keywords'' che possono essere implementate come sinonimi rispetto agli operatori<ref>''ISO/IEC 14882:1998(E) Programming Language C++''. open-std.org – The C++ Standards Committee. 1 September 1998. pp. 40–41.</ref>; tali definizioni non sono assolutamente implementabili nel [[linguaggio C]].
 
{| class="wikitable"
!'''Keyword'''
!'''Operator'''
|-
|<code>and</code>
!As member of K
|<code>&&</code>
!Outside class definitions
|-
|<code>and_eq</code>
| class="table-rh" colspan="2" {{rh}} width="23%" |[[Indexer (programming)|Subscript]]
| align="center" width="11%" |<code>a'''['''b''']'''&=</code>
| width="8%" {{Sit}}
| width="8%" {{Sit}}
|{{cpp|R& K::operator [](S b);}}<br /><br />{{cpp|R& K::operator [](S b, ...); // since C++23}}<br /><br />
| width="25%" {{ND}}
|-
|<code>bitand</code>
| class="table-rh" colspan="2" {{rh}} |Indirection ("object pointed to by ''a''")
|<code>&</code>
| style="text-align:center;" |<code>'''*'''a</code>|| {{Sit}} || {{Sit}}
|{{cpp|R& K::operator *();}}
|{{cpp|R& operator *(K a);}}
|-
|<code>bitor</code>
| class="table-rh" colspan="2" {{rh}} |Address-of ("address of ''a''")
|<code><nowiki>|</nowiki></code>
| style="text-align:center;" |<code>'''&'''a</code>|| {{Sit}}<ref name="addressof2" group="lower-alpha"/> || {{Sit}}
|{{cpp|R* K::operator &();}}
|{{cpp|R* operator &(K a);}}
|-
|<code>compl</code>
| class="table-rh" colspan="2" {{rh}} |Structure dereference ("member ''b'' of object pointed to by ''a''")
|<code>~</code>
| style="text-align:center;" |<code>a'''->'''b</code>|| {{Sit}} || {{Sit}}
|{{cpp|R* K::operator ->();}}<br /><br />
| {{ND}}
|-
|<code>not</code>
| class="table-rh" colspan="2" {{rh}} |Structure reference ("member ''b'' of object ''a''")
|<code>!</code>
| style="text-align:center;" |<code>a'''.'''b</code>|| {{Not}} || {{Sit}}
| {{rh}} colspan="2" {{ND}}
|-
|<code>not_eq</code>
| class="table-rh" colspan="2" {{rh}} |Member selected by [[pointer-to-member]] ''b'' of object pointed to by ''a''<ref name="arrowstar" group="lower-alpha" />
|<code>!=</code>
| style="text-align:center;" |<code>a'''->*'''b</code>|| {{Sit}} || {{Not}}
|{{cpp|R& K::operator ->*(S b);}}
|{{cpp|R& operator ->*(K a, S b);}}
|-
|<code>or</code>
| class="table-rh" colspan="2" {{rh}} |Member of object ''a'' selected by [[pointer-to-member]] ''b''
|<code><nowiki>||</nowiki></code>
| style="text-align:center;" |<code>a'''.*'''b</code>|| {{Not}} || {{Not}}
|-
| {{rh}} colspan="2" {{ND}}
|<code>or_eq</code>
|<code><nowiki>|=</nowiki></code>
|-
|<code>xor</code>
|<code>^</code>
|-
|<code>xor_eq</code>
|<code>^=</code>
|}
Questi possono essere utilizzati esattamente come sostituti dei rispettivi simboli di punteggiatura; ciò significa, per esempio, che le espressioni <code>(a > 0 AND NOT flag)</code> e <code>(a > 0 && flag)</code> avranno un significato assolutamente identico.
<nowiki>
 
== Note ==
<references />
 
== Bibliografia ==
 
* {{Cita libro|autore=[[Bjarne Stroustrup]]|titolo=The C++ Programming Language|editore=Addison-Wesley|lingua=inglese|ISBN=978-0-201-70073-2}}
* {{Cita libro|autore=Andrea Domenici, Graziano Frosini|titolo=Introduzione alla programmazione ed elementi di strutture dati con il linguaggio C++|anno=2013|editore=Franco Angeli Editore|p=480|ISBN=978-88-464-6202-2}}
* {{Cita pubblicazione|autore=Marco Cococcioni|titolo=Fondamenti di programmazione|editore=Dipartimento di Ingegneria dell'Informazione dell'[[Università di Pisa]]|url=http://docenti.ing.unipi.it/m.cococcioni/FdP/parti_0_1_e_2_pronte_per_la_stampa.pdf}}
* {{Cita libro|autore=Luis Joyanes Aguilar|titolo=Fondamenti di programmazione in C++. Algoritmi, strutture dati e oggetti|editore=[[McGraw-Hill Education]]|città=[[Madrid]]-[[Milano]]|lingua=spagnolo|ISBN=978-88-386-6477-9}}
 
== Voci correlate ==
 
* [[C++]]
* [[C (linguaggio di programmazione)]]
* [[Scienze dell'Informazione|Scienza dell'informazione]]
* [[Linguaggio di programmazione]]
 
== Collegamenti esterni ==
 
* Volle, Adam. "C++". [[Enciclopedia Britannica|''Encyclopedia Britannica'']], 19 Jun. 2024, https://www.britannica.com/technology/C-computer-language;
* [https://learn.microsoft.com/en-us/cpp/?view=msvc-170 Microsoft C++, C, and Assembler documentation].
{{C++}}{{Linguaggio C}}
{{Principali linguaggi di programmazione}}{{Controllo di autorità}}
{{Portale|informatica}}
 
[[Categoria:C++]]
[[Categoria:C]]</nowiki>
<references group="lower-alpha" />