Вывод восьмеричных и шестнадцатеричных значений

Решение линейных задач.

Арифметические операции

Арифметические операции производятся над числами. Значения, которые участвуют в операции, называются операндами. В языке программирования C++ арифметические операции бинарными (производятся над двумя операндами) и унарными (выполняются над одним операндом). К бинарным операциям относят следующие:

· +

Операция сложения возвращает сумму двух чисел:

 

int a = 10;

int b = 7;

int c = a + b; // 17

int d = 4 + b; // 11

 

· -

Операция вычитания возвращает разность двух чисел:

 

int a = 10;

int b = 7;

int c = a - b; // 3

int d = 41 - b; // 34

 

· *

Операция умножения возвращает произведение двух чисел:

 

int a = 10;

int b = 7;

int c = a * b; // 70

int d = b * 5; // 35

 

· /

Операция деления возвращает частное двух чисел:

 

int a = 20;

int b = 5;

int c = a / b;     // 4

double d = 22.5 / 4.5 // 5

 

При делении стоит быть внимательным, так как если в операции участвуют два целых числа, то результат деления будет округляться до целого числа, даже если результат присваивается переменной float или double:

 

double k = 10 / 4; // 2

std::cout << k;

Чтобы результат представлял число с плавающей точкой, один из операндов также должен представлять число с плавающей точкой:

 

double k = 10.0 / 4.0; // 2.5

std::cout << k;

 

· %

Операция получения остатка от целочисленного деления:

 

int a = 33;

int b = 5;

int c = a % b; // 3

int d = 22 % 4; // 2 (22 - 4*5 = 2)

 

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

· Префиксный инкремент.

Увеличивает значение переменной на единицу и полученный результат используется как значение выражения ++x

 

int a = 8;

int b = ++a;

std::cout << a << "\n"; // 9

std::cout << b << "\n"; // 9

 

· Постфиксный инкремент.

Увеличивает значение переменной на единицу, но значением выражения x++ будет то, которое было до увеличения на единицу

 

int a = 8;

int b = a++;

std::cout << a << "\n"; // 9

std::cout << b << "\n"; // 8

 

· Префиксный декремент.

Уменьшает значение переменной на единицу, и полученное значение используется как значение выражения –x

 

int a = 8;

int b = --a;

std::cout << a << "\n"; // 7

std::cout << b << "\n"; // 7

 

· Постфиксный декремент.

Уменьшает значение переменной на единицу, но значением выражения x-- будет то, которое было до уменьшения на единицу

 

int a = 8;

int b = a--;

std::cout << a << "\n"; // 7

std::cout << b << "\n"; // 8

 

Арифметические операции вычисляются слева направо. Одни операции имеют больший приоритет чем другие и поэтому выполняются вначале. Операции в порядке уменьшения приоритета:

+ (инкремент), - (декремент)
* (умножение), / (деление), % (остаток от деления)
+ (сложение), - (вычитание)

Приоритет операций следует учитывать при выполнении набора арифметических выражений:

 

int a = 8;

int b = 7;

int c = a + 5 * ++b; // 48

std::cout << c;

 

Хотя операции выполняются слева направо, но вначале будет выполняться операция инкремента ++b, которая увеличит значение переменной b и возвратит его в качестве результата, так как эта операция имеет больший приоритет. Затем выполняется умножение 5 * ++b, и только в последнюю очередь выполняется сложение a + 5 * ++b

Скобки позволяют переопределить порядок вычислений. Например:

 

int a = 8;

int b = 7;

int c = (a + 5) * ++b; // 104

std::cout << c;

 

Несмотря на то, что операция сложения имеет меньший приоритет, но вначале будет выполняться именно сложение, а не умножение, так как операция сложения заключена в скобки.

 

Побитовые операции

 

Побитовые операции выполняются над отдельными разрядами или битами чисел. Данные операции производятся только над целыми числами.

 

Операции сдвига

Каждое целое число в памяти представлено в виде определенного количества разрядов. И операции сдвига позволяют сдвинуть битовое представление числа на несколько разрядов вправо или влево. Операции сдвига применяются только к целочисленным операндам. Есть две операции:

 

<<

 

Сдвигает битовое представление числа, представленного первым операндом, влево на определенное количество разрядов, которое задается вторым операндом.

 

>>

 

Сдвигает битовое представление числа вправо на определенное количество разрядов.

Применение операций:

 

int a = 2 << 2; // 10 на два разрядов влево = 1000 - 8

