Главная страница
Навигация по странице:

  • 1.1. Наша первая программа

  • 1.2.1. Константы Синтаксически константы в C++ представляют собой специальные перемен- ные с дополнительным атрибутом постоянства в C++.const

  • Литерал Тип 2int2u unsigned2l long2ul unsigned long2.0double2.0f float2.0l

  • Доступность

  • Не десятичные числа

  • Основы C Моим детям. Никогда не смейтесь, помогая мне осваивать


    Скачать 1.68 Mb.
    НазваниеОсновы C Моим детям. Никогда не смейтесь, помогая мне осваивать
    Дата12.10.2022
    Размер1.68 Mb.
    Формат файлаpdf
    Имя файлаsovremennyy-cpp-piter.pdf
    ТипГлава
    #729589
    страница1 из 9
      1   2   3   4   5   6   7   8   9

    Глава 1
    Основы C++
    Моим детям
    . Никогда не смейтесь, помогая мне осваивать
    компьютер. В конце концов, я учила вас пользоваться горшком.
    — Сью Фитцморис
    В этой главе мы рассмотрим основные возможности C++. Как и во всей книге, мы будем рассматривать их с разных точек зрения, но постараемся не вдавать- ся во все детали, ведь это все равно невозможно. Для более подробной инфор- мации о конкретных возможностях языка мы рекомендуем вам обратиться к онлайн-руководствам по адресам http://www.cplusplus.com/ и http://ru. cppreference.com.
    1.1. Наша первая программа
    В качестве введения в язык программирования C++ рассмотрим следующий пример:
    #include int main()
    { std::cout << "Ответом на Великий Вопрос о Жизни,\n"
    << "Вселенной и Всяком Таком является:"
    << std::endl << 6 * 7 << std::endl; return 0;
    }
    Вывод этой программы, в полном соответствии с Дугласом Адамсом (Douglas
    Adams) [2], имеет вид:
    Ответом на Великий Вопрос о Жизни,
    Вселенной и Всяком Таком является:
    42
    Этот короткий пример иллюстрирует несколько возможностей C++.
    Ввод и вывод не являются частью ядра языка и предоставляются библио-

    текой. Она должна быть включена явно; в противном случае мы ничего не сможем вводить и выводить.
    02_ch01.indd 25 14.07.2016 10:46:03

    Основы C++
    26
    Стандартный ввод-вывод имеет потоковую модель и потому именуется

    . Для обеспечения ее функциональности мы в первой строке программы указываем директиву ее включения
    #include .
    Каждая программа C++ начинается с вызова функции

    main. Она возвра- щает с помощью оператора return целочисленное значение; возврат нуля означает успешное завершение.
    Фигурные скобки

    {} означают блок/группу кода (именуемую также состав- ной инструкцией).
    std::cout

    и std::endl определены в . Первое из этих выра- жений представляет собой выходной поток, который выводит текст на эк- ран. std::endl завершает строку. Мы можем также переходить на новую строку с помощью специального символа
    \n.
    Оператор

    << можно использовать для передачи объекта в выходной поток, такой как std::cout, для выполнения операции вывода.
    std::

    указывает, что использованный тип (или функция) взят из стандар- тного пространства имен. Пространства имен помогают организовывать имена и избегать конфликтов имен (см. раздел 3.2.1).
    Строковые константы (более точно — литералы) заключены в двойные ка-

    вычки.
    Выражение

    6*7 вычисляется и передается в std::cout как целочисленное значение. В C++ каждое выражение имеет тип. Иногда мы как программис- ты обязаны явно объявлять тип, а в других случаях компилятор сам выво- дит его для нас. 6 и 7 являются константными литералами типа int, так что их произведение также представляет собой int.
    Прежде чем продолжить чтение, мы настоятельно рекомендуем вам скомпи- лировать и запустить этот маленький пример на своем компьютере. После того как он будет скомпилирован и запущен, вы сможете немного с ним поиграться, например, добавляя больше арифметических операций и операций вывода (и рас- смотреть получаемые сообщения об ошибках). В конце концов, единственным способом действительно выучить язык является его использование. Если вы уже знаете, как использовать компилятор или даже интегрированную среду разработ- ки C++, можете пропустить оставшуюся часть этого раздела.
    Linux. В каждом дистрибутиве имеется как минимум компилятор GNU C++, обычно устанавливаемый по умолчанию (см. краткое введение в разделе Б.1).
    Пусть мы назвали нашу программу hello42.cpp; тогда ее легко скомпилировать с помощью команды g++ hello42.cpp
    По традиции прошедшего века по умолчанию результирующий бинарный файл называется a.out. Но поскольку программ у нас может быть больше, чем
    02_ch01.indd 26 14.07.2016 10:46:03

    1.1. Наша первая программа
    27
    одна, давайте используем более значимое имя, указав соответствующий флаг в командной строке:
    g++ hello42.cpp -o hello42
    Можно также воспользоваться инструментом make (рассматривается в разде- ле 7.2.2.1), который (в своих последних версиях) предоставляет правила построе- ния бинарных файлов по умолчанию. Так что мы можем просто вызвать его ко- мандой make hello42
    После этого инструмент make выполнит поиск в текущем каталоге исходного файла программы с данным именем. Он найдет hello42.cpp, а так как .cpp яв- ляется стандартным расширением файлов с исходными текстами C++, будет вы- зван системный компилятор C++ по умолчанию. После компиляции программы мы можем вызвать ее из командной строки как
    ./hello42
    Наш бинарный файл может выполняться без привлечения какого-либо ино- го программного обеспечения и может быть скопирован в любую совместимую
    Linux-систему
    1
    и выполнен в ней.
    Windows. Если вы работаете с MinGW, можете компилировать программу точ- но так же, как и в Linux. Если вы используете Visual Studio, то сначала создайте проект
    2
    . Для начинающего простейший путь заключается в использовании шаб- лона проекта для консольного приложения, как описано, например, по адресу http://www.cplusplus.com/doc/tutorial/introduction/visualstudio.
    При запуске такой программы у вас будет буквально несколько миллисекунд, что- бы успеть прочесть ее вывод до того, как консольное окно закроется. Чтобы уве- личить это время до секунды, можно просто добавить непереносимую команду
    Sleep(1000); и включить заголовочный файл . При использова- нии C++11 или более поздней версии ожидание можно реализовать переносимо после включения заголовочных файлов
    и :
    std::this_thread::sleep_for(std::chrono::seconds(1));
    Microsoft предлагает бесплатные версии Visual Studio, называемые “Express”, которые обеспечивают поддержку стандарта языка программирования, как и их профессиональные аналоги. Разница заключается в наличии у профессиональных выпусков большего количества библиотек и возможностей. Поскольку в этой кни- ге они не используются, вы можете смело использовать для компиляции приме- ров версию “Express”.
    1
    Зачастую стандартная библиотека компонуется динамически (см. раздел 7.2.1.4), и тогда частью требований совместимости становится наличие той же ее версии на другой системе.
    2
    Вообще говоря, это не обязательно, так как Visual Studio, помимо интегрированной среды раз- работки, предоставляет инструментарий командной строки. — Примеч. ред.
    02_ch01.indd 27 14.07.2016 10:46:04

    Основы C++
    28
    Интегрированная среда разработки. Короткие программы наподобие при- меров из этой книги легко набрать в обычном редакторе. Большие проекты луч- ше создавать с использованием интегрированных сред разработки (Integrated
    Development Environment — IDE), которые позволяют увидеть, где определяется или используется функция, просмотреть документацию, найти или заменить име- на во всем проекте и т.д. Такой бесплатной интегрированной средой разработки является KDevelop от KDE, написанная на C++. Это, вероятно, наиболее эффек- тивная интегрированная среда разработки в Linux, хорошо интегрированная с git и CMake. Eclipse разработана на Java и существенно более медленная. Однако в последнее время было вложено много усилий в ее поддержку C++, так что мно- гим разработчикам она нравится и они достаточно продуктивно с ней работают.
    Visual Studio — это очень солидная интегрированная среда разработки с некото- рыми уникальными возможностями.
    Чтобы найти наиболее продуктивную и подходящую для себя интегрирован- ную среду разработки, нужно потратить некоторое время на проведение экспери- ментов; конечно же, огромную роль будут играть ваши личные предпочтения и вкусы.
    1.2. Переменные
    C++ является строго типизированным языком программирования (в отличие от множества языков сценариев). Это означает, что каждая переменная имеет тип, и этот тип никогда не изменяется. Переменная объявляется с помощью инструк- ции, начинающейся с типа, за которым следует имя переменной с необязательной инициализацией (или список таких переменных):
    int i1 = 2; // Выравнивание нужно только для удобочитаемости int i2, i3= 5; float pi = 3.14159; double x = -1.5 e6; // -1500000 double y = -1.5e-6; // -0.0000015 char c1 = 'a', c2= 35; bool cmp = i1 < pi, // -> true
    happy = true;
    Две косые черты
    // указывают начало однострочного комментария, т.е. все начиная от этих двух символов и до конца строки компилятором игнорируется.
    В принципе, это все, что надо знать о комментариях. Чтобы у вас не было ощу- щения, что мы пропустили что-то важное по этой теме, рассмотрим их немного подробнее в разделе 1.9.1.
    Вернемся к переменным. Их основные типы — именуемые также встроенными
    типами
    — перечислены в табл. 1.1.
    02_ch01.indd 28 14.07.2016 10:46:04

    1.2. Переменные
    29
    Таблица 1.1. Встроенные типы
    Имя
    Семантика
    char
    Буквы и очень небольшие целочисленные значения short
    Короткое целое число int
    Обычное целое число long
    Длинное целое число long long
    Очень длинное целое число unsigned
    Беззнаковая версия перечисленных значений signed
    Знаковая версия перечисленных значений float
    Число с плавающей точкой одинарной точности double
    Число с плавающей точкой двойной точности long double
    Длинное число с плавающей точкой bool
    Логическое значение
    Первые пять типов представляют собой целые числа неуменьшающейся дли- ны. Например, int имеет длину, не меньшую, чем длина short, т.е. обычно (но не обязательно) оно длиннее. Точная длина каждого типа зависит от реализации; например, тип int может быть длиной 16, 32 или 64 бита. Все эти типы могут быть знаковыми (
    signed) или беззнаковыми (unsigned). Первый квалификатор не оказывает никакого влияния на целые числа (за исключением char), поскольку они являются знаковыми по умолчанию.
    Объявляя целочисленный тип как unsigned, мы не разрешаем ему принимать отрицательные значения, зато вдвое увеличиваем диапазон допустимых положи- тельных значений (плюс одно, если нуль рассматривается ни как отрицательное, ни как положительное число). Слова signed и unsigned можно рассматривать как прилагательные для существительных short, int и других, где int — сущес- твительное, применяемое по умолчанию, когда имеются только прилагательные.
    Тип char может быть использован двумя способами — для букв и для очень коротких чисел. За исключением действительно экзотических архитектур, он поч- ти всегда имеет длину 8 битов. Таким образом, он может представлять значения либо от
    -128 до 127 (signed), либо от 0 до 255 (unsigned), и над ним можно выполнять все числовые операции, доступные для целых чисел. Если не указан ни квалификатор signed, ни unsigned, то, какой из них используется по умолча- нию, зависит от реализации. Мы можем также представить любую букву, код ко- торой помещается в 8 битов. Их можно даже смешивать, например 'a'+7 обычно дает 'h' (в зависимости от используемой кодировки букв). Мы настойчиво реко- мендуем не прибегать к таким способам, поскольку возможная путаница, скорее всего, приведет к напрасной трате времени.
    Применение char или unsigned char для небольших чисел может быть по- лезным при наличии больших контейнеров с ними.
    Логические значения лучше всего представимы с помощью типа bool. Такая переменная может хранить значение true или false. Свойство неуменьшающей- ся длины применимо и к числам с плавающей точкой:
    02_ch01.indd 29 14.07.2016 10:46:05

    Основы C++
    30
    Тип float короче или той же длины, что и тип double, который, в свою оче- редь, короче или той же длины, что и тип long double. Типичными размера- ми являются 32 бита для float, 64 бита — для double и 80 битов — для long double.
    В следующем разделе мы познакомимся с операциями, применимыми к цело- численным типам и типам с плавающей точкой. В отличие от других языков про- граммирования, таких как Python, в которых кавычки ' и " используются и для символов, и для строк, C++ их различает. Компилятор C++ рассматривает 'a' как символ “a” (с типом char), а "a" — как строку, содержащую символ “a” и би- нарный нуль в качестве завершающего символа (т.е. типом этой строки является char[2]). Если вы работали ранее с Python, обратите на это особое внимание.
    Совет
    Объявляйте переменные как можно позже, обычно непосредственно перед их пер- вым применением, и, насколько это возможно, не ранее чем вы сможете их ини- циализировать.
    Этот совет делает большие программы более удобочитаемыми. Кроме того, это позволяет компилятору более эффективно использовать память при наличии вло- женных областей видимости.
    C++11 в состоянии вывести тип переменной, например:
    auto i4= i3 + 7;
    Тип i4 тот же, что и у i3+7, т.е. int. Хотя тип определен автоматически, он остается неизменным, так что все, что впоследствии будет присвоено переменной i4, будет преобразовано в int. Позже мы увидим, насколько в современном про- граммировании полезно ключевое слово auto. В простых объявлениях перемен- ных, наподобие приводимых в этом разделе, обычно лучше объявлять тип явно.
    Применение auto подробно рассматривается в разделе 3.4.
    1.2.1. Константы
    Синтаксически константы в C++ представляют собой специальные перемен- ные с дополнительным атрибутом постоянства в C++.
    const int ci1 = 2;
    const int ci3; // Ошибка: не указано значение
    const float pi = 3.14159;
    const char cc = 'a';
    const bool cmp = ci1 < pi;
    Поскольку они не могут быть изменены, обязательным является установка их зна- чений в объявлении. Второе объявление константы нарушает данное правило, и компилятор не простит вам такой проступок.
    Константы могут использоваться везде, где разрешено применение перемен- ных, — конечно, до тех пор, пока они не изменяются. С другой стороны, кон-
    02_ch01.indd 30 14.07.2016 10:46:05

    1.2. Переменные
    31
    станты, как показанные выше, известны уже во время компиляции. Это позволяет компилятору применять множество видов оптимизации, так что константы могут даже использоваться в качестве аргументов типов (мы вернемся к этому позже, в разделе 5.1.4).
    1.2.2. Литералы
    Литералы, такие как
    2 или 3.14, точно типизированы. Проще говоря, цело- численные значения рассматриваются как имеющие тип int, long или unsigned long — в зависимости от количества цифр. Любое число с точкой или показате- лем степени (например,
    3e12 ≡ 3 · 10 12
    ) считается значением типа double.
    Литералы других типов могут быть записаны путем добавления суффикса из следующей таблицы.
    Литерал
    Тип
    2
    int
    2u
    unsigned
    2l
    long
    2ul
    unsigned long
    2.0
    double
    2.0f
    float
    2.0l
    long double
    В большинстве случаев нет необходимости явно объявлять тип литералов, так как неявное преобразование между встроенными числовыми типами обычно дает значения, ожидаемые программистом.
    Однако есть три основные причины, по которым необходимо уделять внима- ние типам литералов.
    Доступность. Стандартная библиотека предоставляет тип для комплексных чисел, в котором типы действительной и мнимой частей могут быть параметризо- ваны пользователем:
    std::complex z(1.3,2.4), z2;
    К сожалению, предоставляются только операции между самим типом комплекс- ного числа и базовым типом (аргументы в данном случае не преобразуются)
    3
    В результате мы не можем умножить z на int или double, а только на float:
    z2 = 2 * z; // Ошибка: нет int * complex z2 = 2.0 * z; // Ошибка: нет double * complex z2 = 2.0f * z; // Все в порядке, float * complex
    Неоднозначность. При перегрузке функции для других типов аргументов (раз- дел 1.5.4) аргумент наподобие
    0 может оказаться неоднозначным, в то время как для квалифицированного аргумента наподобие
    0u может иметься единственное соответствие.
    3
    Но такая смешанная арифметика может быть реализована, как показано в [18].
    02_ch01.indd 31 14.07.2016 10:46:05

    Основы C++
    32
    Точность. Вопрос точности встает, когда мы работаем с типом long double.
    Поскольку неквалифицированный литерал имеет тип double, возможна потеря значащих цифр до присваивания переменной типа long double:
    long double third1 = 0.3333333333333333333, // Возможна потеря точности third2 = 0.3333333333333333333l; // Точно
    Если вам кажется, что в предыдущих трех абзацах мы были слишком кратки- ми, примите к сведению, что более подробное изложение представлено в разде- ле А.2.1.
    Не десятичные числа. Целочисленные литералы, начинающиеся с нуля, трак- туются как восьмеричные числа, например:
    int o1= 042; // int o1= 34; int o2= 084; // Ошибка: ни 8, ни 9 не являются восьмеричными цифрами!
    Шестнадцатеричные литералы записываются с использованием префикса
    0x или
    0X:
    int h1= 0x42; // int h1= 66; int h2= 0xfa; // int h2= 250;
    В C++14 появились бинарные литералы, которые записываются с использова- нием префикса
    0b или 0B:
    int b1= 0b11111010; // int b1= 250;
    Для повышения удобочитаемости длинных литералов C++14 допускает разде- ление цифр апострофами:
    long d = 6'546'687'616'861'129l; unsigned long ulx = 0x139'ae3b'2ab0'94f3; int b = 0b101'1001'0011'1010'1101'1010'0001; const long double pi = 3.141'592'653'589'793'238'462l;
    Строковые литералы имеют тип массива символов char:
    char s1[]= "Старый стиль C"; // Лучше так не делать
    Однако куда удобнее работать со строками типа string из библиотеки
    . Такая строка может быть легко создана из строкового литерала:
    #include
    std::string s2= "В C++ лучше делать так";
    Очень длинный текст можно разбить на несколько подстрок:
    std::string s3= "Это очень длинный текст, который"
    " не помещается в одну строку";
    Более подробную информацию о литералах можно найти, например, в [43, §6.2].
    02_ch01.indd 32 14.07.2016 10:46:06

    1.2. Переменные
      1   2   3   4   5   6   7   8   9


    написать администратору сайта