2013-08-04 7 views
5

Я искал и нашел формулу: a = (a + b) - (b = a) предполагается обменять две переменные (или объекты в некоторых случаях). Однако я тестировал его с помощью C++ и php, это дало мне другой результат.a = (a + b) - (b = a); C++ vs php

PHP:

$a = 10; 
$b = 20; 
$a = ($a + $b) - ($b = $a); 
echo $a, " ", $b; 

Печатается 20 10

C++

int a = 10; 
int b = 20; 
a = (a + b) - (b = a); 
std::cout << a << " " << b; 

Печатается 10 10

код выглядит так же, но выходы разные, я думал о том, две причины:

  1. C++ код компилируется и php интерпретирует.
  2. Эта формула бесполезна, поскольку она ведет к неопределенному поведению.

Может кто-нибудь объяснить, почему C++ и php-выход отличаются в этой ситуации?

+5

http://stackoverflow.com/questions/949433/could-anyone-explain-these-undefined-behaviors-i-i-i-i-i-etc - ваш код на C++ имеет неопределенное поведение. – Mat

+2

Вы уверены? Я копирую/вставляю код в свой компилятор (g ++), и я получаю «20 10», а не «10 10». – leonm

+2

@leonm Что неудивительно, если поведение не определено. – JJJ

ответ

14

Я не уверен, что такое правила на PHP, но в C++ порядок отдельных подвыражений строго не определен или, как технический термин, «неуказан» - другими словами, компилятору разрешено вычислять b = a до или после него a + b. До тех пор, пока он не вычитает a + b и b = a. Использование «неуказанного» поведения позволяет компилятору создавать более эффективный код в некоторых случаях или просто создавать компилятор для некоторых архитектур.

Это также означает, что если у вас есть выражение, которое «пересчитывает» значение внутри самого выражения, а также использует его в другом месте выражения, вы получаете неопределенное поведение (короткое короткое замыкание). UB означает именно это, поведение не определено - почти все может случиться, в том числе то, что вы видите, и многие другие альтернативы (например, компилятору также разрешено производить 42, даже если логика говорит, что ответ не будет 42 в этом случае [это неправильный вопрос для этого!]).

Я хотел бы также предположить, что если вы хотите поменять местами два значения, в PHP:

$t = $a; 
$a = $b; 
$b = $t; 

и в C++:

#include <algorithm> 

std::swap(a, b); 

или если вы настаиваете на написании самостоятельно:

int t = a; 
a = b; 
b = t; 

Попытка быть умной и выполнять ее «без временной переменной» почти наверняка сделает ее медленнее, чем e использование временного - конечно же, на языке компиляции, таком как C++, - в интерпретируемом языке, таком как PHP, создание новой переменной может добавить немного дополнительных накладных расходов, но вряд ли это будет настолько большим, по сравнению с дополнительными усилиями в требуемой логике ,

+0

В PHP нет никаких правил. Однако, похоже, что подвыражения оцениваются в порядке слева направо. Но это нигде не указано. – greyfade

2

Для PHP:

$a = 10; 
$b = 20; 
$a = ($a + $b) - ($b = $a); 
//executes like thus 
$a = (30) - ($b = $a); 
$a = (30) - ($b = $a = 10); //new $a still not computed, using older $a 
$a = (30) - (10); 
$a = 20; 
//then, $a=20 and $b = 10 

Это полностью связано с Operator Precedence, это может быть то же самое в C или не может, это зависит от старшинства, если неожиданное поведение не происходит.

+0

Как я думаю, php интерпретирует язык, поэтому может быть, что он преобразует части кода в числовое выражение, в результате он всегда дает тот же результат. По сравнению с компиляцией языков, что работает с регистрами, адресами памяти. – ST3

+2

@ user2623967 Скомпилированный или интерпретируемый не входит в него. PHP имеет то преимущество, что имеет только один широко используемый интерпретатор, поэтому даже неопределенное поведение часто предсказуемо (хотя оно может варьироваться в зависимости от версий и платформ). С другой стороны, существует множество различных компиляторов C++, и неопределенное поведение меняется между ними. – JJJ

3

Код C++ полностью сломан из-за неопределенного поведения. (чтение и запись b в одной последовательности).

+0

Как насчет кода PHP? Кажется, он делает то же самое. –

+0

@FractalizeR Поскольку PHP и C++ не являются одним и тем же языком. Так что неопределенное поведение на C++ может быть прекрасно определено в PHP, позволяя вам писать в одной строке, что обычно принимает два (или более) в C++. Или, что то же самое, тот же код, написанный на двух разных языках, не нужно делать «то же самое» :) – Thomas

+0

Непонятно, что в PHP все отлично определено. Не существует языкового стандарта, который я вижу, просто онлайн-набор веб-страниц, в котором говорится, что «существуют операторы, и они видят это», и множество примеров. –

Смежные вопросы