Порядок выполнения работы. 1. Программные модули в C++




 

1. Программные модули в C++

Модули в C++ называются функциями и классами. Обычно программы на C++ пишутся путем объединения новых функций, которые пишет сам программист, с функциями, уже имеющимися в стандартной библиотеке С.

Стандартная библиотека С обеспечивает широкий набор функций для выполнения типовых математических расчетов, операций со строками, с сим­волами, ввода-вывода, проверки ошибок и многих других полезных операций. Это облегчает работу программиста, поскольку эти функции обладают мно­гими из необходимых программисту свойств. Функции стандартной библи­отеки С являются частью среды программирования C++.

Программист может написать функции, чтобы определить какие-то спе­цифические задачи, которые можно использовать в разных местах програм­мы. Эти функции иногда называют функциями, определенными пользовате­лем. Операторы, реализующие данную функцию, пишутся только один раз и скрыты от других функций.

Функция активизируется (т. е. начинает выполнять запроектированную для нее задачу) путем вызова функции. В вызове функции указывается ее имя и дается информация (в виде аргументов), необходимая вызываемой функции для ее работы. Это аналогично иерархической форме управления. Начальник (вызывающая функция или вызывающий оператор) просит под­чиненного (вызываемую функцию) выполнить задание и возвратить (т.е. сообщить) результаты после того, как задание выполнено. Функция-началь­ник не знает, как функция-подчиненный выполняет порученное ей задание. Подчиненный может вызвать другие подчиненные функции, причем начальник не будет осведомлен об этом.

Функции позволяют пользователю использовать модульное программи­рование (сотавлять программу из модулей). Все переменные объявляются в описаниях функций локальными переменными — они известны только для функции, в которой они описаны. Большинство функций имеют список пара­метров, который обеспечивает значения для связующей информации между функциями. Параметры тоже являются локальными переменными.

В программах, содержащих много функций, main должна быть построена как группа вызовов функций, которые и выполняют основную часть работы.

Существует несколько причин для построения программ на основе функций. Подход «разделяй и властвуй» делает разработку программ более управляемой. Другая причина — повторное использование программных кодов, т.е. использование существующих функций как стандартных блоков для создания новых программ. Повторное использование — основной фак­тор развития объектно-ориентированного программирования. При проду­манном присвоении имен функций и хорошем их описании программа может быть создана быстрее из стандартизированных функций, соответ­ствующих определенным задачам. Третья причина — желание избежать в программе повторения каких-то фрагментов. Код, оформленный в виде функции, может быть выполнен в разных местах программы простым вы­зовом этой функции.

Каждая функция должна выполнять одну хорошо определенную задачу и имя функ­ции должно наглядно отражать данную задачу. Это способствует успешному повтор­ному использованию программного обеспечения.

Теперь рассмотрим, как про­граммисты пишут свои собственные необходимые им функции. Рассмотрим программу, которая использует функцию square для вычисления квадратов целых чисел от 1 до 10.

Функция square активизируется или вызывается в main вызовом square(x). Функция создает копию значения х в параметре у. Затем square вы­числяет у * у. Результат передается в ту точку main, из которой была вы­звана square, и затем этот результат выводится на экран. Благодаря структуре повторения for этот процесс повторяется десять раз.

Описание square показывает, что эта функция ожидает передачи в нее целого параметра у. Ключевое слово int, предшествующее имени функции, указывает, что square возвращает целый результат. Оператор return в square передает результат вычислений обратно в вызывающую функцию.

 

include <iostream.h>

int square(int); // прототип функции

main() {

for (int x = 1; x <= 10; x++) cout << square(x) << " ";

cout << endl;

return 0;

}

 

int square(int y) { // описание функции

return у * у;

}

 

Результат работы программы:

1 4 9 16 25 36 49 64 81 100

 

