Манипуляторы и форматирование ввода-вывода
Часто бывает необходимо вывести строку или число в определенном формате. Для этого используются так называемые манипуляторы.
Манипуляторы – это объекты особых типов, которые управляют тем, как ostream или istream обрабатывают последующие аргументы. Некоторые манипуляторы могут также выводить или вводить специальные символы.
Например, один из манипуляторов - это endl. Он вызывает вывод символа новой строки. Другие манипуляторы позволяют задавать формат вывода чисел:
Манипулятор | Описание |
endl | при выводе перейти на новую строку; |
ends | вывести нулевой байт (признак конца строки символов); |
flush | немедленно вывести и опустошить все промежуточные буферы; |
dec | выводить числа в десятичной системе (действует по умолчанию); |
oct | выводить числа в восьмеричной системе; |
hex | выводить числа в шестнадцатиричной системе счисления; |
setw (int n) | установить ширину поля вывода в n символов (n – целое число); |
setfill(int n) | установить символ-заполнитель; этим символом выводимое значение будет дополняться до необходимой ширины; |
setprecision(int n) | установить количество цифр после запятой при выводе вещественных чисел; |
setbase(int n) | установить систему счисления для вывода чисел; n может принимать значения 0, 2, 8, 10, 16, причем 0 означает систему счисления по умолчанию, т.е. 10. |
Использовать манипуляторы просто – их надо вывести в выходной поток.
Предположим, мы хотим вывести одно и то же число в разных системах счисления:
int x = 53;cout << "Десятичный вид: " << dec << x << endl << "Восьмиричный вид: " << oct << x << endl << "Шестнадцатиричный вид:" << hex << x << endl
Аналогично используются манипуляторы с параметрами.
Вывод числа с разным количеством цифр после запятой:
double x;// вывести число в поле общей шириной // 6 символов (3 цифры до запятой, // десятичная точка и 2 цифры после запятой)cout << setw(6) << setprecision(2) << x << endl;Те же манипуляторы (за исключением endl и ends) могут использоваться и при вводе. В этом случае они описывают представление вводимых чисел. Кроме того, имеется манипулятор, работающий только при вводе, это ws. Данный манипулятор переключает вводимый поток в такой режим, при котором все пробелы (включая табуляцию, переводы строки, переводы каретки и переводы страницы) будут вводиться. По умолчанию эти символы воспринимаются как разделители между атрибутами ввода.
int x;// ввести шестнадцатиричное числоcin >> hex >> x;
Указатели
В языке С++ существует два способа доступа к переменной - это ссылка на переменную по её имени и использование механизма указателей.
Указатель-переменная (или просто указатель) это переменная, предназначенная для хранения адреса какой-либо переменной в памяти.
Указатель-константа – это значение адреса оперативной памяти.
В языке определены две специальные операции для доступа к переменным через указатели. Это операции & и операция *.
Результатом операции & является выдача адрес объекта, к которому операция применяется. Например &var1дает адрес, по которому переменная var1хранится в памяти (точнее адрес её первого байта).
Операция *- это операция обращения к содержимому памяти по адресу, хранимому в переменной-указателе или равному указателю константе.
Признаком переменной-указателя для компилятора является наличие в описании переменной двух компонентов:
ü Типа объекта данных, для доступа к которому используется указатель (или, как еще говорят, на который ссылается указатель).
ü Символа *перед именем переменной.
Сочетание типа данныйх и символа * воспринимается компилятором как особый тип данных – «указатель на что-либо». Таким образом, описание
int var1,*ptr;
приводит к появлению переменной var1 и указателя-переменной ptr. Здесь переменная ptr будет иметь тип int*, т.е. тип «указатель на целое».
Указатели при их описании могут, как и обычные переменные, получать начальные значения:
int var1,*ptr=&var1;
Здесь указателю ptr присваивается начальное значение – адрес, по которому в памяти хранится переменная var1.
Еще одна инициализация при описании:
int *ptr=(int*)200;
Операцию *, пытаясь выразить словами смысл выражения, можно заменить фразой: - «взять содержимое по адресу, равному значению указателя». Например, оператор присваивания
*ptr2=*ptr1+4;
Можно интерпретировать так: взять содержимое памяти по адресу, равному значению указателя ptr1, прибавить к этому содержимому 4, а результат поместить по адресу, равному значению указателя ptr2.
Сам указатель-переменная тоже имеет адрес. Поэтому, например, корректным будет фрагмент:
int var1, *ptr1, *ptr2 = &var1;
ptr1 = (int*)&ptr2;
Здесь описываются два указателя-переменные, Указатель ptr2 инициализируется значением адреса переменной var1. Затем указателю ptr1присваивается значение адреса, по которому в памяти располагается указатель ptr2.
Для указателей-переменных разрешены некоторые операции: присваивание, инкремент или декремент, сложение или вычитание, сравнение.
Язык разрешает операцию сравнение указателей одинакового типа (!). При выполнении присваивания значение указателя в правой части выражения пересылается в ячейку памяти, отведенную для указателя в левой части.
Важной особенностью арифметических операций с указателями является то, что физическое увеличение или уменьшение его значения зависит от типа указателя, т.е. от размера того объекта, на который ссылается указатель. Если к указателю, описанному как type *ptr, прибавить или отнять константу N, значение ptr изменяется на N* sizeof(type). Разность двух указателей type *ptr1 и type *ptr2 – это разность их значений, поделенная на sizeof(type).
В частности, арифметические операции над указателями типа char* (размер типа равен 1) выполняются как над обычными целыми числами с той лишь разницей, что значения, участвующие в операции, - это адреса в оперативной памяти. Однако для других типов это не так. Например:
Void main(void)
{
long *ptr1=(long*)100;
long *ptr2=(long*)200;
ptr1++;
ptr2-=10;
printf(“ptr2=%ld,ptr1=%ld,
ptr2-ptr1=%ld\n”,
Дата добавления: 2016-04-22; просмотров: 708;