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

  • Debug

  • Debug | Start Debugging

  • Debug | Step into

  • Борис Пахомов Санкт Петербург бхв петербург 2013 удк 004. 4 Ббк 32. 973. 26018. 2 П


    Скачать 17.38 Mb.
    НазваниеБорис Пахомов Санкт Петербург бхв петербург 2013 удк 004. 4 Ббк 32. 973. 26018. 2 П
    АнкорMS Visual C.pdf
    Дата04.08.2018
    Размер17.38 Mb.
    Формат файлаpdf
    Имя файлаMS Visual C.pdf
    ТипДокументы
    #22453
    страница5 из 37
    1   2   3   4   5   6   7   8   9   ...   37
    с
    символьными данными
    Рассмотрим некоторые полезные программы для работы с символьными данными, использующие операторы условного перехода. Символьные данные в языке С имеют тип char
    : переменная c
    , которая будет содержать один символ (точнее — его код по таблице кодирования символов ASCII), должна описываться как char Здесь это обычное имя переменной, вместо которого можно было бы написать, например, abcde. Компилятор присвоит имени необходимый адрес, если количество символов в имени не превышает допустимое, определенное средой программиро
    - вания.
    Среда VC++ обладает еще одним типом данных для описания символа, но по таблице. В отличие от таблицы ASCII, в соответствии с которой код символа занимает один байт, кодирование по Unicode размещает символ в двух байтах. С таким кодированием мы встретимся позднее. Компилятор С+ трактует переменные типа char как signed char
    (символьная со знаком) и как unsigned char
    (символьная без знака, причем подразумевается, что это данные разных типов. По умолчанию переменные типа char рассматриваются компилятором как переменные типа signed char
    . Такие переменные могут преобразовываться в переменные типа int
    . Теперь после введения типа char можно определить и тип short или short int
    . Этим типом описывают "короткие" переменные целого типа. Такие переменные по определению занимают памяти больше или равно, чем переменные типа char
    , и меньше или равно, чем переменные типа В библиотеке Снаряду с функциями и с которыми мы познакомились ранее, существуют и другие функции ввода/вывода. Две из них — это и putchar()
    . К переменной char c эти функции применяются такс Функции и putchar()
    описаны в файле stdio.h, который в данной версии среды не подключается к заготовке консольной программы автоматически. Первая функция не имеет параметров — в круглых скобках ничего нет. Функция getchar()
    ,

    38 Часть
    I. Изучение языка С/С++
    начав выполняться, ожидает ввода символа с клавиатуры. Как только символ с клавиатуры введен, его значение присваивается переменной Если говорить точнее, функция работает несколько иначе. Фактическая обработка символа начнется только тогда, когда ввод закончится нажатием клавиши, а до этого вводимые символы накапливаются в буфере функции.По- этому если присвоение символов происходит в некотором цикле (например, если мы хотим сформировать строку из символов, вводя их через функцию getchar()
    по одному символу в цикле, то следует ввести всю строку символов, нажать клавишу и только тогда мы увидим результат ввода — строка будет состоять из символов, введенных функцией. Тут возникает вопроса как дать знать программе, что ввод группы символов закончен Ввод данных, как мы в дальнейшем увидим, может осуществляться и из файла. В этом случае на окончание ввода указывает так называемый признак конца файла, присутствующий в файле, который формируется функциями ввода файла после окончания его ввода в момент выполнения функции закрытия файла. Этот признак потом при чтении файла обнаруживается с помощью специальной функции (ее описание находится в файле ). Аббревиатура eof означает end of file. Но как быть с признаком конца ввода при вводе данных с клавиатуры Хотелось бы, чтобы и при вводе с клавиатуры был бы такой же порядок формирования признака конца данных. Ион действительно имеется среда рассматривает ввод символов с клавиатуры в виде специального потока данных, который можно завершить нажатием комбинации клавиш +. При этом формируется символ, значение которого равно –1. Этот символ и будет признаком конца данных, вводимых с клавиатуры функцией ввода. Когда мы в программе "поймаем" этот символ, то должны завершить ввод. Это и будет для нас eof
    . Но такой признак можно и самостоятельно сформировать в программе задать в ней некий символ (например, знак вопроса (?)), который будет означать конец ввода с клавиатуры. Тогда при вводе символов последним надо будет набрать символ знака вопроса (?). А в самой программе проверять каждый введенный символ на совпадение его со знаком вопроса и при обнаружении такого совпадения завершать ввод. Как мы теперь знаем, для того чтобы функция getchar()
    приступила к вводу каждого набранного на клавиатуре символа, надо после набора группы символов (те. строки) нажать клавишу . Нажатию этой клавиши соответствует символ
    \n
    — символ перехода на новую строку. Если мы хотим ограничиться вводом одной строки, то признаком конца ввода файла можно считать
    \n
    . Если же мы хотим вводить группу строки после этого дать знать программе, что ввод завершен, тов качестве признака конца файла можно использовать некий управляющий код из диапазона 0—31 таблицы ASCII) или, как мы видели, какой-либо символ, который имеет отображение на экране в отличие от управляющих. Если воспользоваться стандартным признаком конца файла (нажатием +), то следует поступать так после ввода последнего символа последней строки и нажатия клавиши
    (чтобы функция getchar()
    начала обработку введенных символов, требуется нажать комбинацию клавиш +, затем клавишу (чтобы сим
    Глава
    2. Программы для работы с
    символьными данными вол от + попал на обработку, и тем самым цикл while завершился. Если обозначить символическую константу, задающую значения признака конца ввода с клавиатуры через eof
    , то, воспользовавшись оператором
    #define
    , вначале программы ввода данных с клавиатуры мы можем написать
    #define eof -1 // признак конца ввода символов с клавиатуры Здесь
    //
    — это признак комментария в программе на языке С. Такой знак ставится, если текст комментария занимает только одну строку. Если же ваш комментарий более длинный, то следует воспользоваться другой формой задания комментария "скобками"
    /* */
    . Весь текст между этими скобками можно располагать на многих строках. Например
    /* признак конца ввода символов с клавиатуры Приступим к составлению простейших программ работы с символьными данными. Программа копирования символьного файла. Вариант Напишем программу, в которой входной файл будет вводиться с клавиатуры (входное стандартное устройство — клавиатура, а выводиться на экран (выходное стандартное устройство — экран. Текст программы представлен в листинге 2.1. Листинг 2.1

    // 2.1_2011.cpp : main project file.
    #include "stdafx.h"
    #include для getchar(), putchar(), printf()
    #include для _getch() using namespace System;
    #define eof -1 признак конца файла Ctrl+Z int main()
    { int c; printf("Make input>\n"); c=getchar(); while(c != eof)
    { putchar(c); c=getchar();
    }
    _getch();
    }

    40 Часть
    I. Изучение языка С/С++
    Переменная c
    , в которую вводится один символ, описана как int
    , а не как char
    . Почему Дело в том, что в языке С типы char и int взаимозаменяемы (переменная фактически содержит код символа, те. некоторое число. С другой стороны, чтобы определить момент наступления конца ввода с клавиатуры, мы должны сравнить содержимое переменной с с числом eof
    . Именно поэтому c
    объявлена как Функция printf()
    выводит на экран запрос на ввод. Далее вводится первое значение переменной c
    (как мы договаривались ранее, набираем на клавиатуре строку и нажимаем клавишу , тогда getchar()
    начинает обработку по одному символу. Потом с помощью оператора цикла while()
    начинается циклическая обработка ввода/вывода символов. Пока условие в заголовочной части while()
    истинно (те. пока мы не нажали комбинацию клавиш +), выполняется тело оператора while()
    — все операторы, находящиеся внутри фигурных скобок putchar(c)
    выводит введенный символ на экран, вводит новый символ в качестве значения переменной c
    . После этого программа доходит до конца тела оператора while()
    — закрывающей фигурной скобки — и снова возвращается в его заголовочную часть, где начинает проверять выполнение записанного там условия. Если условие истинно, те. введенный в качестве значения переменной c
    символ не соответствует, то снова выполняются операторы, находящиеся в теле Как только мы нажмем комбинацию клавиш +, в переменной c
    появится ее код — число –1. Поскольку условие выполнения оператора while()
    нарушится значение переменной с станет равно eof
    ), то управление будет передано следующему после while()
    оператору. В этом случаев консольном окне появится сообще- ние-задержка закрытия экрана "Для продолжения нажмите любой символ, которое потребует ввода символа с клавиатуры. Пока мы не нажмем какую-либо клавишу, наша программа-приложение будет ждать ввода, а мы в это время будем рассматривать картинку на экране и гадать, что же у нас получилось. Если мы нажмем любую клавишу, то наша программа завершится. Следует кое-что уточнить независимо оттого, вывели мы символ на экран или нет, он будет отображен на экране функцией getchar()
    . В таком случае говорят, что getchar()
    работает с эхо-сопровождением. Поэтому, когда сработает функция putchar(c)
    , то может показаться, что она повторно выведет введенный символ. На самом деле это не так, двойник символа на экране строкой выше появится из-за излишней плодовитости Для закрепления материала желательно выполнить программу в режиме отладки, чтобы детально посмотреть, как все происходит на самом деле. Для этого щелкните мышью в поле подшивки слева от оператора while(c != eof)
    . В этом поле появится пометка в виде красного кружочка. Это так называемая точка прерывания программы (в опции Debug главного меню среды вы ее обнаружите под названием
    breakpoint). Запуск программы на выполнение осуществляется в режиме отладки либо по нажатию клавиши , либо командами Debug | Start Debugging.
    Глава
    2. Программы для работы с
    символьными данными Введите, например, символы
    123
    . Их коды по таблице ASCII: 49, 50, 51. После нажатия клавиши программа остановится в точке прерывания (в красном кружочке появится желтая стрелка вправо — это сигнал о том, что произошел останов программы. Начинается цикл обработки введенной последовательности
    1, 2, 3. Наведите мышь на переменную с. Тут же всплывет подсказка, показывающая значение этой переменной. Вы увидите, что первое значение переменной будет равно 49 — это код единицы, те. в обработку поступил первый введенный символ запомните, что в переменных находятся коды, а не сами значения. Чтобы выполнить следующий оператор, откройте опцию Debug главного меню и посмотрите, какую команду надо в ней выполнить. Это будет команда Step Over (или нажатие клавиши ). При этой команде выполняется всегда целый оператор. Нов качестве оператора может выступать, как мы увидим далее, и некоторая функция (или подпрограмма, имя которой с параметрами указано в тексте программы (заголовок) и после имени которой стоит точка с запятой. А вам хочется посмотреть по шагам, как выполняется функция. Чтобы в отладочном режиме попасть внутрь функции, надо после останова на ее имени выполнить опции Debug | Step into или нажать клавишу . Таким образом, последовательно нажимая клавишу , вы пошагово выполните всю программу, проследив, как и почему выполняются в определенной последовательности операторы программы. Именно так отлаживается любая программа. В нашем конкретном случае, если выработали в режиме отладки, надо не запутаться, когда нажимать комбинацию клавиш +, иначе ничего не получится, потому что среда передает управление то консольному окну, то самой программе.
    Во-вторых, когда вы попали на шаг обработки закрывающей скобки функции main()
    , следует отключить отладку (это делается нажатием +), иначе вам придется пошагово выполнять еще много операторов, завершающих программу, которых мы обычно вне отладки невидим. И еще один момент. В данной программе придется все-таки самому организовывать задержку экрана с помощью функции
    _getch()
    , потому что после ввода символов в буфере ввода остается один символ , которым мы завершаем обработку введенного признака конца ввода. На рис. 2.1 приведен результат работы нашей программы. Рис. 2.1. Результат работы программы листинга 2.1

    42 Часть
    I. Изучение языка С/С++
    Программа копирования символьного файла. Вариант Ранее мы познакомились с правилом, когда вместо переменной некоторого типа можно использовать и выражение этого же типа. Воспользуемся данной возможностью и запишем нашу программу в другом виде (листинг 2.2). Листинг 2.2
    // 2.2_2011.cpp
    #include "stdafx.h"
    #include для getchar(), putchar(), printf()
    #include для _getch() using namespace System;
    #define eof -1 признак конца файла int main()
    { int c; printf("Make input>\n"); while((c=getchar())!= eof) putchar(c);
    _getch();
    } Ввод символа мы внесли в заголовочную часть while
    , поскольку с — это выражение того же типа, что и c
    . Оператор while в общем случае работает так он сначала вычисляет выражение, которое находится в его заголовочной части, при этом выполняется ввод символа с клавиатуры, что нами нужно. Затем оператор while проверяет, не являются ли введенные символы признаком конца файла. Так как в отличие от предыдущего варианта тело оператора while состоит только из одного оператора putchar(c)
    , то фигурные скобки можно опустить. После того как выполнится putchar(c)
    , управление будет передано в заголовочную часть оператора, где снова начнется вычисление выражения, которое, в свою очередь, потребует ввода символа с клавиатуры и т. д. Подсчет символов в файле. Вариант Напишем программу, в которой файл будет вводиться с клавиатуры. Вид программы представлен в листинге 2.3. Листинг 2.3

    // 2.3_2011.cpp
    #include "stdafx.h"
    #include для getchar(),putchar(), printf()
    Глава
    2. Программы для работы с
    символьными данными
    #include для _getch() using namespace System;
    #define eof -1 признак конца файла int main()
    { long nc; nc=0; printf("Make input>\n"); while(getchar()!= eof) nc++; printf("Characters's number is: %ld\n",nc);
    _getch();
    } Здесь мы встречаемся с новым типом данных long
    — длинное целое. Этот тип можно и long int
    ) применяется для описания больших целых чисел со знаком. По занимаемой памяти этот тип переменных больше или равен типу int
    . Переменные типа long могут объявляться как signed long или unsigned long
    . В первом случае у переменной будет присутствовать знак, во втором — знак будет подавлен. Это означает в обоих случаях, что знаковый разряд числа с квалификатором unsigned будет рассматриваться компилятором как обычный разряд данных, те. станет участвовать в операциях наряду с другими разрядами данных. signed long
    — это синоним long
    . Существует также тип данных long long
    . Переменная этого типа занимает память больше, чем unsigned long
    . Переменные типа long long могут быть со знакомили без знака. Соответственно они объявляются как signed long long и unsigned long long signed long long
    — это синоним long Так как мы подсчитываем количество символов в файле, который (в общем случае) может быть и не "клавиатурным, то должны быть готовы к тому, что в нем будет много символов, и их число превысит допустимое значение, помещающееся в переменной типа int
    . Количество вводимых символов подсчитывается в переменной nc типа long по правилу ввели один символ — значение nc увеличивается на единицу, ввели еще один — снова nc увеличивается на единицу и т. д. Вначале каждого выполнения программы значение nc обнуляется. Далее происходит запрос на ввод символов (текст выводится на экран. Затем опять с помощью цикла while организуется ввод символов до тех пор, пока не будет нажата комбинация клавиш +. Заметим, что тело оператора while
    (как ив предыдущем примере) содержит только одно выражение, поэтому фигурные скобки, ограничивающие тело оператора, излишни. Поскольку тело оператора составляет функция getchar()
    , то когда оператор while начнет вычислять выражение, потребуется ввод символа с клавиатуры. После того как мы введем символ, значение getchar()
    станет равным коду введенного символа эта функция всегда выдает код символа, который мы нажимаем на клавиатуре. Поэтому нет необходимости значение еще присваивать какой-либо переменной, тем более что сам введен

    44 Часть
    I. Изучение языка С/С++
    ный символ по нашему алгоритму не требуется — значение getchar()
    сразу сравнивается с признаком конца файла. Если этот признак еще не введен (мы не нажали комбинацию клавиш +), то условие выполнения оператора while не нарушается, и тело оператора while
    , состоящее всего из одного оператора начинает выполняться опять Новый оператор nc++
    равносиленвыражению nc=nc+1
    тек значению nc добавляется единица. Кстати, можно в данном случае писать и
    ++nc
    : пока операция
    ++
    не участвует в выражении типа int x=nc++
    или int x=++nc
    , это не имеет никакого значения. В последних же случаях положение символов
    ++
    существенно если они находятся до nc
    , то сначала операция выполняется, а потом уже результат присваивается переменной x
    . Если находятся после nc
    , то сначала содержимое nc присваивается переменной x
    , а потом уже nc изменяется на единицу. Этой операции родственна операция
    --
    , которая ведет себя как и
    ++
    , ноне прибавляет, а вычитает единицу. В функции printf()
    мы снова видим новый формат
    %ld
    . Поэтому формату выводятся числа типа Результат работы программы приведен на рис. 2.2. Заметим, что в подсчете символов участвует и символ комбинации клавиши символ, который вводится как признак конца ввода. Поэтому результат — количество введенных символов будет на единицу больше, что и видно из рисунка. Чтобы этого не происходило, в программе перед ее завершением из nc надо было бы отнять единицу, но тогда это было бы ненаглядно для обучающегося. Рис 2.2. Результат работы программы листинга Подсчет символов в файле. Вариант Изменим несколько предыдущую программу, применив новый оператор и новую операцию (см. по тексту. Программа будет выглядеть, как показано в листинге 2.4. Листинг 2.4
    // 2.4_2011.cpp
    #include "stdafx.h"
    #include для getchar(),putchar(),printf()
    #include для _getch()
    Глава
    2. Программы для работы с
    символьными данными
    using namespace System;
    #define eof -1 признак конца файла int main()
    { double nc; printf("Make input>\n"); for(nc=0; getchar() !=eof; nc++)
    ; printf("Characters's number is: %0.f\n",nc); printf("Characters's number is: %f\n",nc);
    _getch();
    } Для подсчета символов в файле мы применили переменную нового типа double это длинное float
    ), т. к. таких символов, возможно, окажется больше,чем может поместиться в переменную, описанную в предыдущем примере.Размер занимаемой памяти для переменной типа double больше или равен, чем для типа float
    , но меньше или равен, чем для типа long double
    . Последний тип совпадает с типом В табл. 2.1 приведены значения размеров памяти для основных типов данных в
    Microsoft C++. Таблица Размеры памяти для основных типов данных
    1   2   3   4   5   6   7   8   9   ...   37


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