Строка int square(int); является прототипом функции. Тип данных int в круглых скобках указывает компилятору, что функция square ожидает в операторе вызова целое значение аргумента. Тип данных int слева от имени функции square указывает компи­лятору, что square возвращает оператору вызова целый результат. Компилятор обращается к прототипу функции для проверки того, что вызовы функции square содержат правильный возвращаемый тип, правильное количество ар­гументов, правильный тип аргументов и правильный порядок перечисления аргументов.

Формат описания функции имеет вид

тип-возвращаемого-значения имя-функции (список-параметров) {

объявления и операторы }

Имя-функции — это любой правильно написанный идентификатор. Тип-возвращаемого-значения — это тип данных результата, возвращаемого из функции оператору ее вызова. Тип возвращаемого значения void указывает, что функция не возвращает никакого значения. Компилятор предполагает тип int для неопределенного типа возвращаемого значения.

Пропуск типа возвращаемого значения в описании функции вызывает синтаксическую ошибку, если прототип функции определяет возвращаемый тип иначе, чем int.

Если забыть вернуть значение из функции, в которой предполагается возвращение результата, это может привести к неожиданным ошибкам. Описание языка C++ указывает, что результат такой оплошности не определенен. В этом случае обычно компиляторы C++ выдают предупреждающее сообщение.

Возвращение какого-то значения из функции, для которой тип возвращаемого зна­чения объявлен как void, вызывает синтаксическую ошибку.

Несмотря на то, что пропущенный тип возвращаемого значения по умолчанию int, всегда задавайте тип возвращаемого значения явным образом. Исключением является функция main, для которой тип возвращаемого значения обычно не указывается.

Список-параметров — это список разделенных запятыми объявлений тех параметров, которые получает функция при ее вызове. Если функция не получает никаких значений, список-параметров задается как void. Тип дол­жен быть указан явно для каждого параметра в списке параметров.

Объявление параметров функции, имеющих одинаковый тип, в виде float x, у вместо float x, float у будет ошибкой. Объявление параметра floatx, у вызовет ошибку компиляции, так как типы надо указывать для каждого параметра в списке.

Точка с запятой после правой круглой скобки, закрывающей список параметров в описании функции, является синтаксической ошибкой.

Повторное определение параметра функции как локальной переменной этой функции является синтаксической ошибкой.

Не используйте одинаковые имена для аргументов, передаваемых в функцию, и соответствующих параметров в описании функции, хотя это и не является ошибкой. Использование разных имен помогает избежать двусмысленности.

Объявления и операторы внутри фигурных скобок образуют тело функ­ции. Тело функции рассматривается как блок. Блок — это просто составной оператор, который включает объявления. Переменные могут быть объявлены в любом блоке, а блоки могут быть вложенными. При любых обстоятель­ствах функция не может быть описана внутри другой функции.

Описание функции внутри другой функции является синтаксической ошибкой.

Выбор осмысленных имен функций и осмысленных имен параметров делает про­грамму более легко читаемой и помогает избежать излишних комментариев. Программа должна быть написана как совокупность небольших функций. Это об­легчает написание, отладку, сопровождение и модификацию программы. Функция, требующая большого количества параметров, возможно, выполняет слиш­ком много задач. Попробуйте разделить такую функцию на небольшие функции, которые выполняют отдельные задачи. Заголовок функции по возможности не должен занимать более одной строки. Прототип функции, заголовок функции и вызовы функции должны быть согласованы между собой по количеству, типу и порядку следования аргументов и параметров и по типу возвращаемых результатов.

Существует три способа возврата управления к точке, из которой была вызвана функция. Если функция не должна возвращать результат, управ­ление возвращается или просто при достижении правой фигурной скобки, завершающей функцию, или при выполнении оператора return; Если функция должна возвращать результат, то оператор

return выражение;

возвращает значение выражения в обращение к функции.

 

2. Прототипы функций

