Harekrishna paul Ответов: 4

#определите площадь(в) В*В; Р=квадрат(++Р); соиь<&ЛТ;Р;


Выход этого кода дает 25, когда p равно 3. Потому что выход должен быть 3*3=9.

Что я уже пробовал:

Мой выход тоже идет 25 но как

4 Ответов

Рейтинг:
0

Jochen Arndt

Когда 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; }


Рейтинг:
0

OriginalGriff

#defines-это средство замены текста, они не действуют как подпрограммы, но "расширяются", чтобы предоставить код.
Итак, когда вы пишете это:

#define square(v) v*v;

r=square(++p); 
cout<<r;
Компилятор видит следующее:
r=++p * ++p; 
cout<<r;
А это значит, что результат не будет таким предсказуемым, он будет варьироваться в зависимости от того, какой компилятор вы используете. В данном случае это приводит к тому, что 5 * 5, но он также может генерировать 16, 12 или 9, Если вы найдете правильный компилятор!
Видеть здесь: Почему x = ++x + x++ дает мне неправильный ответ?[^]


Рейтинг:
0

Patrice T

Настоящий кодекс :

#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);


Рейтинг:
0

Rick York

Поскольку это 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 );
Простите за название этой функции, но она наполовину описывает то, что происходит.