- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Шрифт:
Интервал:
Закладка:
К сожалению, неявное преобразование void* в T* широко распространено в языке C и, вероятно, является основной проблемой совместимости языков С и С++ в реальных программах (см. раздел 27.4).
27.3.6. Перечисление
В языке C можно присваивать целое число перечислению без приведения int в enum. Рассмотрим пример.
enum color { red, blue, green };
int x = green; /* OK в языках C и C++ */
enum color col = 7; /* OK в языке C; ошибка в языке C++ */
Одним из следствий этого факта является то, что в программах на языке С мы можем применять операции инкрементации (++) и декрементации (––) к переменным, являющимся перечислениями. Это может быть удобным, но одновременно небезопасным.
enum color x = blue;
++x; /* переменная x становится равной значению green;
ошибка в языке C++ */
++x; /* переменная x становится равной 3; ошибка в языке C++ */
Выход за пределы перечисления может входить в наши планы, а может быть неожиданным.
Обратите внимание на то, что, подобно дескрипторам структур, имена перечислений пребывают в своем собственном пространстве имен, поэтому каждый раз при указании имени перечисления перед ним следует ставить ключевое слово enum.
color c2 = blue; /* ошибка в языке C: переменная color не находится
в пределах области видимости; OK в языке C++ */
enum color c3 = red; /* OK */
27.3.7. Пространства имен
В языке С нет пространств имен (в том смысле, как это принято в языке С++). Так что же можно сделать, чтобы избежать коллизий имен в больших программах, написанных на языке С? Как правило, для этого используются префиксы и суффиксы. Рассмотрим пример.
/* в bs.h: */
typedef struct bs_string { /* ... */ } bs_string; /* строка
Бьярне */
typedef int bs_bool; /* булев тип Бьярне */
/* in pete.h: */
typedef char* pete_string; /* строка Пита */
typedef char pete_bool; /* булев тип Пита */
Этот прием настолько широко используется, что использовать одно- и двухбуквенные префиксы обычно уже недостаточно.
27.4. Свободная память
В языке С нет операторов new и delete, работающих с объектами. Для использования свободной памяти в нем используются функции, работающие с памятью. Наиболее важные функции определены в стандартном заголовочном файле общих утилит <stdlib.h>.
void* malloc(size_t sz); /* выделить sz байтов */
void free(void* p); /* освободить область памяти, на которую
ссылается указатель p */
void* calloc(size_t n, size_t sz); /* выделить n*sz байтов,
инициализировав их нулями */
void* realloc(void* p, size_t sz); /* вновь выделить sz байтов
в памяти, на которую ссылается
указатель p*/
Тип typedef size_t — это тип без знака, также определенный в заголовочном файле <stdlib.h>.
Почему функция malloc() возвращает указатель void*? Потому что она не имеет информации о том, объект какого типа вы хотите разместить в памяти. Инициализация — это ваша проблема. Рассмотрим пример.
struct Pair {
const char* p;
int val;
};
struct Pair p2 = {"apple",78};
struct Pair* pp = (struct Pair*) malloc(sizeof(Pair)); /* выделить память */
pp–>p = "pear"; /* инициализировать */
pp–>val = 42;
Теперь мы не можем написать инструкцию
*pp = {"pear", 42}; /* ошибка: не C и не C++98 */
ни в программе на языке C, ни в программе на языке C++. Однако в языке С++ мы могли бы определить конструктор для структуры Pair и написать инструкцию Pair* pp = new Pair("pear", 42);
В языке C (но не в языке C++; см. раздел 27.3.4) перед вызовом функции malloc() можно не указывать приведение типа, но мы не рекомендуем это делать.
int* p = malloc(sizeof(int)*n); /* избегайте этого */
Игнорирование приведения довольно часто встречается в программах, потому что это экономит время и позволяет выявить редкую ошибку, когда программист забывает включить в текст программы заголовочный файл <stdlib.h> перед использованием функции malloc(). Однако при этом исчезает и визуальный маркер, свидетельствующий о том, что размер памяти подсчитан неправильно.
p = malloc(sizeof(char)*m); /* вероятно, ошибка — нет места для m целых */
Не используйте функции malloc()/free() в программах, написанных на языке C++; операторы new/delete не требуют приведения типа, выполняют инициализацию (вызывая конструкторы) и очищают память (вызывая деструкторы), сообщают об ошибках, связанных с распределением памяти (с помощью исключений), и просто работают быстрее. Не удаляйте объект, размещенный в памяти с помощью функции malloc(), выполняя оператор delete, и не удаляйте объект, созданный с помощью оператора new, вызывая функцию free(). Рассмотрим пример.
int* p = new int[200];
// ...
free(p); // ошибка
X* q = (X*)malloc(n*sizeof(X));
// ...
delete q; // error
Этот код может оказаться вполне работоспособным, но он не является переносимым. Более того, для объектов, имеющих конструкторы и деструкторы, смешение стилей языков C и C++ при управлении свободной памятью может привести к катастрофе. Для расширения буферов обычно используется функция realloc().
int max = 1000;
int count = 0;
int c;
char* p = (char*)malloc(max);
while ((c=getchar())!=EOF) { /* чтение: игнорируются символы
в конце файла */
if (count==max–1) { /* необходимо расширить буфер */
max += max; /* удвоить размер буфера */
p = (char*)realloc(p,max);
if (p==0) quit();
}
p[count++] = c;
}
Объяснения операторов ввода в языке С приведены в разделах 27.6.2 и Б.10.2.
Функция realloc() может выделить память на