Прототип функции является одной из наиболее важных особенностей C++. Прототип функции указывает компилятору тип данных, возвращаемых функцией, количество параметров, которое ожидает функция, тип параметров и ожидаемый порядок их следования. Компилятор использует прототип функ­ции для проверки правильности вызовов функции. Ранние версии С не вы­полняли такого рода проверку, поэтому был возможен неправильный вызов функции без обнаружения ошибок компилятором. Подобные вызовы приво­дили к неисправимым ошибкам выполнения или к хитроумным исправимым логическим ошибкам, которые было очень трудно обнаружить. Прототипы функции устранили этот недостаток.

В C++ требуются прототипы функций. Используйте директиву препроцессора #include, чтобы получить прототипы стандартных библиотечных функций из заголовоч­ных файлов соответствующих библиотек. Используйте также # include для заголо­вочных файлов, содержащих прототипы функций, используемых вами. Например прототип функции, которая возвращала бы наибольшее из трех передаваемых ей значений (х, у и z) выглядел бы так:

int maximum(int, int, int);

Этот прототип указывает, что maximum имеет три аргумента типа int и возвращает результат типа int. Заметим, что прототип функции такой же, как заголовок описания функции, за исключением того, что в него не включены имена параметров (х, у и z).

Имена параметров могут быть включены в прототипы функции с целью документи­рования. Компилятор эти имена игнорирует.

Отсутствие точки с запятой в конце прототипа функции является синтаксической ошибкой.

Вызов функции, который не соответствует прототипу функции, ведет к синтаксической ошибке. Синтаксическая ошибка возникает также в случае отсутствия согласования между прототипом и описанием функции. Напри­мер, если бы в программе на вышеуказанном примере прототип функции был бы написан так:

void maximum(int, int, int);

компилятор сообщил бы об ошибке, потому что возвращаемый тип void в прототипе функции отличался бы от возвращаемого типа int в заголовке функции.

Другой важной особенностью прототипов функций является приведение типов аргументов, т.е. задание аргументам подходящего типа. Например, математическая библиотечная функция sqrt может быть вызвана с аргумен­том целого типа, даже если функция прототип в math.h определяет аргумент типа double, и при этом функция будет работать правильно. Оператор

cout << sqrt(4);

правильно вычисляет sqrt(4), и печатает значение 2. Прототип функции заставляет компилятор преобразовать целое значение 4 в значение 4.0 типа double прежде, чем значение будет передано в sqrt. Вообще, значения аргумен­тов, которые первоначально не соответствуют типам параметров в прототипе функции, преобразуются в подходящий тип перед вызовом функции. Эти преобразования могут привести к неверным результатам, если не руководст­воваться правилами приведения типов C++. Правила приведения определяют, как типы могут быть преобразованы в другие типы без потерь. В приведенном выше примере sqrt тип int автоматически преобразуется в double без изменения его значений. Однако double преобразуется в int с отбрасыванием дробной части значения double. Преобразование больших целых типов в малые целые типы (например, long в short ) может также привести к изменению значений.

Правила приведения типов применяются к выражениям, содержащим значения двух или более типов данных; такие выражения относятся к вы­ражениям смешанного типа. Тип каждого значения в выражении смешан­ного типа приводится к «наивысшему» типу, имеющемуся в выражении (на самом деле создается и используется временная копия выражения — истин­ные значения остаются неизменными). Ниже в таблице 1 перечислены встроенные типы данных в порядке следования от высших типов к низшим.

Преобразование значений к низшему типу может привести к неверным значениям. Поэтому значения могут преобразовываться к низшему типу толь­ко путем явного присваивания значения переменной низшего типа, либо с помощью операции приведения к типу. Значения аргументов функции пре­образуются к типам параметров в прототипе функции так, как если бы они были непосредственно присвоены переменным этих типов. Если наша функ­ция square, которая использует параметр целого типа, вызывается с аргументом с плавающей точкой, аргумент преобразуется к типу int (низ­шему типу) и squre обычно возвращает неверное значение. Например, square(4.5) возвратит 16 вместо 20.25.

Преобразование от высшего типа в иерархии типов к низшему может изменить значение данных.

Отсутствие прототипа функции, когда функция не определена перед ее первым вызовом, приводит к синтаксической ошибке.

