Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
new_Лекции_1-7.docx
Скачиваний:
117
Добавлен:
05.03.2016
Размер:
1.49 Mб
Скачать

Тема 4: Операции и выражения Лекция 4.1. Математические операторы и выражения План лекции

  1. Пустой оператор и пустые символы

  2. Понятие лексемы

  3. Использование блоков

  4. Операции С++

  5. Унарные и бинарные операции

  6. Математические и логические выражения

  7. Оператор присваивания

  8. Сочетание математических операций с присваиванием

  9. Инкремент и декремент

  10. Приведение типа

  11. Вычисление математических выражений

  12. Приоритет операций

  13. Вычитание беззнаковых целых и переполнение

  14. Ошибки времени выполнения (на примере деления на 0)

  1. Пустой оператор и пустые символы

Все операторы в С++ заканчиваются точкой с запятой. Точка с запятой – пустой оператор, не выполняющий никаких действий. Пустые символы (пробелы, табуляторы, символы новой строки) компилятором игнорируются. Везде, где допустим один пробел, вы может поставить сколько угодно пробелов.

// Пример 4.1.1

//Использование пустых символов - так писать можно, но не рекомендуется!!!

#include <iostream>

using namespace std;

int main() {

int a=0, b=0, y=35; double x=0, z=7.5; cout << "a:" <<

a << " b:" << b << endl; cout << "x:" << x

<< " y:" << y << " z:" << z << endl;

a

=

9

;

b

=

7; cout << " x:" << x

<< " y:" << y

<< endl;

cin.get();

return 0;

}

// Пример 4.1.2

//Использование пустых символов - лучше записать так!!!

#include <iostream>

using namespace std;

int main() {

int a=0, b=-9, y=35;

double x=0, z=7.5;

cout << "a:" << a << " b:" << b << endl;

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

a=9; b=7;

cout << " x:" << x << " y:" << y << endl;

// логическая ошибка

if (a <= b); // ; - ничего не делать!

cout << "a<b\n"; // не относится к if

// логическая ошибка

for (int i=0; i<5; i++); // ; - ничего не делай в цикле!

cout << "H e l l o!"; // не в цикле

cin.get();

return 0;

}

  1. Понятие лексемы

Компилятор в тексте программы выделяет лексемы – минималь­ные единицы языка, имеющие смысл, и на их основе выполняет проверку синтаксических ошибок. Лексемой может быть : ключевое слово, неименованная константа, имя переменной, константы, функции, обозначение операции и т.д. Пробелы внутри лексем недопустимы.

  1. Использование блоков

Везде, где можно поставить одиночный оператор, вы можете поставить составной оператор – блок. Блок - последовательность одиночных операторов, заключенных между фигурными скобками - { оператор1; оператор2; … оператор n; } . В С++ блок определяет область видимости и время жизни объекта . Переменные, объявленные внутри блока являются локальными.

// Пример 4.1.3

// Использование блоков

#include <iostream>

using namespace std;

int main() {

// локальные переменные функции main()

int a=1, b=2, c=a+b;

cout << "a=" << a << " b=" << b << " c=" << c << endl;

cin.get();

// это блок - в нем объявлены блочные локальные переменные

{

int a=2, b=3, c=a+b;

cout << "a=" << a << " b=" << b << " c=" << c << endl;

}

cin.get();

cout << "a=" << a << " b=" << b << " c=" << c << endl;

cin.get();

return 0;

}

  1. Операции С++

Операция – это символ, который заставляет компилятор выполнить действие. В С++ выделяют следующие основные категории операций:

  • операция присваивания (=);

  • математические операции ( +, -, *, /, % );

  • сочетание присваивания и операций ( +=, - =, *=, /=, %= );

  • инкремент и декремент (префиксный и постфиксный) ( ++, – – );

  • операция приведения типа ( (имя_типа) );

  • операции отношения ( >, <, >=, <=, != (не равно) , = = (равно) );

  • логические операции (&& (и) , || (или), ! (не));

  • получить адрес (& );

  • получить значение по адресу (разадресация) ( * );

  • оператор индексации ( [ ] );

  • оператор видимости ( : : );

  • оператор прямого доступа к объекту ( . );

  • оператор косвенного доступа к объекту ( –> );

  • оператор вызова функции ( () );

  • операторы вставки и извлечения в поток ( << , >> );

  • побитовые операции ( &, !, ^, ~,>>,<< ) и т.д.

  1. Унарные и бинарные операции

