![]() Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву ![]() Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Манипуляторы и форматирование ввода-выводаСодержание книги
Поиск на нашем сайте
Часто бывает необходимо вывести строку или число в определенном формате. Для этого используются так называемые манипуляторы. Манипуляторы – это объекты особых типов, которые управляют тем, как ostream или istream обрабатывают последующие аргументы. Некоторые манипуляторы могут также выводить или вводить специальные символы. Например, один из манипуляторов - это endl. Он вызывает вывод символа новой строки. Другие манипуляторы позволяют задавать формат вывода чисел:
Использовать манипуляторы просто – их надо вывести в выходной поток. Предположим, мы хотим вывести одно и то же число в разных системах счисления: 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”, ptr2,ptr1,ptr2-ptr1); } Результат: ptr2=160,ptr1=104,ptr2-ptr1=14
Так как указатель имеет тип long* (длина 4 байта), то «единица измерения» указателя равна 4 байтам. В самом деле: ptr1=100+1*4=104. ptr2=200-10*4=160. ptr2-ptr1=(160-104)/4=56/4=14.
Для чего нужны указатели? Указатели появились, прежде всего, для нужд системного программирования. Поскольку язык Си предназначался для "низкоуровневого" программирования, на нем нужно было обращаться, например, к регистрам устройств. У этих регистров вполне определенные адреса, т.е. необходимо было прочитать или записать значение по определенному адресу. Благодаря механизму указателей, такие операции не требуют никаких дополнительных средств языка. int *ptr=(int*)200;
Однако использование указателей нуждами системного программирования не ограничивается. Указатели позволяют существенно упростить и ускорить ряд операций. Предположим, в программе имеется область памяти для хранения промежуточных результатов вычислений. Эту область памяти используют разные модули программы. Вместо того, чтобы каждый раз при обращении к каждому конкретному модулю копировать эту область памяти, мы можем передавать указатель на эту область в качестве аргумента вызова функции, тем самым упрощая и ускоряя вычисления. Упомянутые в лекции примеры использования указателей никак не связаны с объектно-ориентированным программированием. Казалось бы, объектно-ориентированное программирование должно уменьшить зависимость от низкоуровневых конструкций типа указателей. На самом деле программирование с классами нисколько не уменьшило потребность в указателях, и даже наоборот, нашло им дополнительное применение, о чем будет рассказано в следующих лекциях.
Массивы
Массив – это один из структурированных типов данных. Это расположенные вплотную друг за другом в памяти элементы одного и того же типа. Каждый массив имеет имя. Доступ к отдельным элементам массива осуществляется по имени массива и индексу (порядковому номеру) элемента.
Основные свойства массива: ü Все элементы массива имеют один и тот же тип; ü Все элементы массива расположены в памяти друг за другом; индекс первого элемента равен НУЛЮ. ü Имя массива является указателем-константой, равной адресу начала массива (первого байта первого элемента массива) Признаком массива при описании является наличие парных квадратных скобок [ ]. Константа или константное выражение в скобках задает число элементов массива. Например: char array[81]; int key[4];
При описании массива может быть выполнена инициализация его элементов. Существуют два метода инициализации массивов. ü Инициализация по умолчанию. Это случай, когда все элементы массивов инициализируются нулями. ü Явная инициализация элементов. Это случай, когда после описания массива помещается список начальных значений элементов массива, заключенный в фигурные скобки. Существуют две формы явной инициализации элементов массива: 1) Явное указание числа элементов массива и список начальных значений, возможно, с меньшим числом элементов. Например: char array[10]={‘A’,’B’,’C’,’D’};
Здесь описывается массив из 10 элементов. Первые 4 элемента массива инициализируются символами ’A’,’B’,’C’,’D’. Значение остальных шести элементов либо равно нулю, либо не определено (в зависимости от способа объявления массива). Если список начальных значений содержит больше элементов, чем число в квадратных скобках, компилятор генерирует ошибку. 2) Неявное указание числа элементов массива со списком начальных значений. Компилятор определяет число элементов массива по списку инициализации. Например:
char array[]={’A’,’B’,’C’,’D’};
В результате создается массив ровно из 4 элементов, и эти элементы получают начальные значения из списка инициализации.
Если при описании массива отсутствует значение в квадратных скобках и список начальных значений, компилятор обычно регистрирует ошибку. Однако в тех контекстах, где не требуется резервирование места в памяти под массив, этого не происходит. Эти случаи следующие:
1. Если массив объявляется как внешний, при этом в том месте, где массив описывается приведена информация о числе его элементов. Например: extern char array[]; 2. в описании функции, если указатель на первый элемент массива является аргументом функции. Например: int function (int array[], int index) { // тело функции }
3. В прототипах функций, использующих в качестве аргумента указатель на первый элемент массива.
Доступ к отдельным элементам массива может выполняться либо с помощью индекса, либо операцией взятия значения по адресу. В первом случае для ссылки на нужный элемент указывается его порядковый номер в массиве, заключенный в квадратные скобки. Самый первый элемент массива имеет порядковый номер 0. Например:
int array[]={1,2,3,4,5}; int index = 0, first, last, bad; first = array[index]; // first = 1 last = array[4]; // last = 5 bad = a[index+6]; // bad случайно
В С++ для повышения производительности программы не выполняются многие проверки корректности вычислений, в том числе и контроль допустимости значения индекса массива. Поэтому в приведенном примере значение bad - это содержимое двух байтов памяти сразу после описанного массива a. Содержимое этих байтов случайно. Для упрощения контроля границ индекса массива удобно использовать операцию sizeof, которая применительно к массивам возвращает чмсло байтов памяти, зарезервированных компилятором для массива. Например, так можно определить число элементов массива:
int array[10]={1,2,3,4,5,6,7}; int members; members=sizeof(array)/sizeof(int);
Нетрудно догадаться, что переменная members будет равна 10. Другой способ доступа к элементам массива – использование механизма указателей. Так как имя массива – это указатель-константа на первый байт первого элемента массива, то, используя операцию взятия значения по адресу, можно выполнить доступ к любому из элементов массива. Так следующие выражения являются тождествами:
array тождественно &array[0], (array+i) тождественно &array[i]. Использование указателей для доступа к элементам массива дает несколько более короткий код программы и в ряде случаев позволяет обойтись без дополнительных переменных, используемых в качестве индексов.
С++ поддерживает многомерные массивы. Размерность массива – это число индексов, используемых для ссылки на конкретный элемент массива. Многомерные массивы должны описываться и могут при описании инициализироваться. Например: int matrix[10][20]; int m[3][3]={0, 1, 2, 10,11,12, 20,21,22}; char strings[3][80]= {“Первая строка”, “Втоая строка”, “Третья строка” }; Элементы многомерных массивов хрянятся в памяти в порядке возрастания самого правого индекса. Или, как иногда говорят, по строкам. Список начальных значений, задаваемых при описании массива, соответствует порядку элементов массива в памяти. Особый случай – инициализация двумерного массива строковыми литералами. В приведенном примере описывается двумерный массив strings, состоящий из 3-х строк по 80 символов (байт) каждая. Строки массива инициализируются символами строковых литералов. В конце каждого литерала помещается символ конца строки – ‘\0’. Многомерные массивы могут инициализироваться и без указания одной (самой левой (!)) из размерностей массива в квадратных скобках. Компилятор в этом случае определяет число элементов по числу членов в списке инициализации. Например, для массива m будет получен тот же результат, что и в предыдущем примере.
int m[][3]={0, 1, 2,
10,11,12, 20,21,22}; Имя двумерного массива является указателем-константой на массив указателей констант. Элементами массива указателей являются указатели-константы на начало каждой из строк массива. Например, для двумерного массива matrix[2][2] указателями-константами на нулевую, первую и вторую строки будут соответственно matrix[0], matrix[1] и matrix[2], а следующие выражения будут тождественными:
matrix[0] тождественно & matrix[0][0], matrix[1] тождественно & matrix[1][0], matrix[2] тождественно & matrix[2][0].
Как и для одномерных массивов, доступ к элементам двумерного массива может осуществляться по индексу или с помощью механизма указателей. Рассуждения о многомерных массивах можно эксраполировать и на большее, чем 2 число размерностей. Однако на практике массивы с большей чем 3 размерностью встречаются редко.
|
|||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2016-04-26; просмотров: 388; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 13.59.153.218 (0.011 с.) |