int b = 16 >> 3; // 10000 на три разряда вправо = 10 - 2

 

Число 2 в двоичном представлении 10. Если сдвинуть число 10 на два разряда влево, то получится 1000, что в десятичной системе равно число 8.

Число 16 в двоичном представлении 10000. Если сдвинуть число 10 на три разряда вправо (три последних разряда отбрасываются), то получится 10, что в десятичной системе представляет число 2.

Поразрядные операции

Поразрядные операции также проводятся только над соответствующими разрядами целочисленных операндов:

&: поразрядная конъюнкция (операция И или поразрядное умножение). Возвращает 1, если оба из соответствующих разрядов обоих чисел равны 1

|: поразрядная дизъюнкция (операция ИЛИ или поразрядное сложение). Возвращает 1, если хотя бы один из соответствующих разрядов обоих чисел равен 1

^: поразрядное исключающее ИЛИ. Возвращает 1, если только один из соответствующих разрядов обоих чисел равен 1

~: поразрядное отрицание или инверсия. Инвертирует все разряды операнда. Если разряд равен 1, то он становится равен 0, а если он равен 0, то он получает значение 1.

Применение операций:

 

int a = 5 | 2; // 101 | 010 = 111 - 7

int b = 6 & 2; // 110 & 010 = 10 - 2

int c = 5 ^ 2; // 101 ^ 010 = 111 - 7

int d = ~9; // -10

 

Например, выражение 5 | 2 равно 7. Число 5 в двоичной записи равно 101, а число 2 - 10 или 010. Сложим соответствующие разряды обоих чисел. При сложении если хотя бы один разряд равен 1, то сумма обоих разрядов равна 1. Поэтому получаем:

1 0 1
0 1 0
1 1 1

В итоге получаем число 111, что в десятичной записи представляет число 7.

Возьмем другое выражение 6 & 2. Число 6 в двоичной записи равно 110, а число 2 - 10 или 010. Умножим соответствующие разряды обоих чисел. Произведение обоих разрядов равно 1, если оба этих разряда равны 1. Иначе произведение равно 0. Поэтому получаем:

1 1 0
0 1 0
0 1 0

Получаем число 010, что в десятичной системе равно 2.

 

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

Операции присваивания позволяют присвоить некоторое значения. Эти операции выполняются над двумя операндами, причем левый операнд может представлять только модифицируемое именованное выражение, например, переменную.

Базовая операция присваивания = позволяет присвоить значение правого операнда левому операнду:

 

int x;

x = 2

 

То есть в данном случае переменная x (левый операнд) будет иметь значение 2 (правый операнд).

Стоит отметить, что тип значения правого операнда не всегда может совпадать с типом левого операнда. В этом случае компилятор пытается преобразовать значение правого операнда к типу левого операнда.

При этом операции присваивания имеют правосторонний порядок, то есть выполняются справа налево. И, таким образом, можно выполнять множественное присваивание:

 

int a, b, c;

a = b = c = 34;

 

Здесь сначала вычисляется значение выражения c = 34. Значение правого операнда – 34 присваивается левому операнду с. Далее вычисляется выражение b = c: значение правого операнда c (34) присваивается левому операнду b. И в конце вычисляется выражение a = b: значение правого операнда b (34) присваивается левому операнду a.

Кроме того, следует отметить, что операции присваивания имеют наименьший приоритет по сравнению с другими типами операций, поэтому выполняются в последнюю очередь:

 

int x;

x = 3 + 5;

 

В соответствии с приоритетом операций вначале выполняется выражение 3 + 5, и только потом его значение присваивается переменной x.

Все остальные операции присваивания являются сочетанием простой операции присваивания с другими операциями:

· +=: присваивание после сложения. Присваивает левому операнду сумму левого и правого операндов: A += B эквивалентно A = A + B

· -=: присваивание после вычитания. Присваивает левому операнду разность левого и правого операндов: A -= B эквивалентно A = A - B

· *=: присваивание после умножения. Присваивает левому операнду произведение левого и правого операндов: A *= B эквивалентно A = A * B

· /=: присваивание после деления. Присваивает левому операнду частное левого и правого операндов: A /= B эквивалентно A = A / B

· %=: присваивание после деления по модулю. Присваивает левому операнду остаток от целочисленного деления левого операнда на правый: A %= B эквивалентно A = A % B

· <<=: присваивание после сдвига разрядов влево. Присваивает левому операнду результат сдвига его битового представления влево на определенное количество разрядов, равное значению правого операнда: A <<= B эквивалентно A = A << B