Прототип функции, размещенный вне описания какой-то другой функции, относится ко всем вызовам данной функции, появляющимся после этого прототипа в данном файле. Прототип функции, размещенный внутри описания некоторой функции, от­носится только к вызовам внутри этой функции.

 

Таблица 1. Типы данных

Типы данных    
long double    
double    
float    
unsigned long int (синоним unsigned long)
long int (синоним long)
unsigned int (синоним unsigned)
int    
unsigned short int (синоним unsigned short)
short int (синоним short)
unsigned char    
char    

 

3. Функции работы со строками из библиотеки обработки строк

Библиотека обработки строк обеспечивает много полезных функций для работы со строковыми данными, сравнения строк, поиска в строках сим­волов и других подстрок, разметки строк (разделения строк на логические куски) и определения длины строк. Здесь представлены некоторые типовые функции работы со строками из библиотеки обработки строк (из стандартной библиотеки С). Сведения об этих функциях сведены в таблицу 2.

Заметим, что некоторые функции в таблице 2 имеют параметры с типом данных size_t. Этот тип определяется в заголовочном файле stddef.h (из стан­дартной библиотеки С) как беззнаковый целый тип, такой, как unsigned int или unsigned long.

Приведенные в таблице функции требуют подключения заголовочного файла <string.h>.

Функция strcpy копирует свой второй аргумент — строку в свой первый аргумент — массив символов, который должен быть достаточно большим, чтобы хранить строку и ее завершающий нулевой символ, который также копируется. Функция strncpy эквивалентна strcpy за исключением того, что strncpy указывает количество символов, которое должно быть скопи­ровано из строки в массив. Заметим, что функция strncpy не обязательно должна копировать завершающий нулевой символ своего второго аргумента; завершающий нулевой символ записывается только в том случае, если ко­личество символов, которое должно быть скопировано, по крайней мере на один больше, чем длина строки. Например, если второй аргумент — "test", завершающий нулевой символ записывается только в случае, если третий аргумент strncpy по меньшей мере равен 5 (четыре символа в "test" плюс один завершающий нулевой символ). Если третий аргумент больше пяти, завершающий нулевой символ добавляется к массиву до тех пор, пока не будет записано общее количество символов, указанное третьим ар­гументом.

Примечание: Не добавляется завершающий нулевой символ к первому аргументу strncpy, когда третий аргумент меньше или равен длине строки во втором аргументе.

 

Таблица 2 Функции работы со строками из библиотеки обработки строк

Прототип функции Описание функции
char *strcpy(char *s1, const char *s2)  
  Копирует строку s2 в массив символов s1. Возвращает значение s1.
char *strncpy(char *s1, const char *s2, size_t n)  
  Копирует не более nсимволов из строки s2 в массив символов s1. Возвращает значение s1.
char *strcat(char *s1, const char *s2)  
  Добавляет строку s2 к строке s1. Первый символ строки s2 записывается поверх завершающего нулевого символа строки s1. Возвращает значение s1.
char *strncat(char *s1, const char *s2, size_t n)  
  Добавляет не более nсимволов строки s2 в строку s1. Первый символ из s2 записывается поверх завершающего нулевого символа в s1. Возвращает значение s1.
int *strcmp(const char *s1, const char *s2)  
  Сравнивает строки s1 и s2. Функция возвращает значение 0, меньшее, чем 0 или большее, чем 0, если s1 соответственно равна, меньше или больше, чем s2.
int *strcmp(const char *s1, const char *s2, size_t n)  
  Сравнивает до n символов строки s1 со строкой s2. Функция возвращает значение 0, меньшее, чем 0 или большее, чем 0, если s1 соответственно равна, меньше или больше, чем s2.
char *strtok(char *s1, const char *s2)  
  Последовательность вызовов strtokразбивает строку s1 на «лексемы» — логические куски, такие, как слова в строке текста — разделенные символами, содержащимися в строке s2. Первый вызов содержит в качестве первого аргумента s1, а последующие вызовы для продолжения обработки той же строки, содержат в качестве первого аргумента NULL.При каждом вызове возвращается указатель на текущую лексему. Если при вызове функции лексем больше нет, возвращается NULL.