Операция называется унарной, если в ней принимает участие один операнд (минус перед числом или именем переменной, ++, – – , & (адрес), * (разадресация)). Бинарная операция – операция с двумя операндами ( +, -, *, /, % ).

// Пример 4.1.4

// Унарные и бинарные операции

#include <iostream>

using namespace std;

int main() {

setlocale( LC_ALL, "Russian"); // для вывода на экран русского текста

int a=1, b=2, c=0;

// ++, --, -, &(адрес) - это примеры унарных операций

c++;

c=-c;

cout << "адрес a=" << &a << "\tзначение а=" << a << endl;

cout << "адрес b=" << &b << "\tзначение b=" << b << endl;

cout << "адрес c=" << c << "\tзначение c=" << c << endl;

cin.get();

// +, - - это примеры бинарных операций

a=a+2; // + - бинарная операция сложение

c=a-b; // - бинарная операция вычитания

cin.get();

return 0;

}

  1. Математические и логические выражения

Все, что может быть вычислено в С++ называется выражением. Выражения бывают математические и логические. Выражение всегда возвращает значение. Математическое выражение возвращает числовое значение, а логическое - «истину» (1) или «ложь» (0).

// Пример 4.1.5

// Математические и логические выражения

#include <iostream>

using namespace std;

int main() {

int a=2, b=3, c=0;

//математическое выражение возвращает числовое значение

c=a+b;

cout << "c=" << c << endl;

//логическое выражение возвращает 0/1 (false/true, ложь/истину)

c=a!=b;

cout << "c=" << c << endl;

cin.get();

return 0;

}

  1. Оператор присваивания

Операция присваивания (=) изменяет значение операнда находящегося с левой стороны от знака = (lvalue) на значение операнда, находящегося справа от = (rvalue). Lvalue-это обязательно имя переменной. Rvalue может быть константой, именем или выражением. Множественное присваивание выполняется справа налево.

// Пример 4.1.6

// Присваивание

#include <iostream>

using namespace std;

int main() {

const double Qe=-1.6e-19; // инициализация константы обязательна

double result=0, r1=0,r2=0,r3=0; // инициализация

r1=0; r2=0; r3=0; // обычное присваивание

r1=r2=r3=0; // множественное присваивание выполняется справа налево!!!

//Qe=0; // Ошибка! Константу изменить нельзя!!!

//10.5=result; // Ошибка! Lvalue - обязательно имя

result=10.5; // Rvalue - числовая вещественная константа

cout << "Result=" << result << endl;

result=Qe; // Rvalue - имя другой величины

cout << "Result=" << result << endl;

result=Qe*Qe*Qe; // Rvalue - выражение

cout << "Result=" << result << endl;

r1=r2=r3=result/3.; // множественное присваивание

cout << "r1=" << r1 << "\tr2=" << r2 <<"\tr3=" << r3 << endl;

cin.get();

return 0;

}

  1. Сочетание математических операций с присваиванием

Любую математическую операцию можно сочетать с присваиванием. Операторы myAge=myAge +2; и myAge+=2; эквивалентны.

// Пример 4.1.7

// Сочетание присваиваний и математических операций

#include <iostream>

using namespace std;

int main() {

int TestValue=10;

int a=2;

TestValue+=5; // TestValue=TestValue+5

cout << "TestValue=" << TestValue << endl;

TestValue*=a; // TestValue=TestValue*a;

cout << "TestValue=" << TestValue << endl;

TestValue-=3; // TestValue=TestValue-3;

cout << "TestValue=" << TestValue << endl;

TestValue/=2; // TestValue=TestValue/2;

cout << "TestValue=" << TestValue << endl;

TestValue%=3;

cout << "TestValue=" << TestValue << endl;

cin.get();

return 0;

}

  1. Инкремент и декремент

