Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
л_4_Операции_и_выражения.doc
Скачиваний:
10
Добавлен:
05.11.2018
Размер:
660.99 Кб
Скачать

Особенности выполнения операций инкремента и декремента

Обе формы (префиксная и постфиксная) операторов возвращают значение того же типа, что и операнд. Но важное различие заключается в том, что значение, возвращаемое префиксной формой, является l-value (т.е. можно считать, что префиксная форма возвращает ссылку на операнд, имеющий уже измененное значение), в то время как значение, возвращаемое постфиксной формой оператора, не является l-value. Постфиксная форма возвращает просто значение операнда (причем не измененное, так как изменение будет произведено позже).

В этом контексте, будет возможно, но некорректно, выражение ++х = fun(x); !!! (префиксный ++ слева возвращает lvalue; x изменит свое значение, которое и будет передано в функцию, хотя лучше так не делать). При компиляции выражения x++ = fun(x); получим сообщение: error C2106: '=' : left operand must be l-value, а при компиляции выражения cout << ++x++<< endl; – сообщение: error C2105: '++' needs l-value.

//вариант 1

int fun(int);

#include <iostream>

#include <conio.h>

using namespace std;

int main() {

int x=2;

++x = fun(x); //вызывает функцию с значением 3

cout << x << endl; //3

_getch();

return 0;

}

int fun(int x)

{cout << x << endl;

return x++; //возвращает значение 3!!!

}

//вариант 2

int fun(int);

#include <iostream>

#include <conio.h>

using namespace std;

int main() {

int x=2;

++x = fun(x); //вызывает функцию с значением 3

cout << x << endl; //4

_getch();

return 0;

}

int fun(int x)

{cout << x << endl;

return ++x; //возвращает значение 4!!!

}

//вариант 3

int fun(int);

#include <iostream>

#include <conio.h>

using namespace std;

int main() {

int x=2;

x++ = fun(x); //error C2106: '=' : left operand must be l-value

cout << x << endl;

_getch();

return 0;

}

int fun(int x)

{cout << x << endl;

return ++x;

}

Что напечатает программа:

#define PRINT(int) printf (“%d\n”, int) x=y=1;

z = x++ - 1; PRINT(x ); PRINT(z);

z=0; x=2

z += -x++ + ++y; PRINT(x ); PRINT(z);

z= 0+(-2)+ 2=0; x=3; y=2;

z = x/ ++x; PRINT(z);

результат неопределенный из-за неопределенного порядка операций

Операции присваивания

Оператор присваивания имеет вид:

Имя_переменной = выражение;

– значение выражения из правой части (rvalue) записывается в память по адресу, на который ссылается переменная в левой части (lvalue). При этом операция вырабатывает значение, равное значению, присвоенному переменной, находящейся в левой части операции. Это делает возможным использование операции присваивания в правой части выражений.

Слева от знака операции присваивания может быть только модифицируемое леводопустимое значение (в случае именованной типизированной константы, например, леводопустимое значение не является модифицируемым и ссылается на неизменный участок памяти).

int main()

{

int i=0; double x=0.;

x =(i = 5.25) + 6.5;

cout << i << " " << x << endl; // 5 11.5 (5+6.5)

int j=0; int ix=0;

ix=(j=5.25)+6.5;

cout << j << " " << ix << endl; // 5 11 (5+6.5)

_getch();

return 0;

}

Для более компактной записи присваивания разрешается использовать сокращенные операции присваивания ((составные присваивания: += -= *= /= %= >>= <<= &= ^= |= ). В общем виде оператор присваивания:

переменная = переменная операция выражение;

можно записать компактнее: переменная операция= выражение; (между операцией и символом = не должно быть пробела. Такая запись позволяет не повторять дважды имя одной и той же переменной. Для сокращенных операций присваивания некоторые компиляторы генерируют код, выполняемый быстрее.

Можно использовать и множественное присваивание:

переменная1 = переменная2 = … = переменнаяN = выражение;

a=b=c=d=0; //можно использовать!!!!

Это равносильно записи:

a=(в=(с=(d=0)))

int main()

{

int i=0; float x=0, y=0; bool b=false;

x = b = i = y = 4.567;

cout << y << " " << i << " " << b << " " << x << endl;

// 4.567 4 1 1

_getch();

return 0;

}

Но!!!

int main()

{

float x=0, y=4.5, z=3.2;

x = (y = z) = 6.5; // z=3.2 y=6.5 !!!!! x=6.5

cout << z << " " << y << " " << x << endl;

// 3.2 6.5!!!!! 6.5

_getch();

return 0;

}

операция

содержание

операция

содержание

x=y;

 

k %=m;

k=k % m;

x +=y;

x=x + y;

k >>=m;

k=k >> m сдвиг вправо на m битов

x -=y;

x=x - y;

k <<=m;

k=k << m сдвиг влево на m битов

x *=y;

x=x * y;

k |=m;

k=k | m побитовая операция логического сложения

x /=y;

x=x / y;

k ^=m;

k=k ^ m побитовая операция «исключающее или»