· >>=: присваивание после сдвига разрядов вправо. Присваивает левому операнду результат сдвига его битового представления вправо на определенное количество разрядов, равное значению правого операнда: A >>= B эквивалентно A = A >> B

· &=: присваивание после поразрядной конъюнкции. Присваивает левому операнду результат поразрядной конъюнкции его битового представления с битовым представлением правого операнда: A &= B эквивалентно A = A & B

· |=: присваивание после поразрядной дизъюнкции. Присваивает левому операнду результат поразрядной дизъюнкции его битового представления с битовым представлением правого операнда: A |= B эквивалентно A = A | B

· ^=: присваивание после операции исключающего ИЛИ. Присваивает левому операнду результат операции исключающего ИЛИ его битового представления с битовым представлением правого операнда: A ^= B эквивалентно A = A ^ B

Примеры операций:

 

int a = 5;

a += 10; // 15

a -= 3;       // 12

a *= 2;       // 24

a /= 6;       // 4

a <<= 4;      // 64

a >>= 2;      // 16

 

Ввод и вывод в консоли

 

По умолчанию язык C++ не содержит встроенных средств для ввода с консоли и вывода на консоль, эти средства предоставляются библиотекой iostream. В ней определены два типа: istream и ostream. istream представляет поток ввода, а ostream - поток вывода.

Вобще сам темин "поток" в данном случае представляет последовательность символов, которая записывается на устройство ввода-вывода или считывается с него. И в данном случае под устройством ввода-вывода рассматривается консоль.

Для записи или вывода символов на консоль применяется объект cout, который представляет тип ostream. А для чтения с консоли используется объект cin

Для использования этих объектов в начало исходного файла необходимо подключить библиотеку iostream:

#include <iostream>

Вывод на консоль

 

Для вывода на консоль применяется оператор <<. Этот оператор получает два операнда. Левый операнд представляет объект типа ostream, в данном случае объект cout. А правый операнд - значение, которое надо вывести на консоль.

Так как оператор << возвращает левый операнд - cout, то с помощью цепочки операторов мы можем передать на консоль несколько значений. Например, определим простейшую программу вывода на консоль:

 

#include <iostream>

 

int main()

{

int age = 33;

double weight = 81.23;

std::cout << "Name: " << "Tom" << "\n";

std::cout << "Age: " << age << std::endl;

std::cout << "Weight: " << weight << std::endl;

return 0;

}

 

Консольный вывод программы:

 

 

Оператору << передаются различные значения - строки, значения переменных, которые выводятся на консоль.

Строки могут содержать управляющие последовательности, которые интерпретируются определенным образом. Например, последовательность "\n" интерпретируется как перевод на новую строку. Из других управляющих последовательностей также нередко употребляется "\t", которая интерпретируется как табуляция.

Также цепочку операторов << можно завершать значением std::endl, которое вызывает перевод на новую строку и сброс буфера. При выводе в поток данные вначале помещаются в буфер. И сброс буфера гарантирует, что все переданные для вывода на консоль данные немедлено будут выведены на консоль.

Ввод с консоли

 

Для считывания с консоли данных применяется оператор ввода >>, который принимает два операнда. Левый операнд представляет объект типа istream (в данном случае объект cin), с которого производится считывание, а правый операнд - объект, в который считываются данные.

Например, считаем данные с консоли:

 

#include <iostream>

 

int main()

{

int age;

double weight;

std::cout << "Input age: ";

std::cin >> age;

std::cout << "Input weight: ";

std::cin >> weight;

std::cout << "Your age: " << age << "\t your weight: " << weight << std::endl;

return 0;

}

 

Здесь после приглашений к вводу программа ожидает ввода значений для переменных age и weight.

Пример работы программы:

 

 

Стоит отметить, что так оператор ввода в первом случае будет добавлять данные в целочисленную переменную age, то он ожидает ввода числа. В случае с переменной weight оператор ввода ожидает дробное число, причем разделителем целой и дробной части должна быть точка. Поэтому мы не можем ввести любые значения, например, строки. В этом случае программа может выдать некорректный результат.

Оператор ввода >> возвращает левый операнд - объект cin, поэтому можно по цепочке считывать данные в различные переменные:

 

#include <iostream>

 

int main()

{

int age;

double weight;

std::cout << "Input age: ";

std::cin >> age >> weight;

std::cout << "Your age: " << age << "\t your weight: " << weight << std::endl;

return 0;

}

 

Пример работы программы:

 

 