Операции инкремент и декремент увеличивают/уменьшают значение переменной на единицу. Операторы myAge++; myAge=myAge+1; и myAge+=1; эквивалентны. Префиксность/постфикность важны в выражениях и определяют что выполнить сначала : инкремент/декремент, а затем участвовать в вычислениях или наоборот.

// Пример 4.1.8

// Использование инкремента и декремента

#include <iostream>

using namespace std;

int main() {

int myAge=33, yourAge=33, sumAge=0;

cout << "myAge:\t" << myAge << "\nyourAge:\t" << yourAge << endl;

cin.get();

myAge++; // постфиксный ++

++yourAge; // префиксный ++

cout << "myAge:\t" << myAge << "\nyourAge:\t" << yourAge << endl;

cin.get();

cout << "myAge:\t" << myAge++ << "\nyourAge:\t" << ++yourAge << endl;

cin.get();

cout << "myAge:\t" << myAge << "\nyourAge:\t" << yourAge << endl;

cin.get();

//sumAge=++myAge + yourAge++;

//sumAge=++myAge + ++yourAge;

sumAge=myAge++ + yourAge++;

cout << "sumAge:\t" << sumAge << endl;

cout << "myAge:\t" << myAge << "\nyourAge:\t" << yourAge << endl;

cin.get();

return 0;

}

  1. Приведение типа

Операция приведения типа (type casting) заставляет компилятор изменить тип переменной. Для приведения типа существует два способа : старый С-стиль и новый оператор static_cast :

int a=2; double b, c;

b=(double) a; // старый стиль C

c=static_cast<double>(a); // современный стиль C++

Компилятор часто может выполнять и неявные преобразования типов.

// Пример 4.1.9

//Явные и неявные преобразование типов

#include <iostream>

using namespace std;

int main()

{

unsigned char ch='A';

cout << ch << endl;

//неявное преобразование типов выполняет компилятор

ch=ch+1;

cout << ch << endl;

//явное преобразование типов выполняет программист (стиль С)

ch=(char)((int)ch+1);

cout << ch << endl;

//явное преобразование типов выполняет программист (стиль С++)

ch=static_cast<char>(static_cast<int>(ch)+1);

cout << ch << endl;

cin.get();

return 0;

}

  1. Вычисление математических выражений

Для вычисления промежуточных выражений в сложных формулах компилятор выделяет временные ячейки памяти. Их тип определяется типом операндов. Например, если два операнда целые, то и тип временной ячейки – целый. Если тип числовых операндов различен, то тип временной ячейки такой, как у более сложного операнда. Поэтому возможны ошибочные вычисления на стадии промежуточных расчетов. Это проблема программиста.

// Пример 4.1.10

// Вычисление сложных выражений

#include <iostream>

using namespace std;

int main()

{

int a=0, b=0, y=35;

double x=0, z=7.5;

cout << "a:" << a << " b:" << b;

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

a=9; b=7;

y=x=a+b; // a+b - математическое выражение. Для его вычисления

// компилятор использует временную ячейку памяти целого типа // (int temp=a+b;),т.к. оба операнда целые и возвращает ее значение в качестве // результата. Этот результат присваивается справа налево переменным x и y.

cout << "a:" << a << " b:" << b;

cout << " x:" << x << " y:" << y << endl;

y=x=a+z; // a+z - математическое выражение. Для его вычисления

// компилятор использует временную ячейку памяти вещественного типа

// (double temp=a+b;), т.к. второй операнд вещественный и возвращает ее

// значение в качестве результата. Этот результат присваивается справа налево // переменным x и y. При этом происходит усечение дробной части на стадии

/ / присвоения.

cout << "Temporary value a+z=" << (a+z) << endl;

cout << "x:" << x << " y:" << y << endl;

cin.get();

return 0;

}

// Пример 4.1.11

// Потеря дробной части на стадии промежуточных вычислений

#include <iostream>

using namespace std;