size_t *strlen(const char *s)  
  Определяет длину строки s. Возвращает количество символов, предшествующих завершающему нулевому символу.

В примере программы strcpy используется для копирования полной строки в массиве х в массив у и strncpy — для копирования первых 14 символов массива х в массив z. Нулевой символ ('\0') добавляется в массив z, потому что вызов strncpy в программе не записывает завершающий нулевой символ (третий аргумент меньше, чем длина строки второго аргумента).

Функция strcat добавляет свой второй аргумент — строку к своему пер­вому аргументу — массиву символов, содержащему строку. Первый символ второго аргумента замещает нулевой символ ('\0'), который завершал строку в первом аргументе. Программист должен быть уверен, что массив, исполь­зуемый для хранения первой строки, достаточно велик для того, чтобы хра­нить комбинацию первой строки, второй строки и завершающего нулевого символа (скопированного из второй строки). Функция strncat добавляет указанное количество символов из второй строки в первую. К результату до­бавляется завершающий нулевой символ.

//Использование strcpy и strncpy

#include <iostream. h>

#include <string.h>

main ()

{

char x[ ] = "Поздравляю Вас с днем рождения";

char y[35], z[15];

cout << "Строка в массиве х: " << х << endl

<< "Строка в массиве у: " << strcpy(х, у) << endl;

strncpy(z, х, 14);

z[14] = ' \ 0 ';

cout << "Строка в массиве z: " << z << endl;

return 0;

}

 

Результат работы программы:

 

Строка в массиве х: Поздравляю Вас с днем рождения

Строка в массиве у: Поздравляю Вас с днем рождения

Строка в массиве z: Поздравляю Вас

// Использование strcat и strncat.

#include <iostream.h>

#include <string.h>

main()

{

char s1 [25] = "Счастливого ";

char s2[ ] = "Нового Года ";

char s3 [40] = "";

cout << "s1 = " << s1 << endl << "s2 = " << s2 << endl;

cout << "strcat(s1, s2) = " << strcat(s1, s2) << endl;

cout << "strncat(s3, s1, 12) = " << strncat(s3, s1, 12)<< endl;

cout << "strcat(s3, s1) = " << strcat(s3, s1) << endl;

return 0;

}

 

Результат работы программы:

 

s1 = Счастливого

s2 = Нового Года

strcat (s1, s2) = Счастливого Нового Года

strncat(s3, s1, 12) = Счастливого

strcat(s3, s1) = Счастливого Счастливого Нового Года

 

Следующий пример программы сравнивает три сроки, используя функции strcmp и strncmp. Функция strcmp сравнивает символ за символом строку в своем первом аргументе со строкой в своем втором аргументом. Функция возвра­щает 0, если строки равны, отрицательное значение, если первая строка меньше, чем вторая, и положительное значение, если первая строка больше, чем вторая. Функция strncmp эквивалентна strcmp, за исключением того, что strncmp проводит сравнение только до указанного количества символов. Функция strncmp не сравнивает символы, следующие за нулевым символом в строке. Программа печатает целое значение, возвращаемое при каждом вызове функции.

// Использование strcmp и strncmp

#include <iostream.h>

#include <iomanip.h>

#include <string.h>

main () {

char *sl = "Счастливого Нового Года";

char *s2 = "Счастливого Нового Года";

char *s3 = "Счастливого Праздника";

cout << "s1 = " << s1 << endl << "s2 = " << s2 << endl

<< "s3 = " << s3 << endl << endl << "strcmp(s1, s2)= "

<< setw(2) << strcmp(sl, s2) << endl << "strcmp(sl, s3) = "

<< setw(2) << strcmp(s1, s3) << endl << "strcmp(s3, s1) = "

<< setw(2) << strcmp(s3, s1) << endl << endl;

cout << "strncmp(s1, s3, 12) = " << setw(2)

<< strncmp(s1, s3, 12) << endl

<< "strcmp(sl, s3, 13) = " << setw(2)

<< strncmp(s1, s3, 13) << endl

<< "strcmp(s3, s1, 13) = " << setw(2)

<< strncmp(s3, s1, 13) << endl;
return 0;
}

 

