c++ — вопросы с ответами

C++ – это язык программирования общего назначения. Он был создан Бьярном Страуструпом в Bell Labs приблизительно в 1980 году. C++ очень похож на C (изобретенный Деннисом Ритчи в начале 1970-х). C++ настолько совместим с C, что, вероятно, скомпилирует более 99% программ на C без изменения строк исходного кода. Тем не менее, C++ является намного более структурированным и более безопасным языком, чем C, поскольку он основан на ООП (Объектно-ориентированное программирование).

Можно ли назвать C++ основополагающим языком программирования?

Ответ зависит от точки зрения разработчика и требований к проекту. Большинство распространенных задач можно выполнить в C++, хоть и не очень быстро. Например, проектирование GUI для приложений. Некоторые другие языки, такие как Visual Basic и Python, имеют встроенные элементы дизайна GUI. Поэтому они лучше подходят для задач такого типа.

Некоторые из сценарных языков обеспечивают дополнительную программируемость приложений: MS Word и даже Photoshop, как правило, являются вариациями Basic, а не C++.

Но несмотря на это, C++ по-прежнему широко используется, и множество самых известных программ и сервисов написаны именно на нем, например:

  • Bloomberg (финансы);
  • Amazon (веб-коммерция), Google (веб-поиск);
  • Facebook (социальные сети).

Многие языки программирования зависят от производительности и надежности C++ при их реализации. Сюда относятся:

  • Виртуальные машины Java;
  • Интерпретаторы JavaScript (например, Google V8);
  • Браузеры (например, Internet Explorer, Mozilla Firefox, Apple Safari и Google Chrome);
  • Прикладные и веб-среды (например, платформа Microsoft .NET для веб-служб).

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

Типы переменных в C++

C++ определяет целый набор простых типов данных.

Тип void не имеет связанных с ним значений и может использоваться только в нескольких случаях. Чаще всего это тип возвращаемых функций, которые не возвращают значение.

Арифметический тип включают символы, целые числа, логические значения и числа с плавающей запятой. В дальнейшем арифметический тип можно разделить на две категории:

  • Плавающий тип. Число с плавающей запятой (или плавающий тип) представляет собой десятичные числа. Стандарт IEEE определяет минимальное количество значащих цифр. Большинство компиляторов обычно обеспечивают большую точность, чем указанный минимум. Как правило, числа с плавающей запятой представлены 32 битами, удваиваются в 64 битах и имеют повышенную точность в 96 или 128 битах.
  • Интегральный тип (который включает символ, целое число и логический тип данных). Логический тип имеет только две разновидности значений: True или False. Существует несколько типов символов, большинство из которых созданы для поддержки интернационализации. Основным типом символов является char. Char имеет тот же размер, что и один машинный байт, то есть один байт.

Тип со знаком. это отрицательные или положительные числа (включая ноль). В типе со знаком диапазон должен быть равномерно разделен между значениями + ve и -ve. Таким образом, 8-битный символ со знаком будет содержать значения от –127 до 127.

Тип без знака. В типе без знака все значения >= 0. 8-битный символ без знака может содержать от 0 до 255 (оба включительно).

Переменная в C++

Переменная предоставляет нам возможность именного хранения. Она позволяет программисту манипулировать данными в соответствии с необходимостью. Каждая переменная в C++ имеет свой тип.

Имя переменной и ее идентификаторы

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

  • Идентификаторы должны
  • Начинаться с буквы или подчеркивания ('_');
  • Быть чувствительны к регистру (прописные и строчные буквы различны)

К тому же, часть переменных зарезервирована системой (auto, default, for, operator, int, typedef, char и т. д.).

Существует много общепринятых соглашений для именования переменных в разных языках программирования. Следование этим соглашениям может улучшить читаемость программы.

  • Идентификатор должен дать хоть какое-то указание на его значение;
  • Имена переменных обычно строчные – site77, а не Site77 или SITE77;
  • Классы, которые мы определяем, обычно начинаются с заглавной буквы;
  • Идентификаторы, содержащие несколько слов, должны визуально отличать каждое слово. Например, my7_website, а не my7website.

Регистровая переменная

Переменные, которые часто используются в программе на C++, могут быть помещены в регистры с помощью ключевого слова register. Ключевое слово register указывает компилятору сохранить данную переменную в регистре. Компилятор может как поместить ее в регистр, так и нет. Как правило, сами компиляторы выполняют различные оптимизации, которые включают внесение некоторых переменных в регистр. Количество программных переменных в программе на C++ не ограничено. Но компилятор может не хранить переменную в регистре. Это связано с тем, что регистровая память очень ограничена и чаще всего используется ОС.

Предопределенный жизненный цикл объектов