int main() {

// Вычисление параметров шара

const double PI=3.14; // константа PI

const double k=0.01; // коэффициент для перевода мм. в см.

double R=1.5; // радиус, мм

double Ro=7.8; // плотность, г/см^3

double C=0; // длина окружности, см

double S=0; // площадь окружности, см^2

double V=0; // объем шара, см^3

double VErr=0; // неправильно вычисленный объем шара, см^3

double M=0; // масса шара, г

double MErr=0; // неправильно вычисленная масса шара, г

C=2*PI*R*k;

S=PI*R*R;

//PI=3.1; // значения констант изменять нельзя!!!

VErr=4/3*PI*R*R*R; // 4/3-неправильно! ->целый тип->потеря дробной части

//V=4./3*PI*R*R*R; // 4./3.-правильно!->вещ.тип->потери дробной части нет

//V=(double)4/3*PI*R*R*R;// правильно!->вещ.тип->потери дробной части нет

V=4*PI*R*R*R/3; // правильно!->вещ.тип->потери дробной части нет

MErr=Ro*VErr;

M=Ro*V;

cout << "R=" << R << '\t' << "Ro=" << Ro << endl;

cout << "C=" << C << '\t' << "S=" << S << endl;

cout << "VErr=" << VErr << '\t'<< "MErr=" << MErr << endl;

cout << "V=" << V << '\t'<< "M=" << M << endl;

cin.get();

return 0;

}

  1. Приоритет операций

Все выражения вычисляются слева направо с учетом приоритета математических операций. Для изменения приоритета используются круглые скобки. Круглые скобки могут быть вложенными.

// Пример 4.1.12

// Приоритеты и скобки

#include <iostream>

using namespace std;

int main() {

setlocale( LC_ALL, "Russian"); // для вывода на экран русского текста

// Вычисление средней зарплаты трех человек

int z1=100, z2=150, z3=120; // зарплата трех человек

int isz; //средняя зарплата(int-неправильно->возможна потеря дробной части)

double dsz; // средняя зарплата (double - правильно)

isz=z1+z2+z3/3; // неправильно : делится на 3 только z3!!!

cout << "Ошибка! isz=" << isz << endl;

isz=(z1+z2+z3)/3.; // неправильно : потеря дробной части при присваивании!!!

cout << "Ошибка! isz=" << isz << endl;

dsz=(z1+z2+z3)/3; //неправильно : потеря дробной части до присваивании!!!

cout << "Ошибка! dsz=" << dsz << endl;

dsz=(z1+z2+z3)/3.; //правильно 3. - double константа

cout << "ПРАВИЛЬНО! dsz=" << dsz << endl;

dsz=(double)(z1+z2+z3)/3; //правильно -- преобразование C-стиля

cout << "ПРАВИЛЬНО! dsz=" << dsz << endl;

dsz=static_cast<double>(z1+z2+z3)/3; //правильно -- преобразования С++-стиля

cout << "ПРАВИЛЬНО! dsz=" << dsz << endl;

cin.get();

return 0;

}

  1. Вычитание беззнаковых целых и переполнение

При выполнении вычитания беззнаковых целых возможно целочисленное переполнение, если от меньшего вычесть большее число.

// Пример 4.1.13

// Вычитание и целочисленное переполнение беззнаковых целых

#include <iostream>

using namespace std;

int main() {

setlocale( LC_ALL, "Russian"); // для вывода на экран русского текста

// переполнение беззнакового целого при вычитании

unsigned int difference=0, bigNumber=100, smallNumber=50;

difference=smallNumber - bigNumber;

cout << "\nРазность = " << difference;

difference+=500;

cout << "\nРезультат = " << difference;

cin.get();

return 0;

}

  1. Ошибки времени выполнения (на примере деления на 0)

При делении на 0 возникает ошибка времени выполнения (run time error). // Пример 4.1.14

// Деление на 0

#include <iostream>

using namespace std;

void main() {

setlocale( LC_ALL, "Russian"); // для вывода на экран русского текста

int a=1, b=0, c=0;

cout << "a=" << a << " b=" << b << " c=" << c << endl;

cin.get();

// run time error

c=a/b; // деление на 0

cout << "a=" << a << " b=" << b << " c=" << c << endl;

cin.get();

if (b == 0) {

cout << "Деление на 0!!!" << endl;

cin.get();

return;

}

else c=a/b;

cout << "a=" << a << " b=" << b << " c=" << c << endl;

cin.get();

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]