Результат работы программы:

 

s1 = Счастливого Нового Года

s2 = Счастливого Нового Года

s3 = Счастливого Праздника

 

strcmp(sl, s2) = 0

strcmp(sl, s3) = -2

strcmp(s3, s1) = 2

 

strncmp(sl, s3, 12) = 0

strncmp(sl, s3, 13) = -2

strncmp(s3, s1, 13) = 2

 

Как компьютер узнает о порядке следования букв? Все символы пред­ставляются внутри компьютера как численные коды; когда компьютер срав­нивает две строки, он на самом деле сравнивает численные коды символов в строке. (Замечание: коды символов упорядочены по алфавиту только для латинских букв, а к кириллице это, к сожалению, не относится.) Внутренний численный код, используемый для представления символов, может быть различным для разных компьютеров (особенно это относится к символам кирилли­цы).

В попытке стандартизации представления символов большинство произ­водителей компьютеров спроектировало свои машины так, чтобы использо­вать одну из двух популярных кодирующих схем — ASCII или EBCDIC. ASCII означает «Американский стандартный код для информационного об­мена» («American Standard Code for Information Interchange»), a EBCDIC оз­начает «Расширенный двоичный код закодированного десятичного обмена» («Extended Binary Coded Decimal Interchange Code»). Существуют и другие схемы кодирования, но эти две наиболее популярны.

ASCII и EBCDIC называются символьными кодами или символьными на­борами. Манипуляции со строками и символами на самом деле подразумевают манипуляцию с соответствующими численными кодами, а не с самими сим­волами. Это объясняет взаимозаменяемость символов и малых целых в C++. Так как имеет смысл говорить, что один численный код больше, меньше или равен другому численному коду, стало возможным сопоставлять различ­ные строки и символы друг с другом путем ссылки на коды символов.

Функция strtok используется для превращения строки в последователь­ность лексем. Лексема — это последовательность символов, отделенная сим­волами разделителям (обычно пробелами или знаками пунктуации). Напри­мер, в строке текста каждое слово может рассматриваться как лексема, а пробелы, отделяющие слова друг от друга, можно рассматривать как разде­лители.

Для разбиения строки на лексемы требуется несколько вызовов функции strtok(при условии, что строка содержит больше одной лексемы). Первый вызов strtok содержит два аргумента: строку, которую нужно разбить на лексемы, и строку, которая содержит символы, разделяющие лексемы (т.е. разделители). В примере оператор

tokenPtr = strtok(string, " ");

присваивает tokenPtrуказатель на первую лексему в string. Второй аргумент strtok, " " указывает, что лексемы в string разделяются пробелами. Функция strtok отыскивает первый символ в string, не являющийся разделителем (пробелом). Это начало первой лексемы. Затем функция находит следующий разделительный символ в строке и заменяет его нулевым символом ('\0'). Этим заканчивается текущая лексема. Функция strtok сохраняет указатель на следующий символ, стоящий в string за данной лексемой, и возвращает указатель на текущую лексему.

//Использование strtok

#include <iostream.h>

#include <string.h>

main() {

char string[] = "Это предложение содержит пять лексем";

char *tokenPtr;

cout <<"Строка, разбиваемая на лексемы:" << endl << string

<< endl << endl << "Лексемы:" << endl;

tokenPtr = strtok(string, " ");

while (tokenPtr!= NULL) {

cout << tokenPtr << endl;

tokenPtr = strtok(NULL, " ");

}

return 0;

}

Результат работы программы:

Строка, разбиваемая на лексемы:

Это предложение содержит пять лексем

Лексемы:

Это

предложение

содержит

пять

лексем

