Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Операции над указателями. Адресная арифметика
< Кратко рассказать: понятие указателя, операции взятия адреса и обращения по адресу > Над указателями можно выполнять операции присваивания, обращения по адресу, сравнения, арифметическое сложение и вычитание. Пример присваивания: int x = 10; int y = 10; int* xptr = &x; int* yptr = &y; Указатели одного и того же типа можно сравнивать с помощью стандартных операций сравнения. При этом сравниваются значения указателей, а не значения величин, на которые данные указатели ссылаются. В приведенном примере условие if (x==y) возвратит истину, а if(xptr==yptr) – ложь (адреса разные). К указателю можно прибавить целое число или вычесть из него целое число. Результатом прибавления к указателю единицы является адрес следующей величины типа, на который ссылается указатель, в памяти. Например: объявлена переменная long int x и указатель long int * xptr. Для хранения переменной типа long int в памяти отводится 4 байта. Если адрес x равен 0x1000 и xptr=&x, то в результате операции xptr+=1 указатель станет равным 0x1004 (на 4 байта больше). Вычитание применимо только к указателям одного типа. Разность указателей показывает, сколько объектов соответствующего типа может поместиться между указанными адресами. Строки в языке C++ Для того чтобы работать с текстом, в языке Си++ не существует особого встроенного типа данных. Роль строки играет массив символов, заканчивающийся нулевым байтом (то есть байтом, значение которого равно нулю, или ‘\0’). Иногда такое представление называют Си-строки, поскольку оно появилось в языке Си. Таким образом, если мы объявляем строку из 10 символов, то с учетом последнего нулевого байта необходимо объявить массив char str[11]; Для записи строковых констант в программе используются литералы. Литерал – это последовательность знаков, заключенная в двойные кавычки: "Это строка", "0123456789", "*" Символ, заключенный в двойные кавычки, отличается от символа, заключенного в апострофы. Литерал "*" обозначает два байта: первый байт содержит символ звездочки, второй байт содержит ноль. Константа '*' обозначает один байт, содержащий знак звездочки. С помощью литералов можно инициализировать массивы: char alldigits[] = "0123456789"; Размер массива явно не задан, он определяется исходя из размера инициализирующего его литерала, в данном случае 11 (10 символов плюс нулевой байт). При таком объявлении нулевой байт компилятор добавит автоматически.
При работе со строками особенно часто используется связь между массивами и указателями. < Дать определение указателя > Значение литерала – это массив неизменяемых байтов нужного размера. Строковый литерал может быть присвоен указателю на char: char* message = "Сообщение программы";Значение литерала – это адрес его первого байта, указатель на начало строки. Указатель на байт (тип char*) указывает на начало строки. Для ввода строк используют функции scanf() и gets(), fgets().Первая функция применяется, если вводимая строка не содержит пробелов. Пример: char name [50]; scanf(" %s", name); Так как name – массив символов, а имя массива есть указатель (адрес) первого элемента, то перед name в данном случае знак & не ставится. Длину строки вычисляет функция strlen(): int n=strlen(str1); Завершающий нулевой символ в подсчет не включается. Копирование строк: strcpy(str2, str1) - Копировать строку str1по адресу str2, включая завершающий нулевой байт. Программирование ввода-вывода в файлы в языке C++ Для использования функций ввода/вывода в языке С необходимо подключить к программе заголовочный файл <stdio.h>. Информация считывается как поток байтов. Объявление файловой переменной, открытие файла и создание связи между файловой переменной в языке C производится системным вызовом fopen, возвращающим указатель на файловую переменную. Обычно в программе используется конструкция: FILE * f = fopen("имя_файла", "режим_открытия"); Допустимые значения режима открытия файла: r – чтение, w – запись, a – добавление в конец. Для нетекстовых (двоичных) файлов соответственно rb, wb, ab. Для одновременных чтения/записи: r+, w+, a+ и r+b, w+b, a+b. Пример: FILE *f=fopen("test-c.txt","w"); Для ввода/вывода в файл используются функции, аналогичные стандартному вводу/выводу, к их именам добавлена «f», например: fprintf(f,”формат”,список); fscanf(file,формат”,список); fgets(имя_строки, размер,f). Примеры: fprintf(f,"number: %2i",i); fgets(res_string,sizeof(res_string),file). Закрытие файла: fclose(file); Перегрузка функций и операторов в языке C++ В языке Си++ допустимо иметь несколько функций с одним и тем же именем, потому что функции различаются не только по именам, но и по типам аргументов. Этот прием называется перегрузкой функций.
Как и при объявлении обычных функций, каждую функцию необходимо объявить и определить. Пусть, скажем, требуется определить среднее нескольких чисел. Тогда в программе можно объявить функцию вычисления среднего значения двух целых чисел sred(int, int): float sred(int a, int b) { return (a+b)/2; } Если в программе требуется также определить среднее из трех чисел, то ее можно объявить аналогично: float sred(int a, int b, int c) (return (a+b+c)/3; } Если теперь потребуется определить среднее из трех действительных чисел, то можно объявить еще функцию: float sred (float a, float b, float c) { return (a+b+c)/3; } При определении функций имеют значение тип и количество аргументов, но не тип возвращаемого значения. Попытка определения двух функций с разными типами возвращаемых значений, но с одним и тем же именем, одними и теми же аргументами, приведет к ошибке компиляции. Язык C++ допускает также перегрузку операторов. Перегрузка операторов производится в тех случаях, когда в программе определяется собственный тип данных – тогда необходимо определить операции, допустимые для этого типа. Например, пусть объявлен тип данных – школьная дробь: struct Ratio {unsigned long num, denum;}; Теперь имя структуры Ratio может использоваться для объявления переменных или массивов нового типа: Ratio x,y,z; Перегрузка оператора сводится к написанию новой функции. Например, чтобы определить операцию += для дробей, необходимо написать функцию со следующим заголовком: Ratio& operator+=(Ratio &a, const Ratio &b) { a.num=a.num*b.denum + b.num*a.denum; a.denum*=b.denum; return a; } Перегрузка оператора состоит в написании функции вида тип operatorS(параметры), где S – знак операции. Динамическое распределение памяти в языке C++ В С++ объекты могут быть размещены либо статически – во время компиляции, либо динамически – во время выполнения программы. Динамическое распределение памяти используется тогда, когда заранее неизвестно, сколько объектов понадобится в программе и понадобятся ли они вообще. В C++ используется два способа работы с динамической памятью. Первый использует семейство функций malloc и достался в наследство от С. Второй использует операции new и delete, определенные только в C++. Основу системы динамического распределения памяти в С составляют библиотечные функции calloc(), malloc(), realloc() и free(). Первые три функции возвращают указатель на выделенную область памяти или NULL. < Быть готовым рассказать, что такое указатель > Функция calloc():void *calloc(size_t num, size_t size); выделяет память, размер которой равен значению выражения num * size, т.е. память, достаточную для размещения массива, содержащего num объектов размером size. Выделенная область памяти обнуляется. Функция malloc():void *malloc(size_t size); возвращает указатель на первый байт области памяти размера size или NULL. Выделенная область памяти не инициализируется. Функция realloc():void *realloc(void *ptr, size_t size); изменяет размер блока ранее выделенной памяти, адресуемой указателем *ptr в соответствии с заданным размером size.. Функция free():void free(void *ptr); освобождает блок памяти, адресуемый указателем *ptr. Функция free() должна вызываться только с указателем, который был ранее получен в результате вызова одной из функций динамического распределения памяти.
Основу динамического распределения памяти в C++ составляют операции new и delete. Память для величины какого-либо типа можно выделить, выполнив операцию new. Созданный таким образом объект существует до тех пор, пока память не будет явно освобождена с помощью операции delete. В качестве операнда delete должен быть задан адрес, возвращенный операцией new. Операция new имеет несколько форм: int* n = new int: // 1 int* m = new int (10); // 2 int* q = new int [10]; // 3 В операторе 1 операция new выполняет выделение достаточного для размещения величины типа int участка динамической памяти и записывает адрес начала этого участка в переменную n. В операторе 2, кроме описанных выше действий, производится инициализация выделенной динамической памяти значением 10. В операторе 3 операция new выполняет выделение памяти под 10 величин типа int (массива из 10 элементов) и записывает адрес начала этого участка в переменную q, которая может трактоваться как имя массива. Через имя можно обращаться к любому элементу массива. Освобождение памяти, выделенной под массив, должно быть выполнено с помощью операции delete: delete адрес; или (для масива) delete [] адрес.
|
|||||||
Последнее изменение этой страницы: 2017-01-24; просмотров: 379; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 35.175.172.94 (0.01 с.) |