Существуют следующие арифметические операторы, поддерживаемые языком C ++:
Реляционные операторы
Существуют следующие реляционные операторы, поддерживаемые языком C ++:
Оператор
Описание
Пример
==
Проверяет, равны ли значения двух операндов или нет, если да, то условие становится истинным.
(A == B) не соответствует действительности.
знак равно
Проверяет, равны ли значения двух операндов или нет, если значения не равны, условие становится истинным.
(A! = B) истинно.
>
Проверяет, превышает ли значение левого операнда значение правого операнда, если да, тогда условие становится истинным.
(A> B) неверно.
=
Проверяет, превышает ли значение левого операнда значение правого операнда, если да, тогда условие становится истинным.
(A> = B) неверно.
>
Двоичный оператор правого сдвига. Значение левых операндов перемещается вправо на количество бит, заданных правым операндом.
A >> 2 даст 15, что составляет 0000 1111
Операторы присваивания
Существуют следующие операторы присваивания, поддерживаемые языком C ++:
Другие операторы
В следующей таблице перечислены некоторые другие операторы, поддерживаемые C ++:
Оператор
Описание
sizeof
Возвращает размер переменной. Например, sizeof (a), где ‘a’ является целым числом и будет возвращать 4.
Если Условие истинно, то оно возвращает значение X, иначе возвращает значение Y.
Используются для ссылки на отдельных членов классов, структур и союзов.
Преобразуют один тип данных в другой. Например, int (2.2000) вернет 2.
Возвращает адрес переменной. Например, & a; даст фактический адрес переменной.
Является указателем на переменную. Например * var; будет указывать на переменную var.
Приоритеты операторов в C ++
Например, x = 7 + 3 * 2; здесь x назначается 13, а не 20, потому что оператор * имеет более высокий приоритет, чем +, поэтому он сначала умножается на 3 * 2, а затем добавляется в 7.
Ключевые слова — это предварительно определенные зарезервированные идентификаторы, имеющие специальные значения. Их нельзя использовать в качестве идентификаторов в программе. Для Microsoft C++ зарезервированы следующие ключевые слова. Имена с начальными символами подчеркивания и именами, указанными для C++/CX и C++/CLI, являются расширениями Майкрософт.
Стандартные ключевые слова C++
__asm ключевое слово Майкрософт заменяет asm синтаксис C++. asm зарезервировано для совместимости с другими реализациями C++, но не реализовано. Используется __asm для встроенной сборки на целевых объектах x86. Microsoft C++ не поддерживает встроенную сборку для других целей.
Ключевые слова Microsoft C++
В C++ идентификаторы, содержащие два последовательных символа подчеркивания, зарезервированы для реализаций компилятора. Соглашение корпорации Майкрософт — перед ключевыми словами, зависящими от корпорации Майкрософт, с двойными символами подчеркивания. Эти слова невозможно использовать как имена идентификаторов.
Расширения Microsoft по умолчанию включены. Чтобы обеспечить полную переносимость программ, можно отключить расширения Майкрософт, указав /permissive- параметр или /Za ( Отключить расширения языка) во время компиляции. Эти параметры отключают некоторые ключевые слова, относящиеся к Microsoft.
Если расширения Microsoft включены, в программах можно использовать ключевые слова, специфические для систем Microsoft. Для совместимости со стандартом ANSI эти ключевые слова начинаются с двух символов подчеркивания. Для обеспечения обратной совместимости поддерживаются версии с одним подчеркиванием многих ключевых слов с двойным подчеркиванием. __cdecl Ключевое слово доступно без символа подчеркивания в начале.
__based Ключевое слово имеет ограниченное использование для целевых компиляций с 32-и 64-битным целевым объектом.
С момента своего создания C++ стал одним из наиболее широко используемых языков программирования в мире. Грамотно сконструированные программы на языках C++ быстры и эффективны. Он более гибок, чем другие языки: он может работать с самыми высокими уровнями абстракции, а также на низком аппаратном уровне. C++ предоставляет стандартные библиотеки с высоким уровнем оптимизации. Он обеспечивает доступ к аппаратным функциям низкого уровня, чтобы максимально увеличить скорость и сократить потребление памяти. С помощью C++ можно создавать широкий спектр приложений. Игры, драйверы устройств и высокопроизводительное научное программное обеспечение. Встраиваемые программы. Клиентские приложения Windows. Даже библиотеки и компиляторы для других языков программирования пишутся на C++.
Одно из начальных требований для C++ — обратная совместимость с языком C. В результате программы на C++ всегда можно писать в стиле C: с необработанными указателями, массивами, символьными строками с завершающим нулем и другими функциями. Это может обеспечить высокую производительность, но также может приводить к ошибкам и увеличению сложности. Эволюция C++ концентрируется на возможностях, которые значительно снижают необходимость использования идиом в стиле C. Старые средства программирования C все еще можно использовать там, где это необходимо, но в современном C++ они нужны все реже и реже. Современный код на C++ проще, безопаснее, элегантнее и так же быстр, как и раньше.
В следующих разделах приводятся общие сведения об основных возможностях современного C++. Если не указано иное, перечисленные здесь функции доступны в C++ 11 и более поздних версиях. В компиляторе C++ от Майкрософт с помощью параметра /std можно указать версию стандарта, используемую для проекта.
Ресурсы и интеллектуальные указатели
При выделении памяти кучи всегда, когда это возможно, используйте интеллектуальные указатели. Если необходимо явно использовать операторы new и delete, следуйте принципу RAII. Дополнительные сведения см. в разделе Управление временем жизни и ресурсами объекта (RAII).
std::string и std::string_view
std::vector и другие контейнеры стандартной библиотеки
Все контейнеры стандартной библиотеки следуют принципу RAII. Они предоставляют итераторы для безопасного обхода элементов. И они хорошо оптимизированы для повышения производительности, а также тщательно протестированы на отсутствие ошибок. Используя эти контейнеры, можно исключить потенциальные ошибки и неэффективные приемы в пользовательских структурах данных. Вместо необработанных массивов используйте vector в качестве последовательного контейнера в C++.
При необходимости оптимизации производительности рассмотрите возможность использования следующих средств.
Тип array важен при внедрении, например, как член класса.
Алгоритмы стандартной библиотеки
Перед принятием решения о том, что вам нужно написать собственный алгоритм для программы, сначала ознакомьтесь с алгоритмами стандартной библиотеки C++. Стандартная библиотека содержит постоянно увеличивающийся набор различных алгоритмов для многих распространенных операций, таких как поиск, сортировка, фильтрация и рандомизация. Имеется обширная математическая библиотека. Начиная с C++ 17 предоставляются параллельные версии многих алгоритмов.
Ниже приведены некоторые важные примеры.
При написании операторов сравнения по возможности используйте строгие выражения и именованные лямбда-выражения.
auto вместо явных имен типов
В C++ 11 введено ключевое слово auto для использования в объявлениях переменных, функций и шаблонов. Ключевое слово auto предписывает компилятору определить тип объекта, чтобы не указывать его явным образом. auto особенно полезно, когда выводимый тип является вложенным шаблоном.
Циклы for на основе диапазона
Итерации в стиле C для массивов и контейнеров подвержены ошибкам индексирования, а также достаточно рутинные. Чтобы устранить эти ошибки и сделать код более удобочитаемым, используйте с контейнерами стандартной библиотеки и необработанными массивами циклы for на основе диапазона. Дополнительные сведения см. в разделе Оператор for на основе диапазона.
Выражения constexpr вместо макросов
Макросы в языках C и C++ являются токенами, которые обрабатываются препроцессором перед компиляцией. Перед компиляцией файла каждый экземпляр токена макроса заменяется определенным значением или выражением. Макросы обычно используются в программировании в стиле C для определения значений констант времени компиляции. Однако макросы подвержены ошибкам и их сложно отлаживать. В современном C++ следует отдавать предпочтение переменным constexpr для констант времени компиляции.
Унифицированная инициализация
Дополнительные сведения см. в разделе Инициализация фигурными скобками.
Семантика перемещения
Современный C++ предоставляет семантику перемещения, что позволяет устранять ненужное копирование памяти. В предыдущих версиях языка в определенных ситуациях копирования нельзя было избежать. Операция перемещения передает владение ресурсом от одного объекта к другому без создания копии. Некоторые классы владеют такими ресурсами, как память кучи, дескрипторы файлов и т. д. При реализации класса, владеющего ресурсами, можно определить для него конструктор перемещения и оператор присваивания перемещения. Компилятор выбирает эти специальные члены класса при разрешении перегрузки в ситуациях, когда копирование не требуется. Типы контейнеров стандартной библиотеки вызывают для объектов конструктор перемещения, если он определен. Дополнительные сведения см. в разделе Конструкторы перемещения и операторы присваивания перемещения (C++).
Лямбда-выражения
Лямбда-выражение [=](int i) < return i >x && i можно прочитать как «функция, которая принимает один аргумент типа int и возвращает логическое значение, указывающее, является ли аргумент больше x и меньше y «. Обратите внимание, что переменные x и y из окружающего контекста можно использовать в лямбда-выражении. [=] указывает, что эти переменные записываются по значению, то есть лямбда-выражение имеет собственные копии этих значений.
Исключения
В современном C++ в качестве способа сообщить об ошибках и обработать их состояние отдается предпочтение исключениям, а не кодам ошибок. Дополнительные сведения см. в разделе Современный подход к обработке исключений и ошибок в C++.
std::atomic
Используйте структуру и связанные типы std::atomic стандартной библиотеки C++ для механизмов взаимодействия между потоками.
std::variant (C++17)
Объединения обычно используются в программировании в стиле C для экономии памяти, позволяя членам разных типов занимать одно и то же расположение в памяти. Однако объединения не являются типобезопасными и могут быть подвержены ошибкам программирования. В C++ 17 появился класс std::variant в качестве более надежной и безопасной альтернативы объединениям. Функция std::visit может использоваться для доступа к членам типа variant типобезопасным способом.
Оператор префикса декремента ( — ) аналогичен оператору префикса инкремента, за исключением того, что операнд уменьшается на единицу, а результатом является это уменьшенное значение.
Операторы префиксных и постфиксных инкремента и декремента влияют на свои операнды. Они различаются между собой порядком выполнения инкремента или декремента при вычислении выражения (Дополнительные сведения см. в разделе Постфиксные операторы инкремента и декремента.) В форме префикса приращение или уменьшение происходит до того, как значение используется при вычислении выражения, поэтому значение выражения отличается от значения операнда. В постфиксной форме инкремент или декремент выполняется после использования значения при вычислении выражения, поэтому значение выражения совпадает со значением операнда. Например, в следующей программе выполняется вывод на печать » ++i = 6 «.
Операнд целочисленного типа или типа с плавающей запятой инкрементируется или декрементируется на целое значение 1. Тип результата совпадает с типом операнда. Операнд типа указателя инкрементируется или декрементируется на значение размера объекта, к которому он относится. Инкрементированный указатель указывает на следующий объект, а декрементированный — на предыдущий.
Поскольку операторы инкремента и декремента имеют побочные эффекты, использование выражений с операторами инкремента или декремента в макросе препроцессора может иметь нежелательные результаты. Рассмотрим следующий пример.
Макрос разворачивается до следующего выражения:
Если значение i больше или равно j или меньше j на 1, оно будет инкрементировано дважды.
Встраиваемые функции C++ предпочтительнее макросов во многих случаях, поскольку исключают побочные эффекты, подобные описанным здесь, и позволяют языку выполнять более полную проверку типов.
Переменная: символическое имя количества данных, чтобы имя можно было использовать для доступа к данным, на которые он ссылается в области кода, где он определен. В C++ переменная обычно используется для ссылки на экземпляры скалярных типов данных, тогда как экземпляры других типов обычно называются объектами.
Объект. для простоты и согласованности в этой статье используется объект term для ссылки на любой экземпляр класса или структуры, и когда он используется в общем смысле, включает все типы, даже скалярные переменные.
Тип POD (обычные старые данные): Эта неофициальная Категория типов данных в C++ относится к скалярным типам (см. раздел фундаментальные типы) или к классам Pod. Класс POD не содержит статических данных-членов, которые не являются типами POD, а также не содержит пользовательских конструкторов, пользовательских деструкторов или пользовательских операторов присваивания. Кроме того, класс POD не имеет виртуальных функций, базового класса и ни закрытых, ни защищенных нестатических данных-членов. Типы POD часто используются для внешнего обмена данными, например с модулем, написанным на языке С (в котором имеются только типы POD).
Указание типов переменных и функций
C++ — это строго типизированный язык, который также является статически типизированным; Каждый объект имеет тип, и этот тип никогда не изменяется (не следует путать с статическими объектами данных). При объявлении переменной в коде необходимо либо явно указать ее тип, либо использовать auto ключевое слово, чтобы указать компилятору вывести тип из инициализатора. При объявлении функции в коде необходимо указать тип каждого аргумента и его возвращаемое значение или void значение, если функция не возвращает никакого значения. Исключением является использование шаблонов функции, которые допускают аргументы произвольных типов.
После объявления переменной изменить ее тип впоследствии уже невозможно. Однако можно скопировать значения переменной или возвращаемое значение функции в другую переменную другого типа. Такие операции называются преобразованиями типов, которые иногда являются обязательными, но также являются потенциальными источниками потери или неправильности данных.
При объявлении переменной типа POD настоятельно рекомендуется инициализировать ее, т. е. указать начальное значение. Пока переменная не инициализирована, она имеет «мусорное» значение, определяемое значениями битов, которые ранее были установлены в этом месте памяти. Необходимо учитывать эту особенность языка C++, особенно при переходе с другого языка, который обрабатывает инициализацию автоматически. При объявлении переменной типа, не являющегося классом POD, инициализация обрабатывается конструктором.
В следующем примере показано несколько простых объявлений переменных с небольшим описанием для каждого объявления. В примере также показано, как компилятор использует сведения о типе, чтобы разрешить или запретить некоторые последующие операции с переменной.
Базовые (встроенные) типы
Базовые типы распознаются компилятором, в котором предусмотрены встроенные правила, управляющие операциями, выполняемыми с такими типами, а также преобразованием в другие базовые типы. Полный список встроенных типов, а также их размер и числовые ограничения см. в разделе Встроенные типы.
На следующем рисунке показаны относительные размеры встроенных типов в реализации Microsoft C++:
В следующей таблице перечислены наиболее часто используемые фундаментальные типы и их размеры в реализации Microsoft C++:
Другие реализации C++ могут использовать разные размеры для определенных числовых типов. Дополнительные сведения о размерах и отношениях размеров, необходимых стандарту C++, см. в разделе Встроенные типы.
Тип void
Квалификатор типа const
Любой встроенный или пользовательский тип может квалифицироваться ключевым словом const. Кроме того, функции-члены могут быть const полными и даже const перегруженными. Значение const типа не может быть изменено после инициализации.
Строковые типы
Определяемые пользователем типы
Компилятор не имеет встроенных сведений о пользовательском типе. Он узнает о типе при первом обнаружении определения во время процесса компиляции.
типы указателей
Датировано назад к самой ранней версии языка C, C++ позволяет объявить переменную типа указателя с помощью специального декларатора * (звездочка). Тип указателя хранит адрес расположения в памяти, в котором хранится фактическое значение данных. В современных C++ они называются необработанными указателями и доступны в коде с помощью специальных операторов * (звездочки) или -> (тире с символом «больше»). Это называется разыменованием, и какой из используемых объектов зависит от того, выполняется ли разыменование указателя на скаляр или указатель на член в объекте. Работа с типами указателя долгое время была одним из наиболее трудных и непонятных аспектов разработки программ на языках C и C++. В этом разделе приводятся некоторые факты и рекомендации по использованию необработанных указателей, если вы хотите, но в современной версии C++ больше не требуется (или рекомендуется) использовать необработанные указатели для владения объектами, так как при развитии интеллектуального указателя (см. Дополнительные сведения в конце этого раздела). Все еще полезно и безопасно использовать необработанные указатели для отслеживания объектов, но если требуется использовать их для владения объектом, необходимо делать это с осторожностью и после тщательного анализа процедуры создания и уничтожения объектов, которые им принадлежат.
Первое, что необходимо знать, — это то, что при объявлении переменной необработанного указателя выделяется только память, необходимая для хранения адреса расположения памяти, на который будет ссылаться указатель при разыменовывании. Выделение памяти для самого значения данных (также называемое резервным хранилищем) еще не выделено. Другими словами, объявив переменную необработанного указателя, вы создаете переменную адреса памяти, а не фактическую переменную данных. Разыменовывание переменной указателя до проверки того, что она содержит действительный адрес в резервном хранилище, приведет к неопределенному поведению (обычно неустранимой ошибке) программы. В следующем примере демонстрируется подобная ошибка:
Пример разыменовывает тип указателя без выделения памяти для хранения фактических целочисленных данных или без выделенного допустимого адреса памяти. В следующем коде исправлены эти ошибки:
Однако можно легко забыть удалить динамически выделенный объект, особенно в сложном коде, который вызывает ошибку ресурса, называемую утечкой памяти. По этой причине в современном С++ настоятельно не рекомендуется использовать необработанные указатели. Почти всегда лучше обернуть необработанный указатель в Интеллектуальный указатель, который автоматически освобождает память при вызове его деструктора (когда код выходит за пределы области для смарт-указателя); с помощью смарт-указателей вы практически устраняете целый класс ошибок в программах на C++. В следующем примере предположим, что MyClass — это пользовательский тип, который имеет открытый метод DoSomeWork();
Дополнительные сведения о смарт-указателях см. в разделе интеллектуальные указатели.
Дополнительные сведения о преобразовании указателей см. в разделе преобразования типов и типизация.
Дополнительные сведения об указателях в целом см. в разделе указатели.
Типы данных Windows
Дополнительные сведения
Дополнительные сведения о системе типов C++ см. в следующих разделах.
Преобразования типов и безопасность типов Описание типовых проблем преобразования типов и способов их избежать.