Последующие вызовы strtok для продолжения разбиения string на лексе­мы содержат в качестве первого аргумента NULL. Аргумент NULL указывает, что вызов strtok должен продолжать разбиение на лексемы, начиная с ячейки в string, сохраненной последним вызовом strtok. Если лексем при вызове strtok больше не оказалось, strtok возвращает NULL. Программа исполь­зует strtok для разбиения на лексемы строки «Это предложение содержит пять лексем». Каждая лексема печатается отдельно. Заметим, что strtokмодифи­цирует входную строку; поэтому, если строка после вызова strtok будет снова использоваться в программе, необходимо сделать копию строки.

Функция strlen получает в качестве аргумента строку и возвращает количество символов в строке — завершающий нулевой символ в длину не включается. Например:

//Использование strlen

#include <iostream.h>

#include <string.h>

main () {

char *stringl = "abcdefghijklmnopqrstuvwxyz";

char *string2 = "три";

char *string3 = "Бостон";

cout << "Длина строки \"" << stringl

<< "\" - " << strlen(stringl) << endl

<< "Длина строки \ "" << string2

<< "\" - " << strlen(string2) << endl

<< "Длина строки \"" << string3

<< "\" - " << strlen(string3) << endl;
return 0;

}

Результат работы программы:

 

Длина строки "abcdefghijklmnopqrstuvwxyz" - 26

Длина строки "три" - 3

Длина строки "Бостон" - 6

 

Помимо перечисленных стандартных функций работы со строками перечислим еще некоторые из них:

STRCHR() - обнаруживает первое вхождение данного символа в строке;

STRCSPN() - обнаруживает в строке первое вхождение символа из заданной последовательности символов;

STRLWR() - преобразует строку в символы нижнего регистра (в строчные буквы);

STRNCMP() - сравнивает N символов в двух строках;

STRNSET() - заполняет N символов строки заданным символом;

STRPBRK() - обнаруживает первое вхождение символа из одной строки в другой строке;

STRRCHR() - обнаруживает последнее вхождение данного символа в строке;

STRREV() - реверсирует строку (записывает в обратном порядке);

STRSPN() - находит в строке первую подстроку из заданной последовательности символов;

STRSTR() - обнаруживает первое вхождение данной строки в

другой строке;

STRUPR() - преобразует строку в символы верхнего регистра

(в прописные буквы);

ATOI() - преобразовывает строку в значение типа INT;

ATOF() - преобразовывает строку в значение типа DOUBLE;

ITOA() - преобразовывает значение типа INT в строку символов;

GCVT() - преобразовывает значение типа DOUBLE в строку символов.

 

Функции преобразования строк: ATOI(), ITOA(), ATOF(), GCVT()

 

Функция ATOI()

 

Формат: INT ATOI(CHAR *PTR);

 

Функция ATOI() преобразовывает строку, на которую указывает указатель PTR, в целое число. Функция распознает необязательную строку из табуляций и пробелов, необязательный знак ('+' или '-'), строку цифр. Первый неопознанный символ заканчивает преобразование. Функция возвращает искомое число типа INT, если же входная строка не может быть преобразована в число типа INT, возвращается 0.

 

Функция ATOF()

 

Формат: DOUBLE ATOF(CHAR *PTR);

 

Функция ATOF() преобразовывает строку, на которую указывает указатель PTR, в число вещественного типа двойной точности. Функция распознает: необязательную строку из табуляций и пробелов, необязательный знак ('+' или '-'), строку цифр или необязательную десятичную точку, необязательную букву 'E', за которой следует необязательное целое число со знаком. Первый неопознанный символ заканчивает преобразование. Функция возвращает искомое число типа DOUBLE. Если входная строка не может быть преобразована в число типа DOUBLE, возвращается 0.

 

Функция ITOA()

 

Формат: CHAR *ITOA(INT VALUE, CHAR *STRING, INT RADIX);

 

