» » » » Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

На нашем литературном портале можно бесплатно читать книгу Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп, Бьёрн Страуструп . Жанр: Программирование. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале litmir.org.
Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Название: Программирование. Принципы и практика использования C++ Исправленное издание
Дата добавления: 22 август 2024
Количество просмотров: 100
Читать онлайн

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних просмотр данного контента СТРОГО ЗАПРЕЩЕН! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту readbookfedya@gmail.com для удаления материала

Программирование. Принципы и практика использования C++ Исправленное издание читать книгу онлайн

Программирование. Принципы и практика использования C++ Исправленное издание - читать бесплатно онлайн , автор Бьёрн Страуструп

Специальное издание самой читаемой и содержащей наиболее достоверные сведения книги по C++. Книга написана Бьярне Страуструпом — автором языка программирования C++ — и является каноническим изложением возможностей этого языка.
Помимо подробного описания собственно языка, на страницах книги вы найдете доказавшие свою эффективность подходы к решению разнообразных задач проектирования и программирования. Многочисленные примеры демонстрируют как хороший стиль программирования на С-совместимом ядре C++, так и современный -ориентированный подход к созданию программных продуктов. Третье издание бестселлера было существенно переработано автором. Результатом этой переработки стала большая доступность книги для новичков. В то же время, текст обогатился сведениями и методиками программирования, которые могут оказаться полезными даже для многоопытных специалистов по C++. Не обойдены вниманием и нововведения языка: стандартная библиотека шаблонов (STL), пространства имен (namespaces), механизм идентификации типов во время выполнения (RTTI), явные приведения типов (cast-операторы) и другие.
Настоящее специальное издание отличается от третьего добавлением двух новых приложений (посвященных локализации и безопасной обработке исключений средствами стандартной библиотеки), довольно многочисленными уточнениями в остальном тексте, а также исправлением множества опечаток.
Книга адресована программистам, использующим в своей повседневной работе C++. Она также будет полезна преподавателям, студентам и всем, кто хочет ознакомиться с описанием языка «из первых рук».

Перейти на страницу:
class="code">age нумеруются от 0 до age.size()–1. Вектор age можно изобразить следующим образом:

Как реализовать эту схему в компьютерной памяти? Как хранить значения и обеспечивать к ним доступ? Очевидно, что мы должны определить класс и назвать его vector. Далее, нужен один член класса для хранения размера вектора и еще один член для хранения его элементов. Как же представить множество элементов, количество которых может изменяться? Для этого можно было бы использовать стандартный класс vector, но в данном контексте это было бы мошенничеством: мы же как раз этот класс и разрабатываем.

Итак, как представить стрелку, изображенную на рисунке? Представим себе, что ее нет. Мы можем определить структуру данных фиксированного размера.

class vector {

  int size,age0,age1,age2,age3;

  // ...

};

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

Это просто и красиво, но как только мы попробуем добавить элемент с помощью функции push_back(), окажемся в затруднительном положении: мы не можем добавить элемент, так как количество элементов зафиксировано и равно четырем. Нам нужно нечто большее, чем структура данных, хранящая фиксированное количество элементов. Операции, изменяющие количество элементов в объекте класса vector, такие как push_back(), невозможно реализовать, если в классе vector количество элементов фиксировано. По существу, нам нужен член класса, ссылающийся на множество элементов так, чтобы при расширении памяти он мог ссылаться на другое множество элементов. Нам нужен адрес первого элемента. В языке C++ тип данных, способный хранить адрес, называют указателем (pointer). Синтаксически он выделяется суффиксом *, так что double* означает указатель на объект типа double. Теперь можем определить первый вариант класса vector.

// очень упрощенный вектор элементов типа double (вроде vector<double>)

class vector {

  int sz;        // размер

  double* elem;  // указатель на первый элемент (типа double)

public:

  vector(int s); // конструктор: размещает в памяти s чисел

  // типа double,

  // устанавливает на них указатель elem,

  // хранит число s в члене sz

  int size() const { return sz; } // текущий размер

};

Прежде чем продолжить проектирование класса vector, изучим понятие “указатель” более подробно. Понятие “указатель” — вместе с тесно связанным с ним понятием “массив” — это ключ к понятию “память” в языке C++.

17.3. Память, адреса и указатели

 

 Память компьютера — это последовательность байтов. Эти байты нумеруются от нуля до последнего. Адресом (address) называют число, идентифицирующее ячейку в памяти. Адрес можно считать разновидностью целых чисел. Первый байт памяти имеет адрес 0, второй — 1 и т.д. Мегабайты памяти можно визуализировать следующим образом:

Все, что расположено в памяти, имеет адрес. Рассмотрим пример.

int var = 17;

Эта инструкция резервирует участок памяти, размер которого определяется размером типа int, для хранения переменной var и записывает туда число 17. Кроме того, можно хранить адреса и применять к ним операции. Объект, хранящий адрес, называют указателем. Например, тип, необходимый для хранения объекта типа int, называется указателем на int и обозначается как int*.

int* ptr = &var; // указатель ptr хранит адрес переменной var

Для определения адреса объекта используется оператор взятия адреса, унарный &. Итак, если переменная var хранится в участке памяти, первая ячейка которого имеет адрес 4096 (или 212), то указатель ptr будет хранить число 4096.

По существу, память компьютера можно рассматривать как последовательность байтов, пронумерованную от 0 до size-1. Для некоторых машин такое утверждение носит слишком упрощенный характер, но для нашей модели этого пока достаточно.

Каждый тип имеет соответствующий тип указателя. Рассмотрим пример.

char ch = 'c';

char* pc = &ch; // указатель на char

int ii = 17;

int* pi = &ii; // указатель на int

Если мы хотим увидеть значение объекта, на который ссылаемся, то можем применить к указателю оператор разыменования, унарный *. Рассмотрим пример.

cout << "pc==" << pc << "; содержимое pc==" << *pc << "n";

cout << "pi==" << pi << "; содержимое pi==" << *pi << "n";

Значением *pc является символ c, а значением *pi — целое число 17. Значения переменных pc и pi зависят от того, как компилятор размещает переменные ch и ii в памяти. Обозначение, используемое для значения указателя (адрес), также может изменяться в зависимости от того, какие соглашения приняты в системе; для обозначения значений указателей часто используются шестнадцатеричные числа (раздел A.2.1.1).

Оператор разыменования также может стоять в левой части оператора присваивания.

*pc = 'x'; // OK: переменной char, на которую ссылается

           // указатель pc,

           // можно присвоить символ 'x'

*pi = 27;  // OK: указатель int* ссылается на int, поэтому *pi —

           // это int

*pi = *pc; // OK: символ (*pc) можно присвоить переменной

           // типа int (*pi)

 

 Обратите внимание: несмотря на то, что значение указателя является целым числом, сам указатель целым числом не является. “На что ссылается int?” — некорректный вопрос. Ссылаются не целые числа, а указатели. Тип указателя позволяет выполнять операции над адресами, в то время как тип int позволяет выполнять (арифметические и логические) операции над целыми числами. Итак, указатели и целые числа нельзя смешивать.

int i = pi; // ошибка: нельзя присвоить объект типа int*

            // объекту типа int

pi = 7;     // ошибка: нельзя присвоить объект типа int объекту

            // типа int*

Аналогично, указатель на char (т.е. char*) — это не указатель на int (т.е. int*). Рассмотрим пример.

pc = pi; // ошибка: нельзя присвоить объект типа int*

         // объекту типа char*

pi = pc; // ошибка: нельзя присвоить объект типа char*

         // объекту

Перейти на страницу:
Комментариев (0)