Каждый объект, который вы создаете в своей программе, имеет точно определенное время жизни. Как только вы определились с конкретным жизненным циклом, вы точно знаете, в какой момент время вашего объекта он начинается, а когда заканчивается.

Для автоматических переменных жизненный цикл начинается после их объявления, то есть после того, как инициализация заканчивается нормально (не через исключение). А вот заканчивается их жизненный цикл после выхода из области, в которой они были объявлены. Для двух автоматических объектов, объявленных рядом друг с другом, жизненный цикл закончится позже у того, у которого он раньше начался.

Жизненный цикл параметров функции начинается непосредственно перед началом выполнения функции, а заканчивается сразу после ее выполнения.

Для глобальных переменных (переменных, определенных в области имен) жизненный цикл начинается до основного запуска, а заканчивается сразу после него. Для двух глобальных переменных, определенных в одной и той же единице перевода (файле, после включения заголовка), тот, который определен выше, начинает жизненный цикл раньше и заканчивает его позже. Для двух глобальных переменных, определенных в разных единицах перевода, невозможно сделать предположения об их относительном жизненном цикле.

Жизненный цикл временных переменных (с двумя четко определенными исключениями) начинается, когда функция возвращается по значению внутри большего выражения (или когда они создаются), и заканчивается после оценки полного выражения.

Двумя исключениями являются:

  • Когда временная переменная связана с глобальной или автоматической ссылкой, срок ее службы длится столько же, сколько и у ссылки;
  • Второе исключение из правила применимо, когда идет инициация встроенных массивов пользовательских типов. В этом случае, если стандартно конструктор используется для инициализации n-го элемента массива, и имеет один или несколько аргументов, жизненный цикл каждого отдельного временного файла, созданного в аргументе по умолчанию, заканчивается, когда мы приступаем к инициализации (n + 1) -го элемента. Но в практике это скорее всего никогда не пригодится.

Полезные в использовании возможности C++

C++ все еще активно развивается, постоянно расширяя свой функционал и возможности. Самым примечательным обновлением стала версия C++11, изменившая ядро языка и добавившая множество новых возможностей.

nullptr

Константа 0 имеет несколько ролей: константа целого числа и константа нулевого указателя. C++11 исправляет это, вводя новое ключевое слово, служащее отличительной константой нулевого указателя – nullptr.

В исходном коде все нулевые указатели будут представлены новым ключевым словом nullptr.

shared_ptr

Интеллектуальный указатель не является новой концепцией, многие библиотеки реализовали его еще много лет назад. Одним из самых популярных указателей является boost::shared_ptr, новшеством которого стала стандартизация. Вам больше придется использовать внешнюю библиотеку для работы со смарт-указателями.

Широко используемый стандартизированный разделяемый указатель приводит к тому, что в исходном коде остается только несколько необработанных указателей.

Выражение noexcept

Если функция не в состоянии генерировать исключение или если программа не написана для обработки исключений генерируемых функцией, эта функция может быть объявлена как noexcept.

Шаблоны с вариативным числом аргументов

Это новая возможность языка, которая может принимать произвольное количество аргументов шаблона любого типа. Оба класса и функции могут быть переменными.

Лямбда-функции

Если есть одна особенность, которая широко используется в новых программах, то это точно лямбда-функции. Так же известные как "анонимные функции", лямбды – это в основном миниатюрные функции, имена которых не привязаны к ним. Они могут быть встроены в другие функции или сохранены внутри векторов функций и вызваны позже.

Сценарные языки, а особенно Python, Javascript и Ruby, годами наслаждались лямбдами, но теперь в C++ они тоже есть. Лямды очень полезны, а особенно в процессе разработки видеоигр.

Сильно типизированные перечисления

"Традиционные" перечисления в C++ экспортируют свои перечислители в окружающую область, что может привести к коллизиям имен, если два разных перечисления в одной и той же области видимости натыкаются на перечислители с одинаковыми именами.

C++11 вводит ключевые слова класса enum. Они больше не экспортируют свои счетчики в окружающей области. Более того, теперь мы также можем наследовать от enum.

Единая инициализация и список инициализаторов

До появления C++11, программисты, особенно новички, могли легко запутаться с вопросом о том, как инициализировать любую переменную или любой объект. Инициализация может быть выполнена с использованием скобок, фигурных скобок и/или операторов присваивания. Итак, C++11 запускает концепцию равномерной инициализации, в которой для любой инициализации вы можете написать один общий синтаксис.

