Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Алгоритмизация и программирование. Учебное пособие для студентов направления подготовки 09.03.02 Информационные системы и технологии

.pdf
Скачиваний:
0
Добавлен:
12.08.2026
Размер:
1 Мб
Скачать

Функция не может возвращать массив или функцию, но может возвращать указатель на любой тип, в том числе на массив и на функцию.

Определения используемых функций могут располагаться после функции main() или находиться в другом файле.

Стандартный способ передачи параметров функции – передача по значению. При таком способе после вызова функции для формальных параметров выделяется некоторый объем памяти; формальные параметры инициализируются значениями фактических параметров; после выхода их функции память освобождается.

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

Ещё один способ – передача параметров по ссылке. В этом случае можно обойтись без использования явных операций с указателями.

§ 4. Объявление функции, её вызов.

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

Структура объявления функции:

<тип> <имя_функции> (<тип> [<имя_параметра>]); Имена параметров не являются обязательным элементом, но удобны при исправлении

ошибок в программе на несоответствие типов.

В отличие от определения функции, в прототипе (объявлении) за заголовком сразу ставится точка с запятой «;» и отсутствует тело функции.

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

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

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

101

#include. Сделать это можно разными способами:

подключение стандартного заголовка – #include <standart_file.h>;

подключение пользовательского файла – #include "my_file.c" Структура вызова функции:

<адресное_выражение> ([<список_выражений>]); Имя функции синтаксически – это адрес начала тела функции. Поэтому обращаясь к

функции, используют адресное выражение (это может быть имя функции, разадресация указателя на функцию), которое содержит значение адреса функции.

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

Задача 25. Объявите два целочисленных массива разных размеров и напишите функцию, которая заполняет их элементы значениями, а затем выводит эти значения на экран.

Функция должна содержать два параметра – массив и его размер.

Математическая модель и описание алгоритма решения. В данной задаче размеры массивов постоянные и определены вначале, пользователю вводить ничего не нужно.

Текст программы к задаче 25.

------------------------------------------------------------------------------------------------

#include <iostream>

using namespace std;

 

void fillShowArr(int array[], int size);

 

int main()

 

{

const int SIZE1 = 8;

const int SIZE2 = 14;

 

int array1 [SIZE1] = {};

int array2 [SIZE2] = {};

 

fillShowArr(array1, SIZE1);

fillShowArr(array2, SIZE2);

 

return 0;

 

}

void fillShowArr(int array[], int size)

{for (int i = 0; i < size; i++)

{

array[i] = i + 1;

cout << array[i] << " ";

}

cout << endl;

}

------------------------------------------------------------------------------------------------

102

В компиляторе языка С++ этот компьютерный код представлен на рис. 81.

Рис 81. Программный код задачи 25

Результат реализации программы на рис. 82:

Рис 82. Результат решения задачи 25

Задача 26. Разработайте программу, в которой объявлена рекурсивная функция, вычисляющая факториалы, начиная с 1 до заданного n. Значения факториалов выведите на экран.

Математическая модель и описание алгоритма решения. Пользователю необходимо ввести значение n. Для нахождения n! будем использовать рекурсивную функцию.

Результат выполнения программы – вычисленные факториалы от 1! до n!, выведем на

экран.

103

Текст программы к задаче 26.

------------------------------------------------------------------------------------------------

#include <iostream> using namespace std;

unsigned long int factorial(unsigned long int);// прототип рекурсивной функции int i = 1; // инициализация глобальной переменной для подсчёта кол-ва

рекурсивных вызовов

unsigned long int result; /* глобальная переменная для хранения возвращаемого результата рекурсивной функцией*/

int main(int argc, char* argv[])

{

int n; // локальная переменная для передачи введенного числа с клавиатуры cout << "\n Enter value n = ";

cin >> n;

for (int k = 1; k <= n; k++)

{

cout << " " << k << "!" << "=" << factorial(k) << endl; // вызов рекурсивной функции

}

return 0;

}

