Лекция 4. Более сложные элементы программирования (Электронные лекции)
Описание файла
Файл "Лекция 4. Более сложные элементы программирования" внутри архива находится в папке "Лекции". PDF-файл из архива "Электронные лекции", который расположен в категории "". Всё это находится в предмете "программирование и алгоритмизация" из 1 семестр, которые можно найти в файловом архиве НИУ «МЭИ» . Не смотря на прямую связь этого архива с НИУ «МЭИ» , его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст из PDF
Лекция 3. Более сложные элементы программирования3.1. Обработка символьной информации на Си3.1.1. Символьный типСначала освежим знания, полученные в лекции 1. Описаниесимвольной переменной а: char а; данные типа char занимают в памяти один байт и принимают значения на множестве символов, допутимых для данного компьютера. Внутренний код байта определяется покодовой таблице.Тип сhar рассматривается в Си как тип целое (со знаком signed char или просто char); при желании над переменными типа charможно выполнять арифметические операции.Символьная константа записывается как соответствующий символ, заключенный в апострофы. Оператор а='а' означает, что символьной переменной с именем а присваивается значение символа а.Для использования управляющих символов в Си имеютсяуправляющие константы, запись которых в апострофах начинается снаклонной черты (\), например:\n - перевод строки,\f - перевод страницы,\a - звонок,\0 - нулевой байт (используется для обозначения конца строки).Если в апострофах после косой черты стоит восьмеричная(начинается с 0 и содержит цифры от 0 до 7) или шестнадцатеричная(начинается с х или Х) константа, то она рассматривается как символ ссоответствующим кодом; например, '\0100'-прописная латинская Р.3.1.2.
Работа со строками символов в Си. Строковые литералы. .В Си отсутствует специальный строковый тип. Вместо такого типа используется понятие стрoкового литерала.Строковый литерал - последовательность символов, заключенная в двойные кавычки, например, " text". В памяти ЭВМ строковый литерал представляется как массив элементов типа char, в конце которого помещен символ '\0' (нуль-терминатор).Адрес строкового литерала и интерпретация его как элемента языка зависит от приема его использования.Строковый литерал может использоваться в Си-программах следующим образом:1.
Для инициализации массивов типа char.Следующие описания являются идентичными:сhar str[6]="слово"; /*6-й символ - нуль-терминатор*/char str[]="слово";char str[6]={'с','л','о','в','о', '\0'};Если длина массива превышает длину литерала, то оставшиесясимволы считаются неопределенными для локальных нестатическихмассивов или равными нулю для глобальных или статистических массивов.Пример.void main(){char a[10]="слово"/*последние 4 символа имеют неопредел.знач.*/...В этом случае адрес первого символа литерала есть значениеимени массива (адрес первого элемента массива).
Массив располагается в стеке функции.2. Для инициализации или присваивания значения переменнойтипа char *. Например:char *str1,*str2="text2";...str1="text1";Литералы "text1" и "text2" располагаются в сегменте данных программы, значения адресов их первых элементов присваиваются переменным-указателям str1 и str2. Литералы в данном случае рассматриваются как указатели-константы.Замечание. Недопустимо присваивать значения, в том числе изначения литералов, именам массивов, так как имя массива - этоуказатель-константа. Например, следующий фрагмент программыневерен:char str[6];str="слово";...23. Для записи выводимого текста в функциях вывода (printf, puts,и т.д.). Литералы, используемые в этих операторах, хранятся в сегменте данных.4.
Последовательности символов, вводимые с помощью функции scanf по формату s,с помощью функции gets и аналогичных функций, записываются в память как литералы (символ \n не заносится впамять, вместо него записывается \0). Адресом литерала становитсяадрес переменной-указателя или имя символьного массива, в которыйвводится литерал.Для ввода и вывода строк в Си можно применять функции scanfи printf с использованием формата s. Существуют также специальныефункции ввода-вывода строк символов puts и gets.
Они действуюттакже, как scanf("%s",string) и printf("%s\n",string), за одним исключением: scanf принимает символы, пока не встретится \n, а передает впамять символы до \n или пробела (символы от первого пробела до \nостаются в буфере); gets передает в память все символы до \n.3.1.3.
ПРИМЕРЫ ОБРАБОТКИ СТРОКПример 1. Вычислить количество слов в строке; под словом понимается группа символов, не содержащая пробелов. Слова могутразделяться одним или несколькими пробеламиВ приведенной программе мы подсчитываем число "концовслов", т. е. число пар символов "непробел-пробел" или "непробел-конец строки". Алгоритм (блок-схема на рис.11) предусматривает последовательный просмотр символов строки от ее начала, цикл заканчивается на символе '\0'.3началоВвод исходнойстроки prk=0; i=0;нетpr[i]’\0’данет(pr[i]’ ‘)и((pr[i]=’ ‘)или (pr[i]=’\0’))даk=k+1i=i+1Вывод kконецРис.11.
Алгоритм вычисления числа слов в строке#include <stdio.h>#include <conio.h>#define NMAX 81 /*максимальная длина стpоки*/void main(){char pr[NMAX];/*рассматриваемая строка*/int k,n,i; /*k-число слов, n-длина стpоки, i-счетчик символов*/4puts("Введите стpоkу");gets(pr);k=0; i=0;while (pr[i]!='\0'){if ((pr[i]!=' ') && ((pr[i+1]==' ') || (pr[i+1]=='\0')))k=k+1;i=i+1;};printf("Число слов pавно %2d\n",k); getch();}Пример 2. Определить, сколько в последовательности А малыхлатинских букв и сколько в последовательности В цифр.Пояснения к примеру 2.Известно, что во всех широко используемых в настоящее времякодовых таблицах символов малые латинские буквы от ‘a’ до ‘z’ расположены друг за другом в порядке возрастания кода.
Цифры от ‘0’ до‘9’ – также расположены подряд. Поэтому надо найти, сколько символов строки А удовлетворяют условию:‘a’ ≤ A[i] ≤ ‘z’,и сколько символов строки Bудовлетворяют условию:‘0’ ≤ B[i] ≤ ‘9’.Так как алгоритмы обработки A и B отличаются только обозначениями и константами, то следует разработать общую функцию обработки, которая должна вычислять количество символов некоторойстроки str, расположенных в интервале от с1 до с2. Прототип такойфункции Си: int number(char *str, char c1, char c2); ниже приведена программа, выполняющая задание:#include <stdio.h>#include <conio.h>#define NMAX 81 /*максимальная длина стpоки*/int number(char *str, char c1, char c2);void main()5{char a[NMAX], b[NMAX];/*заданные строки*/puts("Input a");gets_s(a);puts("Input b");gets_s(b);printf(" ka=%d\n",number(a,'a','z'));printf(" kb=%d\n",number(b,'0','9'));_getch();}int number(char *str, char c1,char c2){int i, k;k=0; i=0;while (str[i]!='\0'){if ((str[i]>=c1)&&(str[i]<=c2))k=k+1;i=i+1;}return(k);}3.1.4.
Функции и макросы для работы с символьной информациейМакросы для проверки вида символов и преобразования символов содержатся в заголовочном файле <ctype.h>. Примеры обращенийк макросам:isalnum(c) - истина ,если с - буква или цифра;isalfa(c) - истина, если с - буква;isascii(c) - истина, если код символа с меньше или равен 127;tolower(c) - преобразует символ прописной буквы в символстрочной, не изменяя остальные символы; не являющиеся прописными буквами символы не преобразуются;toupper(c) - преобразует символ строчной буквы в символ прописной (обратная для tolower).6Макросы файла <ctype.h> не предназначены для работы с русскими буквами.Библиотека для работы со строками символов содержит, например, функции: определение длины строки, копирование строк, выделение подстрок, определение вхождения символа или подстроки встроку, сравнение строк, конкатенация (сцепление строк), вывод строкс сообщениями об ошибках и т.
д. Прототипы функций содержатся взаголовочном файле <string.h>.Большинство функций обрабатывают только последовательности символов, заканчивающиеся нулем-терминатором. В примерахпрограмм следующей лекции использованы функции:strlen(const char *s) - возвращает длину в байтах для строки, на которую указывает s, не учитывая нуль-терминатор;strcpy(char *s1, const char *s2) - копирует строку, на которую указывает s2, в строку, на которую указывает s1;strcmp(const char s1, const char* s2) - выполняет сравнение строк,на которые указывают s1 и s2; возвращает 0, если строки одинаковы, и положительное значение, если s1>s2, иначе отрицательное;эта функция осуществляет лексикографическое1 (или алфавитное)сравнение строк;strncpy(char *s1, const char *s2, int n) - копирует не более n первыхсимволов строки, на которую указывает s2, в строку, на которуюуказывает s1; если n меньше длины строки s2, то в s1 не переносится символ '\0';strcat(char* str1, const char* str2) – присоединяет к строке str1 строкуstr2; под str1 должна быть отведена память, достаточная для хранения результата;1Сначала сравниваются первые символы строк; если их кодысовпадают, то сравниваются коды вторых символов; если их кодысовпадают, то сравниваются коды следующих символов.
Большейсчитается строка, у которой раньше встретится символ с большим(ударение на первом слоге) кодом. Если коды всех символов строкравны, то и строки равны. Например, строка «1000» меньше, чем строка «5».7strstr(const char *s1,const char *s2) - возвращает указатель на место первого вхождения s2 в s1.При работе с символьной информацией часто требуются функции, преобразующие строку символов в число и числа в строку символов (иначе говоря, внешнее представление числа во внутреннее инаоборот). Прототипы таких функций содержатся в заголовочномфайле <stdlib.h>, некоторые из них дублируются в <math.h> и другихзаголовочных файлах. В примерах следующей лекции будет использоваться функция atof, преобразующая строку символов в значение типаdouble; ее шаблон:double atof(const char *s)Все вышеупомянутые функции, в частности, используются припрограммировании обработки таблиц.
В таких задачах часто требуется:• выделить смысловые поля таблицы, т. е. подстроки, с помощьюфункций strcpy, strncpy;• преобразовать некоторые поля из символьного представления вчисловое (с помощью функций atof, atoi и др.);• проанализтровать символьные поля с помощью функции strstr,strcmp;• подготовить строки выходных данных с помощью, например, itoa,gcvt (см.