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

  • 3.4. Переменные и операции над ними в С++

  • Стандартные математические функции С++ Математическая запись функции Запись функции в TP | x | abs(x)

  • Приоритеты операций в выражениях

  • 3.5. Простейший ввод/вывод

  • 3.6. Указатели и ссылки

  • 3.7. Строковый тип данных

  • Функции обработки строковых данных

  • 3.8. Программирование развилок

  • В. Ю. Наумов Введение в информатику


    Скачать 2.05 Mb.
    НазваниеВ. Ю. Наумов Введение в информатику
    Анкорosnovy_prog С
    Дата13.02.2022
    Размер2.05 Mb.
    Формат файлаpdf
    Имя файлаosnovy_prog С++.pdf
    ТипДокументы
    #360392
    страница6 из 15
    1   2   3   4   5   6   7   8   9   ...   15

    Диапазоны типов данных
    Имя типа
    Байты Другие имена
    Диапазон значений int
    4 signed от -2 147 483 648 до 2 147 483 647 unsigned int
    4 unsigned
    От 0 до 4 294 967 295
    __int8 1 char от -128 до 127 unsigned __int8 1 unsigned char
    От 0 до 255
    __int16 2 short, short int, signed short int от -32 768 до 32 767 unsigned __int16 2 unsigned short, unsigned short int
    От 0 до 65 535
    __int32 4 signed, signed int, int от -2 147 483 648 до 2 147 483 647 unsigned __int32 4 unsigned, unsigned int
    От 0 до 4 294 967 295
    __int64 8 long long, signed long long
    -9 223 372 036 854 775 808 до
    9 223 372 036 854 775 807 unsigned __int64 8 unsigned long long
    От 0 до
    18 446 744 073 709 551 615 bool
    1
    NONE false или true char
    1
    NONE от -128 до 127 signed char
    1
    NONE от -128 до 127 unsigned char
    1
    NONE
    От 0 до 255 short
    2 short int, signed short int от -32 768 до 32 767 long
    4 long int, signed long int от -2 147 483 648 до 2 147 483 647 unsigned long
    4 unsigned long int
    От 0 до 4 294 967 295 long long
    8
    Нет
    (но эквивалентно
    __int64)
    -9 223 372 036 854 775 808 до
    9 223 372 036 854 775 807 unsigned long long
    8
    Нет
    (но эквивалентно unsigned__int64)
    От 0 до
    18 446 744 073 709 551 615 float
    4
    NONE
    3,4E +/- 38 (7 знаков) double
    8
    NONE
    1,7E +/- 308 (15 знаков) long double
    8
    NONE
    То же, что и для double wchar_t
    2
    __wchar_t
    От 0 до 65 535

    64
    В C++ различают явное и неявное преобразование типов данных.
    Неявное преобразование типов данных выполняет компилятор С++, а явное преобразование данных выполняет сам программист. Результат любого вычисления будет преобразовываться к наиболее точному типу данных, из тех типов данных, которые участвуют в вычислении.
    Например, если в выражении делится одно целое число на другое, то результат тоже будет целым (при этом вещественная часть числа будет отброшена), но если одно из исходных чисел будет вещественным, то и результат будет вещественным.
    Также компилятор будет работать и с переменными разных типов, т.е. если присвоить целочисленной переменной значение вещественной переменной, то будет присвоена только целая часть, произойдет неявное
    преобразование типов данных.
    Кроме неявного преобразования типов данных существует еще и явное. Cи-стиль приведения типов данных доступен и языке C++, но считается не самодостаточным по сравнению с приведением типов в C++.
    Так как Си-стиль приведения типов не так точен, как C++-стиль приведения и не так заметен. Cи-стиль приведения типов данных может быть использован для преобразования любого типа в любой другой тип, при этом неважно насколько это небезопасное преобразование, например, преобразование целого числа в указатель типа int). Для использования Си- стиля приведения достаточно перед именем переменной (variable) указать в круглых скобках необходимый тип (type):
    ()
    Операция static_cast доступна только в языке C++. static_cast может быть использована для преобразования одного типа в другой, но она не должна быть использована для выполнения недопустимого преобразования, например, преобразование значения в указатель или наоборот. Рекомендуется пользоваться операцией

    65 static_cast
    , нежели
    Cи-стилем приведения, потому что static_cast ограничивает недопустимое приведение типов и, следовательно — безопаснее. Операция static_cast, грубо говоря, — это шаблон функции, в которой необходимо явно указать тип данных для преобразования, то есть задать параметр шаблона. static_cast (value);
    Итак, в треугольных скобочках указывается тип данных, к которому необходимо преобразовать значение value, которое стоит в круглых скобочках.
    3.4. Переменные и операции над ними в С++
    Переменная в С++ – именованная область памяти, в которой хранятся данные определенного типа. У переменной есть имя и значение.
    Имя служит для обращения к области памяти, в которой хранится значение. Перед использованием любая переменная должна быть описана.
    Примеры: int a; float x;
    Общий вид оператора описания:
    [класс памяти][const]<тип> <имя> [инициализатор];
    Класс памяти может принимать значения: auto, extern, static, register
    . Класс памяти определяет время жизни и область видимости переменной. Если класс памяти не указан явно, то компилятор определяет его исходя из контекста объявления. Время жизни может быть постоянным – в течение выполнения программы или временным – в течение блока. Область видимости – часть текста программы, из которой допустим обычный доступ к переменной. Обычно область видимости совпадает с областью действия. Кроме того случая, когда во внутреннем блоке существует переменная с таким же именем.

    66
    Const – показывает, что эту переменную нельзя изменять
    (именованная константа).
    При описании можно присвоить переменной начальное значение
    (инициализация).
    Классы памяти: auto –автоматическая локальная переменная. Спецификатор auto может быть задан только при определении объектов блока, например, в теле функции. Этим переменным память выделяется при входе в блок и освобождается при выходе из него. Вне блока такие переменные не существуют. extern – глобальная переменная, она находится в другом месте программы (в другом файле или долее по тексту). Используется для создания переменных, которые достуны во всех файлах программы. static – статическая переменная, она существует только в пределах того файла, где определена переменная. register - аналогичны auto, но память под них выделяется в регистрах процессора. Если такой возможности нет, то переменные обрабатываются как auto.
    ПРИМЕР
    int a; //глобальная переменная int main()
    { int b;//локальная переменная extern int x;//переменная х определена
    //в другом месте static int c;//локальная статическая переменная a=1;//присваивание глобальной переменной int a;//локальная переменная а a=2;//присваивание локальной переменной
    ::a=3;//присваивание глобальной переменной
    } int x=4;//определение и инициализация х

    67
    В примере переменная а определена вне всех блоков. Областью действия переменной а является вся программа, кроме тех строк, где используется локальная переменная а. Переменные b и с – локальные, область их видимости – блок. Время жизни различно: память под b выделяется при входе в блок (т. к. по умолчанию класс памяти auto), освобождается при выходе из него. Переменная с (static) существует, пока работает программа.
    Если при определении начальное значение переменным не задается явным образом, то компилятор обнуляет глобальные и статические переменные. Автоматические переменные не инициализируются.
    Имя переменной должно быть уникальным в своей области действия.
    Описание переменной может быть выполнено или как объявление, или как определение. Объявление содержит информацию о классе памяти и типе переменной, определение вместе с этой информацией дает указание выделить память. В примере extern int x; - объявление, а остальные
    – определения.
    Знаки операций обеспечивают формирование выражений.
    Выражения состоят из операндов, знаков операций и скобок. Каждый операнд является, в свою очередь, выражением или частным случаем выражения – константой или переменной.
    Таблица 3.3
    Унарные операции
    & получение адреса операнда
    *
    Обращение по адресу (разыменование)
    - унарный минус, меняет знак арифметического операнда

    68
    Таблица 3.3. Продолжение

    поразрядное инвертирование внутреннего двоичного кода це- лочисленного операнда (побитовое отрицание)
    ! логическое отрицание (НЕ). В качестве логических значений используется 0 - ложь и не 0 - истина, отрицанием 0 будет 1, от- рицанием любого ненулевого числа будет 0.
    ++
    Увеличение на единицу префиксная операция - увеличивает операнд до его использования, постфиксная операция увеличивает операнд после его исполь- зования. int m=1,n=2; int a=(m++)+n; // a=4,m=2,n=2 int b=m+(++n); //a=3,m=1,n=3
    -- уменьшение на единицу: префиксная операция - уменьшает операнд до его использования, постфиксная операция уменьшает операнд после его исполь- зования. sizeof вычисление размера (в байтах) для объекта того типа, который имеет операнд sizeof (выражение) sizeof (тип)
    Примеры: sizeof (float) //4 sizeof (1.0) //8, т. к. вещественные константы по умолчанию имеют тип double

    69
    Таблица 3.4
    Бинарные операции
    + бинарный плюс (сложение арифметических операндов)
    - бинарный минус (вычитание арифметических операндов)
    * умножение операндов арифметического типа
    / деление операндов арифметического типа (если операнды целочис- ленные, то выполняется целочисленное деление)
    % получение остатка от деления целочисленных операндов
    <<
    Формат выражения с операцией сдвига: операнд_левый операция_сдвига операнд_правый сдвиг влево битового представления значения левого целочисленного операнда на количество разрядов, равное значению правого операнда, освободившиеся разряды обнуляются
    >> сдвиг вправо битового представления значения правого целочисленного операнда на количество разрядов, равное значению правого операнда, освободившиеся разряды обнуляются, если операнд беззнакового типа и заполняются знаковым разрядом, если – знакового
    & поразрядная конъюнкция (И) битовых представлений значений це- лочисленных операндов (бит =1, если соответствующие биты обоих опе- рандов=1)
    | поразрядная дизъюнкция (ИЛИ) битовых представлений значений целочисленных операндов (бит =1, если соответствующий бит одного из операндов=1)
    ^ поразрядное исключающее ИЛИ битовых представлений значений целочисленных операндов(бит =1, если соответствующий бит только од- ного из операндов=1)

    70
    Таблица 3.5
    Операции сравнения
    < меньше, чем
    > больше, чем
    <= меньше или равно
    >= больше или равно
    == равно
    != не равно
    && конъюнкция (И) целочисленных операндов или отношений, цело- численный результат ложь(0) или истина(не 0)
    || дизъюнкция (ИЛИ) целочисленных операндов или отношений, це- лочисленный результат ложь(0) или истина(не 0)
    Кроме перечисленных, в С++ определены следующие операции присваивания:
    =, +=, -=, *=, /=
    Формат операции простого присваивания:
    <операнд1>=<операнд2>
    Леводопустимое значение – выражение, которое адресует некоторый участок памяти, т. е. в него можно занести значение. Это название произошло от операции присваивания, т. к. именно левая часть операции присваивания определяет, в какую область памяти будет занесен результат операции. Переменная – это частный случай леводопустимого выражения.
    Составные операции присваивания используются тогда, когда необходимо модифицировать исходное значение переменной.
    Стандартные математические функции языка C++ можно описать в виде таблицы (табл. 3.6), для их использования необходимо подключать библиотеку или для Microsoft Visual Studio (MVS) .

    71
    Таблица 3.6
    Стандартные математические функции С++
    Математическая запись функции
    Запись функции в TP
    |x|
    abs(x)
    e
    x
    exp(x)
    cos x
    cos(x)
    sin x
    sin(x)
    tan x
    tan (x)
    arcsin x
    asin(x)
    arcos x
    acos(x)
    ln x
    log(x)
    lg x
    log10(x)
    x
    sqrt(x)
    x
    y
    pow(x,y)
    π
    M_Pi
    округление а до наименьшего целого, но не меньше чем а
    ceil( a )
    округление а до наибольшего целого, но не больше чем а
    floor(a)
    При использовании этих функций результат получается типа float.
    Но есть и исключение. При вычислении abs(x) результат получается int, поэтому для получения абсолютного значения вещественного числа нужно использовать fabs(x)
    Все тригонометрические вычисления производятся в радианах.
    Кроме того, здесь представлены не все известные функции. Чтобы увидеть полный перечень функций в данном заголовочном файле, просто откройте его. Сделать это можно либо через поиск, либо через обозреватель решений, если программируете в MVS.
    Из констант, переменных, разделителей и знаков операций можно конструировать выражения. Каждое выражение представляет собой правило вычисления нового значения. Если выражение формирует целое или вещественное число, то оно называется арифметическим. Пара арифметических выражений, объединенная операцией сравнения,

    72 называется отношением. Если отношение имеет ненулевое значение, то оно – истинно, иначе – ложно.
    Таблица 3.7
    Приоритеты операций в выражениях
    Ранг
    Операции
    1
    ( ) [ ] -> .
    2
    ! - ++ -- & * (тип) sizeof тип( )
    3
    * / % (мультипликативные бинарные)
    + - (аддитивные бинарные)
    5
    << >> (поразрядного сдвига)
    6
    < > <= >= (отношения)
    7
    == != (отношения)
    8
    & (поразрядная конъюнкция «И»)
    9
    ^ (поразрядное исключающее «ИЛИ»)
    10
    | (поразрядная дизъюнкция «ИЛИ»)
    11
    && (конъюнкция «И»)
    12
    || (дизъюнкция «ИЛИ»)
    13
    ?: (условная операция)
    14
    = *= /= %= -= &= ^= |= <<= >>= (операция присваивания)
    15
    , (операция запятая)
    3.5. Простейший ввод/вывод
    Программа в процессе своей работы может взаимодействовать с пользователем. То есть она может запросить у него некоторую информацию, или, наоборот, предоставить ее ему. Общение с пользователем, впрочем, как и с любым другим устройством, происходит при помощи операций ввода/вывода. Если речь идет о выводе, то данные могут поступать на различные устройства (экран, принтер, файл, звуковая

    73 система). Наиболее распространенным устройством вывода при общении человека и ЭВМ является монитор. А устройством ввода – клавиатура.
    В языке Си++ нет встроенных средств ввода и вывода – он осуществляется с помощью функций, типов и объектов, которые находятся в стандартных библиотеках. Существует два основных способа вывода текстовой информации на экран в консольном
    14
    режиме: функции унаследованные из Си и объекты С++.
    Для ввода/вывода данных в стиле Си используются функции, которые описываются в библиотечном файле stdio.h.
    1) Оператор вывода: printf (<форматная строка>, <список аргументов>); форматная строка - строка символов, заключенных в кавычки, которая показывает, как должны быть напечатаны аргументы.
    ПРИМЕР
    printf (“Значение числа Пи равно %f\n”, pi);
    Форматная строка может содержать
    1) символы печатаемые текстуально;
    2) спецификации преобразования;
    3) управляющие символы.
    Каждому аргументу соответствует своя спецификация преобразования:
    %d, %i - десятичное целое число;
    %f - число с плавающей точкой;
    %e,%E – число с плавающей точкой в экспоненциальной форме;
    %u – десятичное число в беззнаковой форме;
    %c - символ;
    %s - строка.
    14
    Консольным чаще всего называют взаимодействие с пользователем посредством ввода/вывода текстовой информации (текстовый интерфейс).

    74
    В форматную строку также могут входить управляющие символы:
    \n - управляющий символ новая строка;
    \t – табуляция;
    \a – звуковой сигнал и др.
    Также в форматной строке могут использоваться модификаторы формата, которые управляют шириной поля, отводимого для размещения выводимого значения. Модификаторы – это числа, которые указывают минимальное количество позиций для вывода значения и количество позиций ля вывода дробной части числа:
    %[-]m[.p]C, где
    - задает выравнивание по левому краю,
    m – минимальная ширина поля,
    p – количество цифр после запятой для чисел с плавающей точкой и минимальное количество выводимых цифр для целых чисел (если цифр в числе меньше, чем значение р, то выводятся начальные нули),
    C- спецификация формата вывода.
    ПРИМЕР
    printf("\n %10.5d - целое,\n%10.5f - с плавающей точкой\ \n%10.5e – в экспоненциальной форме\n%10s - строка", 10, 10.0, 10.0, "10");
    Будет выведено:
    2) Оператор ввода: scanf (<форматная строка>, <список аргументов>);
    В качестве аргументов используются адреса переменных. Например: scanf(“%d%f ”, &x,&y);
    00010 – целое
    10.00000 – с плавающей точкой
    1.00000е+001 - в экспоненциальной форме
    10 – строка.

    75
    При использовании библиотеки классов Си++, используется библи- отечный файл iostream.h, в котором определены стандартные потоки ввода данных от клавиатуры cin и вывода данных на экран дисплея cout, а также соответствующие операции
    1)
    << - операция записи данных в поток;
    2)
    >> - операция чтения данных из потока.
    ПРИМЕР
    #include ; cout << “\nВведите количество элементов: ”; cin >> n;
    Таким образом, для ввода данных нужно использовать поток ввода данных cin и операцию чтения данных из потока >>, для вывода данных поток вывода на экран cout и операцию записи данных в поток <<. Для потоков ввода и вывода не надо указывать формат данных, т. к. библиотека iostream позволяет компилятору сделать это автоматически.
    Если вводится или выводится несколько объектов, каждый объект потока отделяется соответствующей операцией.
    ПРИМЕР
    cout << “\nx=”<>a>>b>>c;
    Приведем еще несколько примеров использования потоков ввода/вывода.
    Чтобы вывести некоторый текст, можно написать так:
    Cout<<”\ntext”;
    Содержимое экрана после выполнения этой операции: text

    76
    Как видно из примера, выводимый текст заключается в апострофы.
    Там же указываются управляющие символы, они теже, что и для Си-стиля.
    Если же требуется вывести значение некоторой переменной, то необходимо указать лишь ее имя. int x=5; cout<Содержимое экрана:
    Эти два способа вывода можно комбинировать так: cout<<”\nx=”<Содержимое экрана:
    Вообще, выводу подвергаются константы и переменные простых типов непосредственно. Для вывода сложных типов, таких как, например, массивы и записи, необходимо указывать конкретное поле вывода или адрес элемента в массиве. Вывод строк осуществляется непосредственно цельно.
    Для внесения ясности в процесс ввода данных нужно обязательно делать приглашение ко вводу, как правило, сообщая пользователю, какие данные ему необходимо ввести. Потому всегда, где в блок-схемах алгоритмов идет блок ввода, подразумевается в программе наличие как минимум пары стандартных процедур. Это, помимо, cin, еще и x=5 5

    77 предшествующий cout, выводящий комментарии к тому, что нужно ввести в данном месте. Пример записи процедуры:
    ПРИМЕР
    Ввести с клавиатуры значение аргумента и вычислить значение
    функции y = sin(x).
    #include
    #include int main()
    { float x,y; cout<<”\nInput x”; cin>>x; y=sin(x); cout<<”\ny=”<}
    Содержимое экрана:
    Символом

    обозначено место, в котором нажата клавиша Enter.
    3.6. Указатели и ссылки
    Указатели являются специальными объектами в программах на
    Си++. Указатели предназначены для хранения адресов памяти. Когда компилятор обрабатывает оператор определения переменной, например, int а=10;, то в памяти выделяется участок памяти в соответствии с типом переменной (int=> 4 байта) и записывается в этот участок указанное значение. Все обращения к этой переменной компилятор заменит на адрес области памяти, в которой хранится эта переменная. x= –2.36

    y= –0.70 10
    &a

    78
    Программист может определить собственные переменные для хранения адресов областей памяти. Такие переменные называются указателями. Указатель не является самостоятельным типом, он всегда связан с каким-то другим типом.
    Указатели делятся на две категории: указатели на объекты и указатели на функции. Рассмотрим указатели на объекты, которые хранят адрес области памяти, содержащей данные определенного типа.
    В простейшем случае объявление указателя имеет вид:
    <тип> *<имя>;
    Тип может быть любым, кроме ссылки.
    ПРИМЕР
    int *i; double *f, *ff; char *c;
    Размер указателя зависит от модели памяти. Можно определить указатель на указатель: int**a;
    Указатель может быть константой или переменной, а также указывать на константу или переменную.
    ПРИМЕР
    int i;
    //целая переменная const int ci=1;
    //целая константа int *pi; //указатель на целую переменную const int *pci;//указатель на целую константу
    //Указатель можно сразу проинициализировать: int *pi=&i;
    //указатель на целую переменную const int *pci=&ci;; //указатель на целую константу int*const cpi=&i; //указатель-константа
    //на целую переменную const int* const cpc=&ci;//указатель-константа
    //на целую константу
    Если модификатор const относится к указателю (т. е. находится между именем указателя и *), то он запрещает изменение указателя, а если он находится слева от типа (т. е. слева от *), то он запрещает изменение значения, на которое указывает указатель.

    79
    Для инициализации указателя существуют следующие способы:
    Присваивание адреса существующего объекта:
    1) с помощью операции получения адреса int a=5; int *p=&a; или int p(&a);
    2) с помощью проинициализированного указателя int *r=p;
    3) адрес присваивается в явном виде char*cp=(char*)0х В800 0000; где 0х В800 0000 – шестнадцатеричная константа, (char*) – операция приведения типа.
    4) присваивание пустого значения: int*N=NULL; int *R=0;
    Все переменные, объявленные в программе размещаются в одной непрерывной области памяти, которую называют сегментом данных. Такие переменные не меняют своего размера в ходе выполнения программы и называются статическими. Размера сегмента данных может быть недостаточно для размещения больших массивов информации. Выходом из этой ситуации является использование динамической памяти.
    Динамическая память – это память, выделяемая программе для ее работы за вычетом сегмента данных, стека, в котором размещаются локальные переменные подпрограмм и собственно тела программы.
    Для работы с динамической памятью используют указатели. С их помощью осуществляется доступ к участкам динамической памяти, которые называются динамическими переменными. Динамические переменные создаются с помощью специальных функций и операций. Они существуют либо до конца работы программ, либо до тех пор, пока не будут уничтожены с помощью специальных функций или операций.

    80
    Для создания динамических переменных используют операцию new, определенную в С++:
    <указатель> = new <имя_типа>(<инициализатор>);
    Операция new позволяет выделить и сделать доступным участок динамической памяти, который соответствует заданному типу данных.
    Если задан инициализатор, то в этот участок будет занесено значение, указанное в инициализаторе. int*x=new int(5);
    Для удаления динамических переменных используется операция delete
    , определенная в С++: delete <указатель>; где указатель содержит адрес участка памяти, ранее выделенный с помощью операции new. delete x;
    В языке Си определены библиотечные функции для работы с динамической памятью, они находятся в библиотеке :
    1) void*malloc(unsigned s) – возвращает указатель на начало области динамической памяти длиной s байт, при неудачном завершении возвращает NULL;
    2) void*calloc(unsigned n, unsigned m) – возвращает указатель на начало области динамической для размещения n элементов длиной m байт каждый, при неудачном завершении возвращает NULL;
    3) void*realloc(void
    *p,unsigned s)
    –изменяет размер блока ранее выделенной динамической до размера s байт, р – адрес начала изменяемого блока, при неудачном завершении возвращает NULL;
    4) void *free(void *p) – освобождает ранее выделенный участок динамической памяти, р - адрес начала участка.

    81
    ПРИМЕР
    int *u=(int*)malloc(sizeof(int));
    В функцию передается количество требуемой памяти в байтах, т. к. функция возвращает значение типа void*, то его необходимо преобразовать к типу указателя (int*). free(u); // освобождение выделенной памяти
    С указателями можно выполнять следующие операции:
    1) разыменование (*);
    2) присваивание;
    3) арифметические операции (сложение с константой, вычитание, инкремент ++, декремент --);
    4) сравнение;
    5) приведение типов.
    1) Операция разыменования предназначена для получения значения переменной или константы, адрес которой хранится в указателе. Если указатель указывает на переменную, то это значение можно изменять, также используя операцию разыменования.
    ПРИМЕР
    int a; //переменная типа int int*pa=new int; //указатель и выделение памяти
    // под динамическую переменную
    *pa=10; //присвоили значение динамической
    //переменной, на которую указывает указатель a=*pa; //присвоили значение переменной а
    Присваивать значение указателям-константам запрещено.
    2) Приведение типов
    На одну и ту же область памяти могут ссылаться указатели разного типа. Если применить к ним операцию разыменования, то получатся разные результаты. int a=123; int*pi=&a; char*pc=(char*)&a; float *pf=(float*)&a;

    82 printf("\n%x\t%i",pi,*pi); // 66fd9c 123 printf("\n%x\t%c",pc,*pc); // 66fd9c { printf("\n%x\t%f",pf,*pf); // 66fd9c 0.000000
    Т. е. адрес у трех указателей один и тот же, но при разыменовании получаются разные значения в зависимости от типа указателя.
    В примере при инициализации указателя была использована операция приведения типов. При использовании в выражении указателей разных типов, явное преобразование требуется для всех типов, кроме void*
    . Указатель может неявно преобразовываться в значения типа bool, при этом ненулевой указатель преобразуется в true, а нулевой в false.
    3) Арифметические операции применимы только к указателям одного типа.
    -
    Инкремент увеличивает значение указателя на величину sizeof(тип).
    ПРИМЕР
    char *pc; int *pi; float *pf; pc++;//значение увеличится на 1 pi++;//значение увеличится на 4 pf++;//значение увеличится на 4
    -
    Декремент уменьшает значение указателя на величину sizeof(тип).
    -
    Разность двух указателей – это разность их значений, деленная на размер типа в байтах.
    ПРИМЕР
    int a=123,b=456,c=789; int*pi1=&a; int *pi2=&b; int*pi3=&c; printf("\n%x",pi1-pi2); //1 printf("\n%x",pi1-pi3); //2
    Суммирование двух указателей не допускается.

    83
    Можно суммировать указатель и константу: pi3=pi3+2; pi2=pi2+1; printf("\n%x\t%d",pi1,*pi1); // 66fd9c 123 printf("\n%x\t%d",pi2,*pi2); // 66fd9c 123 printf("\n%x\t%d",pi3,*pi3); // 66fd9c 123
    При записи выражений с указателями требуется обращать внимание на приоритеты операций.
    Ссылка – это синоним имени объекта, указанного при инициализации ссылки.
    Формат объявления ссылки
    <тип> & <имя> =<имя_объекта>;
    ПРИМЕР
    int x;// определение переменной int& sx=x;// определение ссылки на переменную х const char& CR=’\n’;//определение ссылки на константу
    Правила работы со ссылками:
    1)
    Переменная ссылка должна явно инициализироваться при ее описании, если она не является параметром функции, не описана как extern или не ссылается на поле класса.
    2)
    После инициализации ссылке не может быть присвоено другое значение.
    3)
    Не существует указателей на ссылки, массивов ссылок и ссылок на ссылки.
    4)
    Операция над ссылкой приводит к изменению величины на которую она ссылается
    Ссылка не занимает дополнительного пространства в памяти, она является просто другим именем объекта.
    ПРИМЕР
    #include void main()
    {

    84 int I=123; int &si=I; cout<<”\ni=”< I=456; cout<<”\ni=”< I=0; cout<<”\ni=”<}
    3.7. Строковый тип данных
    Любой текст состоит из символов. Для хранения одного символа предназначен тип данных char. Переменную типа char можно рассматривать двояко: как целое число, занимающее 1 байт и способное принимать значения от 0 до 255 (тип unsigned char) или от -128 до 127
    (тип signed char) и как один текстовый символ. Сам же тип char может оказаться как знаковым, так и беззнаковым, в зависимости от операционной системы и компилятора. Поэтому использовать тип char не рекомендуется, лучше явно указывать будет ли он знаковым (signed) или беззнаковым (unsigned).
    Как и целые числа, данные типа char можно складывать, вычитать, умножать, делить, а можно выводить на экран в виде одного символа.
    Именно это и происходит при выводе символа через объект cout. Если же нужно вывести числовое значение символа (также называемое ASCII- кодом), то значение символа необходимо преобразовать к типу int.
    ПРИМЕР
    #include int main()
    { unsigned char c='A'; // Константы char заключаются в
    // одинарные кавычки cout<}

    85
    В этом примере переменной с типа char присваивается значение, равное символу 'A' (константы типа char записываются как символы в одинарных кавычках), затем на экран выводится значение c, как символа и его ASCII-код, потом переменной c присваивается значение 126 (то есть символ с ASCII-кодом 126) и снова выводится на экран символ и его
    ASCII-код.
    Текстовую строку можно представить, как массив символов типа char
    , но в языке C++ для хранения текстовых строк был создан более удобный тип string. По сути, тип данных string и является массивом символов. Например, если мы объявили переменную S как string S, а затем присвоили ей значение "школа" (текстовые строки заключаются в двойные кавычки), то мы можем обращаться к отдельным символам строки S, представляя S, как массив символов, например, S[0]=='ш',
    S[1]=='к' и т.д. Для того, чтобы узнать длину строки используется метод length(), вызываемый в виде S.length().
    Строковые данные можно считывать с клавиатуры, выводить на экран, присвавать переменным типа string. Также строки можно складывать друг с другом: например, при сложении строк "Hello, " и "world!" получится строка "Hello, world!". Такая операция над строками называется конкатенацией.
    ПРИМЕР
    Основные приемы работы с объектами string .
    string S, S1, S2; // Объявление трех строк cout<<"Как вас зовут? "; cin>>S1; // Считали строку S1
    S2="Привет, "; // Присвоили строке значение
    S=S2+S1; // Использование конкатенации cout<При считывании строк из входного потока считываются все символы, кроме символов–разделителей (пробелов, табуляций и новых

    86 строк), которые являются границами между строками. Например, если при выполнении следующей программы string S1, S2, S3; // объявили 3 строки cin>>S1>>S2>>S3; ввести текст `Мама мыла раму' (с произвольным количеством пробелов между словами), то в строку S1 будет записана строка "Мама", в
    S2 — "мыла", в S3 — "раму".
    Если нужно считать строку со всеми пробелами, то необходимо использовать функцию getline следующим образом: string S; getline(cin,S);
    Основные функции для работы со строками приведены в таблице 3.8, некоторые из них находятся в библиотеке stdio.h, поэтому при составлении программы, работающей со строками эту библиотеку лучше подключать.
    Таблица 3.8
    Функции обработки строковых данных
    Функция
    Описание strlen(имя_строки) определяет длину указанной строки, без учёта нуль-символа strcpy(s1,s2) выполняет побайтное копирование символов из строки s2 в строку s1 strncpy(s1,s2, n) выполняет побайтное копирование n символов из строки s2 в строку s1. возвращает значения s1 strcat(s1,s2) объединяет строку s2 со строкой s1.
    Результат сохраняется в s1 strncat(s1,s2,n) объединяет n символов строки s2 со строкой
    s1. Результат сохраняется в s1 strcmp(s1,s2) сравнивает строку s1 со строкой s2 и возвращает результат типа int: 0 – если строки эквивалентны, >0 – если s1— если s1>s2 С учётом регистра

    87
    Таблица 3.8 продолжение
    strncmp(s1,s2,n) сравнивает n символов строки s1 со строкой s2 и возвращает результат типа int:
    0 – если строки эквивалентны, >0 – если s1s2 С учётом регистра stricmp(s1,s2) сравнивает строку s1 со строкой s2 и возвращает результат типа int: 0 – если строки эквивалентны, >0 – если s1— если s1>s2 Без учёта регистра strnicmp(s1,s2,n) сравнивает n символов строки s1 со строкой s2 и возвращает результат типа int:
    0 – если строки эквивалентны, >0 – если s1s2 Без учёта регистра isalnum(c) возвращает значение true, если с является буквой или цифрой, и false в других случаях isalpha(c) возвращает значение true, если с является буквой, и false в других случаях isdigit(c) возвращает значение true, если с является цифрой, и false в других случаях islower(c) возвращает значение true, если с является буквой нижнего регистра, и false в других случаях isupper(c) возвращает значение true, если с является буквой верхнего регистра, и false в других случаях isspace(c) возвращает значение true, если с является пробелом, и false в других случаях toupper(c) если символ с, является символом нижнего регистра, то функция возвращает преобразованный символ с в верхнем регистре, иначе символ возвращается без изменений. strchr(s,c) поиск первого вхождения символа с в строке
    s. В случае удачного поиска возвращает указатель на место первого вхождения символа с. Если символ не найден, то возвращается ноль.

    88
    Таблица 3.8 продолжение
    strcspn(s1,s2) определяет длину начального сегмента строки s1, содержащего те символы, которые не входят в строку s2 strspn(s1,s2) возвращает длину начального сегмента строки s1, содержащего только те символы, которые входят в строку s2 strprbk(s1,s2) возвращает указатель первого вхождения любого символа строки s2 в строке s1 atof(s1) преобразует строку s1 в тип double atoi(s1) преобразует строку s1 в тип int atol(s1) преобразует строку s1 в тип long int getchar(с) считывает символ с со стандартного потока ввода, возвращает символ в формате int gets(s) считывает поток символов со стандартного устройства ввода в строку s до тех пор, пока не будет нажата клавиша ENTER
    3.8. Программирование развилок
    Развилка является одной из наиболее часто употребляемых алгоритмических управляющих структур. В языке С++ развилки записываются следующим образом: if (<условие>)
    <управляющий оператор положительной ветви>; else
    <управляющий оператор отрицательной ветви>;
    Это полная развилка (обратите внимание, что перед условие взято в круглые скобки, точка запятой стоит после каждого управляющего оператора). Неполная же развилка имеет следующий вид: if (<условие>)
    <управляющий оператор положительной ветви>;

    89
    Здесь <условие> – предикат развилки. Управляющий оператор положительной ветви выполняется, если <условие>=TRUE; иначе выполняется управляющий оператор отрицательной ветви.
    ПРИМЕР
    Наибольшее из трех неравных чисел (A, B, C) возвести в квадрат.
    Пример демонстрирует возможность использования развеет- вляющихся процессов. Блок-схема программы представлена на рис. 3.2.
    #include int main()
    { int a,b,c; cout<<”\nInput a,b,c”; cin>a>>b>>c; if (a>b && a>c) a=a*a; else if (b>c) b=b*b; else c=c*c; cout<<”\na=”<}
    Дословно «if… else…» переводится как «если… иначе…».
    Развилка есть процесс принятия решения относительно выбора дальнейшего движения в зависимости от некоторого условия. Наиболее часто используемыми являются развилки с вариантом решения «да» или
    «нет». Однако существует так называемая развилка множественного выбора (т. е. когда имеется возможность движения далее по алгоритму не в двух направлениях, а в гораздо большем их количестве).

    90
    Для этого используют оператор выбора варианта. Записывается она следующим образом: switch (<выражение>)
    { case <константа 1> : <оператор 1>; break; case <константа 2> : <оператор 2>; break; default: <оператор>;
    }
    Начало
    Конец
    (A>B && A>C)
    Вывод A, B, C
    Ввод A, B, C
    A=A
    2
    B>C
    B=B
    2
    C=C
    2
    Рис. 3.2. Возведение в квадрат наибольшего из трех неравных чисел

    91
    При выполнении оператора switch, вычисляется выражение, записанное после switch, оно должно быть целочисленным. Полученное значение последовательно сравнивается с константами, которые записаны следом за case. При первом же совпадении выполняются операторы помеченные данной меткой. Если выполненные операторы не содержат оператора перехода break, то далее выполняются операторы всех следующих вариантов, пока не появится оператор перехода или не закончится переключатель. Если значение выражения, записанного после switch не совпало ни с одной константой, то выполняются операторы, которые следуют за меткой default. Метка default может отсутствовать.
    Опять подробности работы этой управляющей структуры удобнее рассматривать на примере. Блок-схема алгоритма приведена на рис. 3.3.
    Здесь n – переменная-селектор; константа 1, константа 2 и т.д. – непересекающиеся возможные значения переменной-селектора. Если необходимо указать несколько значений для одного и тогоже действия, можно написать несколько подряд идущих операторов case, после последнего из которых будет указан соответствующий оператор.
    ПРИМЕР
    По введенному номеру дня определить, к какой части недели он
    относится.
    #include int main()
    { int h; string s; cout<<”\nInput day’s number”; cin>>h; switch (h)
    { case 1: case 2:

    92 case 3: s=”начало недели”; break; case 4: s=”четверг”; break; case 5: s=”пятница”; break; case 6: case 7: s=”выходные”; break; default: s=”нет такого дня”;
    } cout<<”\nDay”<
    1   2   3   4   5   6   7   8   9   ...   15


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