unsigned long int factorial(unsigned long int f) // рекурсивная функция для нахождения n!

{

if (f == 1 || f == 0) // базовое или частное решение return 1; // 1!=1 и 0!=1

i++;

result = f * factorial(f - 1); // функция вызывает саму себя return result;

}

------------------------------------------------------------------------------------------------

В компиляторе языка С++ этот компьютерный код представлен на рис. 83.

104

Рис 83. Программный код задачи 26

Пользователю предлагается ввести значение n (рис. 84).

Рис 84. Введение n при решении задачи 26

Результат реализации программы при n = 7 на рис. 85:

Рис 85. Результат решения задачи 26

105

Глава 9. СТРОКИ

§ 1. Строки.

В языке программирования С++ поддерживаются два типа срок – встроенный тип, который есть в С, и класс string из стандартной библиотеки С++.

Для представления символьной информации используют символы (заключены в кавычки, например, 'A'), символьные переменные (тип char) и символьные константы.

Существует специальный формат записи для элементов, не имеющих печатного символа – знак слеш (\), после которого пишут код символа.

Пример. Нулевой байт или нуль-терминатор может быть записан поразному:

char S1, S2, S3; S1 = 0;

S2 = ‘\0’;

S3 = ‘0x00’;

Строка – это последовательность символов, заключенная в двойные кавычки, например, "Programs". Символьные строки хранятся в виде массивов элементов типа char, ограниченные нуль-терминатором. Поэтому их нельзя приравнивать и сравнивать с помощью операций = и ==.

Строку можно присвоить символьному массиву с помощью операции cin. Для введения полной строки текста в С++ используют функцию cin.getline. Данная функция содержит три аргумента: массив символов, его длина и символ-ограничитель.

Пример. Введите строку текста длиной 20 символов: char str[20];

cin.getline(str, 20, '\n');

Функция cin.getline считывает символы строки до тех пор, пока не встретит ограничитель '\n', или количество символов будет меньше указанной длины 20. Ограничитель '\n' определен по умолчанию, поэтому его можно не писать.

Согласно общепринятому стандарту ASCII между символами и кодами существует соответствие. При нажатии клавиши клавиатура кодирует информацию с учетом регистра и

106

вспомогательных клавиш в соответствующий код. Поэтому действия со строками и символами – это действия с соответствующими численными кодами, а не с самими символами. Такие численные коды можно сравнивать (> или <), приравнивать друг другу, сопоставлять с другими.

§ 2. Операции со строками.

Со строками можно производить следующие действия:

создавать;

присваивать и вводить значения;

обрабатывать с помощью стандартных функций:

копировать, сравнивать, вычислять длину, преобразовывать, объединять и др. Для данных типа char определены арифметические операции +, -, *, / и операции

сравнения.

Пример.

char str[20]; // строка представлена массивом из 20 символов

char pr[20] = "Windows"; // в первые семь символов массива pr записывается слово "Windows", в восьмой символ помещается нуль-терминатор, остальные символы не определены

char tr[20] = {'W', 'i', 'n', 'd', 'o', 'w', 's', '\0'}; // данный массив эквивалентен массиву pr

char dr[ ] = "Many windows in house"; // длина массива не указана, компилятор определяет её автоматически: 21+нуль-терминатор=22 символа

char *xr; // указатель на символ

Обратите внимание, в создании переменной pr[20] = "Windows" применяется не операция присваивания, а операция инициализации!

Пример. Обычное присваивание происходит так:

pr[0] = 'W'; pr[1] = 'i'; pr[2] = 'n'; pr[3] = 'd'; pr[4] = 'o'; pr[5] = 'w'; pr[6] = 's'; pr[7] = '\0';

Ввести строку можно с помощью стандартной функции scanf.

107

Пример. Введите строку в массив TEXT: char TEXT[15];

scanf("%s", TEXT);

Здесь длина вводимой строки не должна превышать 14 символов, последний символ (пятнадцатый) компилятор заполнит нуль-оператором.