После ввода одного из значений надо будет ввести пробел и затем вводить следующее значение.

 

Вывод восьмеричных и шестнадцатеричных значений

Программы, представленные в этом уроке до сих пор, выводили числа в десятичном виде. В зависимости от назначения ваших программ вам, возможно, потребуется выводить числа в восьмеричном или шестнадцатеричном виде. Для этого можно разместить модификаторы dec, oct и hex внутри выходного потока. Следующая программа ОСТНЕХ.СРР использует эти модификаторы для вывода значений в десятичном, восьмеричном и шестнадцатеричном виде:

 

#include <iostream>

int main( )

{

cout << "Восьмеричный: " << oct << 10 << ' ' << 20 << endl;

cout << "Шестнадцатеричный: " << hex << 10 << ' ' << 20 << endl;

cout << "Десятичный: " << dec << 10 << ' ' << 20 << endl;

}

 

Когда программа будет откомпилирована и запущена, на экране появится следующий результат:

 

С:\> OCTEX <ENTER>

Восьмеричный: 12 24

Шестнадцатеричный: а 14

Десятичный: 10 20

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

 

Задание ширины поля вывода

 

Есть два способа управления выводом - через вызовы метода объекта cout (например, cout.width(20)) или при помощи "манипуляторов" (cout << setw(10)).

Второй способ удобней, поэтому рассмотрим его. Для использования манипуляторов необходимо подключить заголовочный файл iomanip:

 

#include<iomanip>

 

Для задания ширины поля вывода одного значения используется манипулятор setw с одним параметром - шириной поля вывода. Например:

 

cout << setw(10) << a;

 

выведет значение переменной a в поле шириной 10 символов. Аналогично правилам вывода в языке C, по умолчанию осуществляется выравнивание выводимого значения по правому краю (перед выводимым значением добавляются пробелы), если же число содержит больше символов, чем ширина поля, то будут выведены все символы.

Манипулятор setw влияет только на значение ширины поля вывода для следующего выводимого значения, если нужно задать значение ширины поля вывода для двух чисел, то это нужно делать перед выводом каждого значения.

Манипулятор setfill с одним параметром типа char позволяет задать символ-"заполнитель", который будет использоваться вместо пробела для заполнения поля. Например, вывести время в формате HH:MM (ровно по две цифры для вывода часов и минут) можно следующим образом:

 

cout << setfill('0') << setw(2) << h << ":" << setw(2) << m << endl;

 

Заметим, что манипулятор setfill действует постоянно (до следующего вызова setfill), не нужно устанавливать его перед выводом каждого значения.

Также как и в языке C можно задавать тип выравнивания внутри поля. Выравнивание бывает левым, правым и внутренним. Внутреннее выравнивание означает, что сначала выводится знак числа (если число отрицательное), затем - пробелы, затем - цифры числа. Для задания выравнивания используются манипуляторы left, right, internal.

 

 

Примеры использования различных типов выравнивания:

Пример кода Вывод программы
cout << left << setw(7) << -123 << "*" << endl; -123 *
cout << right << setw(7) << -123 << "*" << endl; -123*
cout << internal << setw(7) << -123 << "*" << endl; - 123*

Вывод действительных чисел

 

Есть два способа вывода действительных чисел - с фиксированной точкой (соответствует форматной строке "%f" функции printf) и с плавающий точкой (соответствует "%e"). Для переключения режима вывода действительных чисел в формат с фиксированной точкой используется манипулятор fixed, для вывода с плавающей точкой - манипулятор scientific.

По умолчанию числа выводятся с точностью в 6 знаков после точки, это значение можно изменить при помощи манипулятора setprecision с параметром - шириной поля вывода.

Например:

 

cout << fixed << setprecision(15) << x << endl;

 

Данные манипуляторы после включения действуют постоянно, до следующего задания значения, то есть их не нужно задавать перед выводом каждой переменной.

По умолчанию (если не задать явно манипулятор fixed или scientific) число может выводиться или с плавающей точкой, или с фиксированной, в зависимости от величины числа. Если был установлен один из манипуляторов fixed или scientific, то вернуть "автоматический" выбор формы представления числа можно при помощи манипулятора

 

cout << resetiosflags(ios_base::floatfield);

 

Пространства имен и using

 

При чтении и записи в предыдущих темах использовались объекты std::cout и std::cin соответственно. Причем они использовались с префиксом std::. Этот префикс указывает, что объекты cout, cin, endl определены в пространствен имен std. А само двойное двоеточие :: представляет оператор области видимости (scope operator), который позволяет указать, в каком пространсте имен определен объект. И без префикса эти объекты по умолчанию мы использовать не можем.