Функция ITOA() преобразовывает целое число, заданное параметром VALUE, в стоку символов, завершающуюся нулевым символом '\0', помещая результат в STRING. Параметр RADIX определяет основание числа VALUE и должен быть в пределах от 2 до 36. Если значение RADIX равно 10 и VALUE < 0, первым символом в строке будет знак '-'. Функция возвращает указатель на полученную строку. Функция может возвращать до 17 байтов. Размер строки STRING должен быть достаточным для того, чтобы поместить результат.

 

Функция GCVT()

 

Формат: CHAR GCVT(DOUBLE VALUE, INT NDEC, CHAR *BUFFER);

 

Функция GCVT() преобразовывает вещественное число двойной точности VALUE в стоку символов по адресу BUFFER. Буфер для размещения стоки должен быть достаточно большим, чтобы вместить преобразованное число с нулевым символом '\0', который автоматически добавляется в конец строки. Функция пытается преобразовать NDEC значимых цифр в F-представление вещественного числа. При неудаче число преобразуется в E-представление вещественного числа. Незначащие нули подавляются при преобразовании. Функция возвращает указатель на строку символов. В случае ошибки возвращаемого значения нет.

 

4. Разбор типового варианта

 

Функция заменяет символы строки из одного заданного алфавита на символы другого алфавита.

Пусть функция, которую мы создаем, будет называться change(). У нее будут два параметра: строка-источник данных и ее длина. Строка должна быть определена в той функции, которая вызывает нашу, следовательно, функции change() передается указатель на эту строку. Второй параметр должен быть целым числом, также определенным в функции main(). В итоге мы формулируем такое описание функции:

void change(char*,int)

Функция получает из программы указатель на символьную строку и ее длину. В функции должны быть описаны как константы-массивы символов две другие строки (“алфавиты”). Функция с помощью вложенных циклов последовательно сравнивает каждый элемент строки-параметра с каждым элементом строки-первого заданного алфавита и, если они совпадают, заменяет в строке-параметре этот символ на соответствующий ему символ из другого алфавита.

#include <stdio.h>

#include <string.h>

#include <conio.h>

 

void change(char *,int); // прототип функции

 

main() {

char str[81],ch;

int len;

 

clrscr();

while (ch!='n')

{

printf("введите строку\n");

gets(str);

len=strlen(str);

 

change(str,len);

 

printf("новая строка:\n%s\nпродолжить?(y/n)",str);

ch=getchar();

while(ch!='y' && ch!='n')

{

getchar();

printf("не понял...\nвведите(y/n)");

ch=getchar();

}

getchar();

}

 

return 0;

}

 

void change(char *str, int len) //функция определенная программистом

{

const char a1[]="abcdefghij"; // 1-й алфавит

const char a2[]="!@#%^&*-+="; // 2-й алфавит

int i,j;

 

for (i=0; i<len; i++)

for (j=0;j<10;j++)

if (str[i]==a1[j])

str[i]=a2[j];

}

 

Результат работы программы:

 

введите строку

abcdefghijklmnopqrstuvwxyz

новая строка:

!@#%^&*-+=klmnopqrstuvwxyz

продолжить?(y/n)y

введите строку

gfftgcvgvkkghbljk[jni

новая строка:

*&&t*#v*vkk*-@l=k[=n+

продолжить?(y/n)j

не понял...

введите(y/n)n

 

Написать программу, содержащую рекурсивную функцию Fibonachi(n), которая вычисляет n-е число Фибоначчи. Определить наибольшее число Фибоначчи, которое может быть выведено на экран. Модифицировать программу так, чтобы использовать double вместо int при вычислении и возвращении числа Фибоначчи. Использовать эту модифицированную программу для повторного определения наибольшего числа Фибоначчи, которое может быть выведено на экран.

 

#include<iostream.h>

 

double fibonachi(int n)

{

if (n>2) return fibonachi(n-2)+fibonachi(n-1);

if ((n=1)||(n=2)) return 1;

}

 

void main()

{

int n=1;

cout<<"vvedite nomer chisla Fibonachi\n";

cin>>n;

cout<<fibonachi(n)<<"\n";

}

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2018-12-19 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: