Newsgroup: it.comp.lang.c++
Titolo: ,?:

Mi pare che i due operatori in oggetto vengano un po' sottovalutati.
Se usati in coppia e con disciplina, possono risultare molto versatili.
Es:
#include <cstdlib>
#include <iostream>
int main()
{
     unsigned a, m, n;
     while (a = rand(),
            m = a*(a*(a+3)+5)+7,
            (a > m) ? (n = rand(),
                       m *= n*(n+9)+1)
                    : (m *= a*(a+3)+1))
     {
         std::cout << m << std::endl;
     }
}
oppure, un po' più esplicito e sicuro,
#include <cstdlib>
#include <iostream>
int main()
{
     unsigned a, m, n, ret;
     while (a = rand(),
            m = a*(a*(a+3)+5)+7,
            ((a > m) ? (n = rand(),
                        m *= n*(n+9)+1)
                     : (m *= a*(a+3)+1)),
            ret = m)
     {
         std::cout << ret << std::endl;
     }
}
Kiuhnm

 Mi pare che i due operatori in oggetto vengano un po' sottovalutati.
pure troppo... la virgola (dall'alto della mia ignoranza, eh!) mica sapevo
neanche che esistesse ^^;
-- 
Under construction

 
non certo nell'esempio che hai postato, in cui non si capisce un cavolo 
di cosa sta succdendo.
Il comma operator per quel che mi riguarda potrebbe essere 
tranquillamente eliminato sedutastante, genera codice difficilmente 
leggibile e contraddice l'idea di base della buona programmazione 
sequenziale, ovverosia che ogni riga di programma esegua una sola 
operazione.
Il conditional operator invece non e' poi cosě desueto, e mi piace il 
fatto che renda molto compatte le espressioni di assegnazione banali, tipo:
bool is_even = (i%2 == 0) ? true : false;
Zeppe

Se usati in coppia e con disciplina, possono risultare molto versatili.
ROTFL !

 bool is_even = (i%2 == 0) ? true : false;
Wow.
Kiuhnm

 neanche che esistesse ^^;
In realtà è semplice, ma potente. L'idea è alla base del 99% dei 
linguaggi funzionali.
La virgola valuta sia l'operando a sinistra che quello a destra, però 
restituisce solo il valore di quello a destra. In presenza di più 
operandi, soltanto il valore dell'ultimo viene restituito.
Es:
int io_valgo_4 = (1,2,3,4);
int m;
int io_valgo_3 = (m = 2, m+1);
Le espressioni vengono sempre valutate da sinistra verso destra.
Kiuhnm

 Le espressioni vengono sempre valutate da sinistra verso destra.
del tipo, il tuo codice, non e' piu' leggibile se scritto come
int io_valgo_4=4;
int m=2;
int io_valgo_3=m+1;
?
almeno, io lo capisco di piu' :D (parlo sia dell'esempio scemo preso in
esame che di cose piu' complesse...)
-- 
Under construction

 Wow.
Non e' una gara a chi genera il codice che si capisce di meno. Un codice 
che non si capisce al volo e' spazzatura. Il tempo della gente vale 
denaro, e nessuno ha voglia di buttare denaro a cercare di capire un 
codice incomprensibile. Ci sono libri e libri su questo...
Ciao,
Zeppe

 Se usati in coppia e con disciplina, possono risultare molto versatili.
Come no :-)
Anche l'Assembler, se usato con disciplina, è incredibilmente potente e 
versatile :-)
Peccato che oggigiorno se ne trovino così pochi, di programmatori 
disciplinati... o tempora, o mores ^_^

 bool is_even = (i%2 == 0) ? true : false;
Voglio sperare che tu abbia sbagliato esempio:
bool is_even = i%2 == 0;
(che per altro si potrebbe scrivere addirittura come
bool is_even = ! ( i%2 );
anche se considero la conversione implicita da intero a booleano un po'
un'aberrazione).
Ciao,
Nicola

 un'aberrazione).
Era un esempio semplice... ma chiaro. Per il resto, probabilmente il 
codice piu' efficente sarebbe:
bool is_even = !(i&1);
ciao,
Zeppe

 bool is_even = !(i&1);
stravecchia obiezione: come la mettiamo coi numeri negativi non
rappresentati in complemento-a-1?
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy              ROT13: 
ybe...@cq.vasa.vg

 
touche'! :)
Ciao,
Zeppe

 rappresentati in complemento-a-1?
Forse c'e' un 'non' di troppo? Ammetto di essere arrugginito
sull'argomento, ma secondo me e' proprio coi numeri negativi
rappresentati in complemento a 1 che l'istruzione qui sopra non e'
corretta.
Ciao,
Nicola

 Forse c'e' un 'non' di troppo?
si.  scusate...  riassumo le rappresentazioni piu' comuni:
-1 complemento a uno: 111...110
   complemento a due: 111...111
   sign-magnitude:    100...001
   excess-127:        lasciato al lattore


 ?
Sě. Niente č migliore in assoluto.
Se vuoi prova a "tradurre" il mio codice iniziale e posta il codice.
Kiuhnm

 un'aberrazione).
Aggiungo una nota riguardante l'operatore '%'.
E' interessante notare che x % n č in (-n,n) anziché in [0,n).
Kiuhnm

 E' interessante notare che x % n č in (-n,n) anziché in [0,n).
a questo punto diciamo anche che se i due operandi di % non sono tutti e 
due non negativi (in tal caso si e' garantiti che anche il risultato e' 
non negativo), il segno del risultato e' definito dall'implementazione, 
quindi bisogna farci attenzione ;)
Ciao,
Zeppe

 E' interessante notare che x % n è in (-n,n) anziché in [0,n).
sicuro?  non ho sottomano lo standard del c++, ma ISO/IEC 9899:1999
6.5.5.6 (aka C99) dice:
"When integers are divided, the result of the / operator is the
algebraic quotient with any fractional part discarded.  If the
quotient a/b is representable, the expression (a/b)*b + a%b shall
equal a.".
se a e b sono interi positivi, lo e' anche a/b.  (a/b)*b non puo'
essere superiore ad a; quindi a%b *deve* essere positivo.
se poi consideriamo segni negativi, le cose cambiano...


    excess-127:        lasciato al lattore
excess-127 non è permesso. La ripresentazionne degli unsigned
deve essere una ripresentazionne binario pura, allors da
essempio, 0 deve avere tutti bits a 0 (da parte bits di padding,
che non entrono nel valore). E la ripresentazionne del typo
signed che corresponde deve aver la stessa ripresentazionne per
i valori communi.
E isEven si scrive:
    bool isEven = i % 2 == 0 ;
Sempre---ogni altre cosa è obfuscazione (una "faute
professionnelle grave", in francese).
--
James Kanze                                           GABI Software
Conseils en informatique orientée objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, 
+33 (0)1 30 23 00 34

 #include <iostream>

Si vede ch'è il primo aprile in Italia:-). O seno, preparisci
per il IOCCC.


 professionnelle grave", in francese).
in base a che cosa?
Per esempio, per me sarebbe piu' chiaro scrivere
bool isEven = (i % 2 == 0) ;
si capisce di piu'.
Ciao,
Zeppe

 che gli altri operatori?
io uso (SPESSO) la virgola, in due contesti piuttosto limitati
nelle parentesi di inizializzazione/controllo dei cicli for, 
while, do etc, per inizializzare molte variabili in poco spazio.
Oppure nelle funzioncine monoriga col solo statement return, che 
perň qualche calcoletto devono farlo o hanno uno o due effetti 
collaterali. Lo fanno e ritornano un risultato finale in una 
sola istruzione.
Va da se che č una concisione che non riesco a usare tranne che 
nei casi molto semplici. In altri, che non leggo facilmente, 
preferisco non usarli.
Rarissimamente uso la virgola come evaluator (e non come 
separator) nelle chiamate di funzioni con calcoli triviali da 
eseguire contestualmente alla chiamata,
Ma in effetti li apprezzo entrambi (anche perché la virgola non 
sono molti linguaggi a usarla come evaluator operator)
ciao
Soviet_Mario


 
Bah, se proprio vogliamo, mille volte meglio cosi':
bool is_even = (i%2 == 0);
--
Roal Zanazzi

 
Affermazione alquanto estremista, se mi lasci passare il termine.
Ad esempio, non vedo cosa ci sia di male in questa:
bool isEven = (i % 2) == 0;
(soprattutto se il malcapitato deve spesso destreggiarsi tra 2 o 3 
linguaggi di programmazione, quando va bene ;-)
--
Roal Zanazzi

 
Perche' da voi sta per finire il Fruttidoro? :-P
Ehi, tra un po' ci sono i giorni Sanculottidi! <vbg>
Scusate, non ho resistito...
--
Roal Zanazzi

 se poi consideriamo segni negativi, le cose cambiano...
Gli interi possono essere anche negativi (a differenza dei naturali).
Kiuhnm

 Gli interi possono essere anche negativi (a differenza dei naturali).
e' per questo che succede questa cosuccia.  si chiama "implementation
dependent behaviour": ogni compilatore conformante allo Standard e'
libero di restituire -6 o -5 come risultato di -35/6.


Maurizio Loreti wrote:
[...]
Non riesco proprio a capire dove vuoi arrivare.
Ho semplicemente affermato di stare attenti.
Kiuhnm

 Ho semplicemente affermato di stare attenti.
                    ^^^^^^^^^
suggerito
Kiuhnm

 molti linguaggi a usarla come evaluator operator)
Considera
int func()
{
   int m = 34;
   return m*m;
}
Questa equivale, in un linguaggio funzionale, a
func()
   m = 34
   m*m
end
Dopo che le espressioni sono state valutate, viene restituito il valore 
dell'ultima.
Applicazioni in C++?
Consideriamo un semplice while:
while (a*f(a) + b/f(a))
{
   ...
}
Non sempre è indicato o corretto chiamare f(a) due volte.
Solitamente si usa
int fa = f(a);
while (a*fa + b/fa)
{
   ...
   fa = f(a);
}
In questi casi può essere conveniente usare
int fa;
while (fa = f(a), a*fa + b/fa)
{
   ...
}
Kiuhnm

 }
Io un programma del genere lo scriverei nel seguente modo:
#include <cstdlib>
#include <iostream>
int main()
{
     unsigned a, m, n;
     while (true) {
         a = rand();
         m = a*(a*(a+3)+5)+7;
         if (a > m) {
             n = rand();
             m *= n*(n+9)+1);
         } else {
             m *= a*(a+3)+1;
         }
         if (m == 0) break;
         std::cout << m << std::endl;
     }
}
Io uso parecchio i "while (true)" e i "break"; uso, ma non 
massicciamente, l'espressione condizionale; non uso mai l'operatore ",".
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila

 massicciamente, l'espressione condizionale; non uso mai l'operatore ",".
Allora abbiamo le stesse abitudini.
Qualcuno potrebbe voler evitare il break:
do
{
   <calcola m>
   if (m)
   {
     ...
   }
} while (m);
Non ci vedo un gran guadagno comunque...
Ciononostante la virgola è IMHO molto elegante in espressioni brevi:
while (m = rand(), m*m)
{
}
Kiuhnm

 rappresentati in complemento-a-1?
Esistono processori che rappresentano gli interi negativi in modo 
diverso dal complemento a 2?

 si capisce di piu'.
Accettato. Argumentavo contra i&1, non contra un parentese di
più o di meno. Anch'io metto a volte le parentesi (seguendo le
abitudine nella ditta dove mi trovo).


 bool isEven = (i % 2) == 0;
Ne anch'io. Per me, é la stessa cosa. Argumentava contra cose
comme !(i&1).


 equal a.".
É un'evoluzione. In ISO/IEC 14882:1998 (§5.6/4) si dice: "The
binary / operator [...] If both operands are nonnegative then
the remainder is nonnegative; if not, the sign of the remainder
is implementation-defined." Diceva anche cosi in ISO/IEC
9899:1990. Il gruppo C l'hanno preciso---dal modo, in fatto, che
si passava su tutti i hardware. É ancore il regolo in Fortran.
Il draft della nuova versione di C++ dice sempre la stessa cosa.
Ma credo che prima la sua adoptazione sarà reso compatibile di
nuovo col C. E perche corresponde in fatti alla pratica
esistante, credo che puoi già ci contarti.


 -35 = 6(-6) + 1
Non é quella della norma C, neanche quella di Fortran. E non è
il risultato che da i processori.


 abitudine nella ditta dove mi trovo).
Ah sě, scusami non avevo capito a che cosa ti riferivi! Sono 
perfettamente d'accordo, le manipolazioni di bit vanno trattate con 
estrema cura, e in genere diciamo che, come buona norma (e con 
attenzione), solo quando si intende lavorare effettivamente a livello di 
byte.
Ciao,
Zeppe