#определите площадь(в) В*В; Р=квадрат(++Р); соиь<&ЛТ;Р;
Выход этого кода дает 25, когда p равно 3. Потому что выход должен быть 3*3=9.
Что я уже пробовал:
Мой выход тоже идет 25 но как
Когда p
если 3, то результат никогда не будет равен 9 из-за операции предварительного приращения.
Таким образом, вы можете ожидать, что результат будет 16 вместо этого (++p = 4).
Но вы получили 25 из-за одного из опасных побочных эффектов макросов C/C++. Если макропараметры используются несколько раз при расширении и параметры являются операторами, то эти операторы также будут выполняться несколько раз.
Просто разверните макрос вручную, чтобы воспроизвести то, что происходит:
#define square(v) v*v r = square(++p);расширяется до (пробелы вставляются для удобства чтения)
r = ++p * ++p;Результат этой операции не определен (см. Порядок оценки - cppreference.com[^]).
int square(int v) { return v * v; }
#defines-это средство замены текста, они не действуют как подпрограммы, но "расширяются", чтобы предоставить код.
Итак, когда вы пишете это:
#define square(v) v*v; r=square(++p); cout<<r;Компилятор видит следующее:
r=++p * ++p; cout<<r;А это значит, что результат не будет таким предсказуемым, он будет варьироваться в зависимости от того, какой компилятор вы используете. В данном случае это приводит к тому, что
5 * 5
, но он также может генерировать 16, 12 или 9, Если вы найдете правильный компилятор!
Настоящий кодекс :
#define square(v) v*v; r= square(++p); cout<<r;
#define square(v) v*v; r= ++p * ++p; cout<<r;
#define square(v) v*v; ++p; ++p; r= p * p; // R= 5*5= 25 cout<<r;
#define square(v) v*v; ++p; r= p; r= r * ++p; // r= 4*5= 20 cout<<r;
#define square(v) v*v;
#define square(v) v*v; p=3; r= square(p+1); cout<<r;
#define square(v) v*v; p=3; r= p+1*p+1; cout<<r;
#define square(v) v*v; p=3; r= p +(1 * p) +1; // r= 3+3+1= 7 cout<<r;
#define square(v) (v)*(v);
Поскольку это C++, я думаю, что лучший способ реализовать square-это использовать шаблонную функцию :
template< typename T > inline T square( T a ) { return a * a; }Эта функция будет работать практически с любым типом данных, и у вас не будет никаких проблем с неопределенностью приоритета, как это было бы с определением макроса.
template< typename T > inline T SqPreIncOut( T p ) { T r = square( ++p ); cout << r; return r; } // you would use it like this : double radius = SqPreIncOut( parameter );Простите за название этой функции, но она наполовину описывает то, что происходит.