Стандартная библиотека C/C++ содержит набор функций для работы со строками (табл. 7). Для их использования необходимо включить заголовочный файл #include<string.h> и #include<ctype.h>.

Табл. 7 Функции для работы со строками

Функция

Прототип и описание

 

 

strchr

char *strchr( char *S, int g);

Определение первого вхождения символа g в строку S

 

 

 

 

int strcmp(const char *S1, const char *S2);

 

Сравнение строк S1 и S2:

strcmp

если S1 < S2, то результат отрицательный;

 

если S1 = S2, то результат равен 0;

 

если S1 > S2, то результат положительный.

 

 

 

char *strcpy(char *S1, const char *S2);

strcpy

Копирование посимвольное из строки S2 в строку S1

Важно: исходная строка не должна быть больше, чем память, выде-

 

 

ленная для второй строки.

 

 

strdup

char *strdup(const char *S);

Выделение памяти для переноса копии строки S

 

 

 

strlen

int strlen(const char *S);

Вычисление длины строки S, не считая нуль-терминатор

 

 

 

strncat

char* strncat(char *S1, char *S2, int k);

Добавление k символов строки S2 к строке S1

 

 

 

strncpy

char *strncpy(char *S1, const char *S2, int k);

Копирование k символов строки S2 в строку S1

 

 

 

strnset

char *strnset(char *S, int k, int m);

Замена первых k символов строки S символом m

 

 

 

strncmp

int strncmp(const char *S1, const char *S2, size_t n);

 

 

108

 

Сравнение первых n символов строк S1 с первыми n символами

 

строки S2

 

 

 

char *strlwr(char *S);

strlwr

Преобразование строки S в символы нижнего регистра (в строчные

 

буквы)

 

 

 

char *strupr(char *S);

strupr

Преобразование строки S в символы верхнего регистра (в прописные

 

буквы)

 

 

strpbrk

char *strpbrk(char *S1, const char *S2);

Определение первого вхождения символа из строки S1 в строку S2

 

 

 

strrchr

char *strrchr(char *S, int n);

Определение последнего вхождения символа n в строке S

 

 

 

strrev

char *strrev(char *S);

Переворот строки S

 

 

 

strstr

char *strstr(const char *S1, const char *S2);

Определение первого вхождения строки S2 в строку S1

 

 

 

sprintf

int sprintf(char *S, const char *format, ...)

Форматированный вывод в строку, на которую указывает S

 

 

 

sscanf

int sscanf(char *S, const char *format, ...)

Считывание данных из массива, указанного S

 

 

 

atoi

int atoi(char *S);

Преобразование строки в целое число

 

 

 

atof

float atof(char *S);

Преобразование строки в число с плавающей точкой

 

 

 

 

char *itoa(int n, char *S, int R);

itoa

Преобразование целого числа n в строку; возвращает указатель на

строку; параметр R определяет основание системы счисления (от 2

 

 

до 36)

 

 

 

std::string P = “Hello”;

append

P.append(“ , world!”);

 

 

Добавление к строке P = “Hello” строки “ , world!”

 

 

109

Обратите внимание, язык программирования С++ плохо совместим с русскими символами. Поэтому при работе со строками рекомендуется использовать английские символы при вводе.

Задача 27. Введите предложение и затем удалите все пробелы из него.

Математическая модель и описание алгоритма решения. Пользователю необходимо ввести количество слов в предложении, которое он хочет преобразовать, а затем эти слова через пробелы, как в предложении.

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

Текст программы к задаче 27.

------------------------------------------------------------------------------------------------

#include <iostream> using namespace std;

int main()

{

string str; string res;

int count_of_words;

cout << "Enter a number, the number of words per line: "; cin >> count_of_words;

cout << "\n" << "Enter sentence: "; for (int i = 0; i < count_of_words; i++)

{

cin >> str; res.append(str);

}

cout << res;

return 0;

}

------------------------------------------------------------------------------------------------

В компиляторе языка С++ этот компьютерный код представлен на рис. 86.

110

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]