Однако подобная запись может показаться несколько громоздкой. И в этом случае можно использовать оператор using, который позволяет ввести в программу объекты из различных пространств имен.

Использование оператора using имеет следующй формат:

 

1 using пространство_имен::объект

 

Например, пусть есть следующая программа:

 

#include <iostream>

 

int main()

{

int age;

std::cout << "Input age: ";

std::cin >> age;

std::cout << "Your age: " << age << std::endl;

return 0;

}

 

Здесь используются сразу три объекта из пространства имен std: cout, cin и endl. Перепишем программу с использованием using:

 

#include <iostream>

using namespace std;

int main()

{

int age;

cout << "Input age: ";

cin >> age;

cout << "Your age: " << age << endl;

return 0;

}

 

Для каждого объекта из пространства std определяется свое выражение using. При этом программа будет работать также как и раньше.

 

Математические функции

 

В С++ определены в заголовочном файле <cmath> функции выполняющие некоторые часто используемые математические задачи. Например, нахождение корня, возведение в степень, sin(), cos() и многие другие. В таблице 1 показаны основные математические функций, прототипы которых содержатся в заголовочном файле <cmath>.

 

 

Таблица 1 — Математические функции в С++

 

Функция Описание Пример
abs( a ) модуль или абсолютное значение от а abs(-3.0)= 3.0 abs(5.0)= 5.0
sqrt(a) корень квадратный из а, причём а не отрицательно sqrt(9.0)=3.0
pow(a, b) Возведение а в степень b pow(2,3)=8
ceil(a) Округление а до наименьшего целого, но не меньше чем а ceil(2.3)=3.0 ceil(-2.3)=-2.0
floor(a) Округление а до наибольшего целого, но не больше чем а floor(12.4)=12 floor(-2.9)=-3
fmod(a, b) вычисление остатка от a/b fmod(4.4, 7.5) = 4.4 fmod( 7.5, 4.4) = 3.1
exp(a) вычисление экспоненты еа exp(0)=1
sin(a) а задаётся в радианах  
cos(a) а задаётся в радианах  
log(a) натуральный логарифм a(основанием является экспонента) log(1.0)=0.0
log10(a) десятичный логарифм а log10(10)=1
asin(a) Арксинус a, где -1.0 < а < 1.0 asin(1)=1.5708

Необходимо запомнить то, что операнды данных функций всегда должны быть вещественными, то есть a и b числа с плавающей точкой. Это связано с тем, что существует несколько экземпляров перегруженных функций, соответствующих списку аргументов. Тему перегруженные функции рассмотрим немного позже, а пока надо запомнить, что a и b числа с плавающей точкой. Разработаем программу, которая будет использовать математические функции.

 

// math_func.cpp: определяет точку входа для консольного приложения.

 

#include "stdafx.h"

#include <iostream>

#include <cmath>

using namespace std;

 

int main(int argc, char* argv[])

{

cout << "log10(10) = " << log10(10.0) << endl; // логарифм десятичный

cout << "log10(1) = " << log10(1.0) << endl;

cout << "log(2.718281) = " << log(2.718281) << endl; // натуральный логарифм(по основанию экспоненты) exp = 2.718281

cout << "sqrt(9) = " << sqrt(9.0) << endl; // корень квадратный

cout << "pow(2,3) = " << pow(2.0,3.0) << endl; // два в кубе

cout << "abs(0) = " << abs(0.0) << endl; // модуль от нуля

cout << "abs(-5) = " << abs(-5.0) << endl;

cout << "ceil(3.14) = " << ceil(3.14) << endl; // округление 3.14 до наименьшего целого, но не меньше чем 3.14

cout << "ceil(-2.4) = " << ceil(-2.4) << endl; // округление -2.4 до наименьшего целого, но не меньше чем -2.4

cout << "floor(3.14) = " << floor(3.14) << endl; // округление 3.14 до наибольшего целого, но не больше чем 3.14

cout << "floor(-2.4) = " << floor(-2.4) << endl; // округление -2.4 до наибольшего целого, но не больше чем -2.4

cout << "fmod(2.4/2.0) = " << fmod(2.4,2.0) << endl; // остаток от деления 2.4/2

system("pause");

return 0;

}


Дата добавления: 2020-11-23; просмотров: 120; Мы поможем в написании вашей работы!

Поделиться с друзьями:




Мы поможем в написании ваших работ!