2012-07-02 12 views
5

So weiß ich, dass C++ ein Operator Präzedenz hat und dassC/C++ Math Order of Betrieb

int x = ++i + i++; 

ist nicht definiert, weil pre ++ und poste ++ auf dem gleichen Niveau sind und somit gibt es keine Möglichkeit wird, die man sagen zuerst berechnet werden. Aber was ich fragte mich, ob

int i = 1/2/3; 

ist undefiniert ist. Der Grund, warum ich frage, ist, weil es mehrere Möglichkeiten gibt, das zu betrachten (1/2)/3 ODER 1/(2/3). Meine Vermutung ist, dass es ein undefiniertes Verhalten ist, aber ich möchte es bestätigen.

+3

Nein, es ist nicht undefiniert. Es ist (eins geteilt durch zwei) geteilt durch drei. Es ist mit anderen Worten ein gewöhnlicher mathematischer Ausdruck. –

+0

Ich denke, dein Denken ist hier ein wenig vage über das erste und das blutete in dein Nachdenken über das zweite. Die erste läuft auf die Reihenfolge der Argumentauswertung für eine undefinierte Funktion hinaus. Das heißt, wenn Sie es als 'Operator + (++ i, i ++)' betrachten, springt es direkt auf Sie. –

+1

C++ (und die meisten anderen Programmiersprachen) haben eine definierte Rangordnung, die der Mathematik entlehnt ist. Sie betrachten einen Ausdruck nicht mehrfach; mathematische Operationen haben eine Hierarchie. Sie können jedoch die Reihenfolge einer Operation mit (gut platzierten) Klammern ändern. –

Antwort

5

In Ihrem Beispiel der Compiler frei bewerten "1" „2 "und" 3 "in beliebiger Reihenfolge, und dann die Divisionen von links nach rechts anwenden.

Es ist das gleiche für das i ++ + i ++ Beispiel. Es kann die i ++ in beliebiger Reihenfolge auswerten und da liegt das Problem.

Es ist nicht so, dass die Präzedenz der Funktion nicht definiert ist, sondern die Reihenfolge der Auswertung ihrer Argumente.

17

Wenn Sie die C++ sehen operator precedence and associativity, werden Sie sehen, dass der Divisionsoperator wird von links nach rechts assoziativ, was bedeutet, wird dies als (1/2)/3 ausgewertet werden, da:

Operatoren, die in der sind Die gleiche Zelle (es können mehrere Reihen von Operatoren in einer Zelle aufgelistet sein) werden mit der gleichen Priorität in der angegebenen Richtung ausgewertet. Zum Beispiel wird der Ausdruck a = b = c wegen der Assoziation von rechts nach links als a = (b = c) und nicht als (a = b) = c geparst.

5

Das erste Code-Snippet ist ein undefiniertes Verhalten, da die Variable i mehrmals zwischen Sequenzpunkten geändert wird.

Das zweite Codefragment ist definiertem Verhalten und ist äquivalent zu:

int i = (1/2)/3; 

als Betreiber / hat links-nach-rechts-Assoziativität.

+0

Kannst du weiter erklären, warum das erste Code-Snippet ein nicht definiertes Verhalten ist? Es gibt die Ausgabe 10, wenn Sie "i = 4" verwenden. Entschuldigung, bin ein Neuling. – akaHuman

+0

@ shrey347, siehe http://c-faq.com/expr/seqpoints.html – hmjd

2

Es definiert ist, geht es von links nach rechts:

#include <iostream> 

using namespace std; 

int main (int argc, char *argv[]) { 
    int i = 16/2/2/2; 
    cout<<i<<endl; 
    return 0; 
} 

print "2" anstelle von 1 oder 16

0

Es könnte sein, dass es nicht definiert ist, weil Sie einen int gewählt haben, der die Menge der ganzen Zahlen ist. Probieren Sie ein Double oder Float, die Fraktionen enthalten.