26 ответов
Вот кусок кода на С++, который кажется очень своеобразным. По какой-то странной причине сортировка данных чудом делает код почти в шесть раз быстрее. #include <algorithm> #include <ctime> #include <iostream> int main() { // Generate data const unsigned arraySize = 32768; ...
optimization
performance
branch-prediction
27 июнь 2012, в 14:02
10 ответов
Предположим, что a1, b1, c1 и d1 указывают на память кучи, и мой числовой код имеет следующий основной цикл. const int n = 100000; for (int j = 0; j < n; j++) { a1[j] += b1[j]; c1[j] += d1[j]; } Этот цикл выполняется 10000 раз через другой внешний цикл for. Чтобы ускорить его, я измен...
performance
vectorization
compiler-optimization
17 дек. 2011, в 19:00
7 ответов
Примечание. Ответы были заданы в определенном порядке, но поскольку многие пользователи сортируют ответы в соответствии с голосами, а не время, которое они дали, здесь индекс ответов в том порядке, в котором они имеют наибольший смысл: Общий синтаксис перегрузки оператора на С++ Три основных прав...
operators
operator-overloading
c++-faq
12 дек. 2010, в 12:59
8 ответов
Что означает копирование объекта? Что такое конструктор копирования и оператор присваивания копии? Когда мне нужно объявить их самостоятельно? Как я могу предотвратить копирование моих объектов?
copy-constructor
assignment-operator
rule-of-three
c++-faq
13 нояб. 2010, в 13:42
25 ответов
После прочтения Hidden Features и Dark Corners of С++/STL на comp.lang.c++.moderated, я был полностью удивлен, что следующий фрагмент, скомпилированный и работающий в как Visual Studio 2008, так и g++ 4.4. Здесь код: #include <stdio.h> int main() { int x = 10; while (x --> 0) // x g...
operators
code-formatting
29 окт. 2009, в 05:47
36 ответов
Мне говорили, что писать код using namespace std в коде неверно, и что я должен использовать вместо него std::cout и std::cin. Почему using namespace std считается плохой практикой? Неэффективен ли он или он может объявлять неоднозначные переменные (переменные, которые имеют одно и то же имя как фун...
namespaces
std
using-directives
c++-faq
21 сен. 2009, в 02:24
1 ответ
Этот вопрос пытается собрать несколько жемчужин среди десятков плохих книг на С++, которые публикуются каждый год. В отличие от многих других языков программирования, которые часто подбираются из учебников, найденных в Интернете, немногие из них могут быстро забрать С++, не изучая хорошо написанную ...
c++-faq
23 дек. 2008, в 05:27
10 ответов
У меня есть файл из 30000 строк данных, которые я хочу загрузить в базу данных sqlite3. Есть ли более быстрый способ, чем создание операторов вставки для каждой строки данных? Данные разделяются пробелами и отображаются непосредственно в таблицу sqlite3. Есть ли какой-либо метод объемной вставки для...
insert
bulk
12 дек. 2008, в 21:10
8 ответов
Какое правильное использование: static_cast dynamic_cast const_cast reinterpret_cast C-стиль (type)value Литье в стиле функции type(value) Как вы решаете, что использовать в каких случаях?
pointers
casting
c++-faq
01 дек. 2008, в 19:46
76 ответов
Я пытаюсь перебрать слова строки. Можно предположить, что строка состоит из слов, разделенных пробелами. Обратите внимание, что меня не интересуют строковые функции Си или подобные манипуляции/доступ к символам. Кроме того, пожалуйста, дайте приоритет элегантности над эффективностью в вашем ответ...
string
split
25 окт. 2008, в 10:08
11 ответов
Что означает ключевое слово explicit в С++?
constructor
explicit
explicit-constructor
c++-faq
23 сен. 2008, в 15:09
16 ответов
Я бы хотел найти хорошую объектно-ориентированную С++ (в отличие от C) оболочку для sqlite. Что рекомендуют люди? Если у вас есть несколько предложений, пожалуйста, разместите их в отдельных ответах для голосования. Кроме того, укажите, есть ли у вас опыт обертки, которую вы предлагаете, и как вы ее...
database
23 сен. 2008, в 12:24
37 ответов
Я знаю, что ссылки - это синтаксический сахар, поэтому код легче читать и писать. Но каковы различия? Резюме из ответов и ссылок ниже: Указатель может быть повторно назначен любым количеством раз, в то время как ссылка не может быть повторно назначена после привязки. Указатели не могут указыват...
pointers
reference
c++-faq
11 сен. 2008, в 22:03
27 ответов
Как вы устанавливаете, очищаете и переключаете бит в C/С++?
bit-manipulation
bitwise-operators
07 сен. 2008, в 01:08
32 ответа
В языках программирования C и С++ в чем разница между использованием угловых скобок и использованием кавычек в инструкции include следующим образом? #include <filename> #include "filename"
c-preprocessor
include
header-files
22 авг. 2008, в 03:23
Наверх
Меню