Задание для индивидуальной работы



1. Составить алгоритм решения задачи.

2. Разработать программу, осуществляющую ввод исходных данных, необходимые вычисления и вывод результатов.

3. Разработать несколько тестовых наборов исходных данных и испытать программу на компьютере.

4. Составить отчет по практической работе.

 

Варианты заданий

1.Разработать программу, которая формирует случайным образом в диапазоне [-99, 99] одномерный целочисленный массив из N элементов (Nвводится) и определяет количество и процентное соотношение положительных, отрицательных и нулевых элементов.

 

2. Разработать программу, которая формирует одномерный целочисленный массив из N элементов, заданных случайными числами на промежутке [a; b). Значения N, a, bвводятся с клавиатуры. Заменить все элементы массива, кратные 3, на сумму их цифр.

3.N точек на плоскости заданы своими координатами, значения которых формируются случайным образом. Значение N вводится пользователем. Разработать программу для нахождения пары самых удаленных друг от друга точек.

4. Разработать программу, которая вводит последовательность вещественных чисел и находит частное средних арифметических значений элементов с нечетными и четными индексами.

 

5. Разработать программу, позволяющую в целочисленной матрице поменять местами в каждой строке наибольший и наименьший ее элементы. Значения элементов матрицы генерируются случайным образом в диапазоне [-99; 99], размеры матрицы вводятся пользователем.

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

7. Разработать программу выбора из заданного на плоскости множества точек N (Nвводится) трех точек, не лежащих на одной прямой, составляющих треугольник наименьшей площади. Координаты точек формируются программой случайным образом.

8. Дана целочисленная квадратная матрица размера n´m(n, mвводятся). Значения элементов матрицы задаются случайным образом в диапазоне [-99, 99]. Разработать программу, позволяющую находить сумму элементов матрицы, расположенных выше главной диагонали и ниже побочной диагонали.

 

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

10. Объявите двумерный целочисленный массив, в котором n ´ m элементов. Выполните генерацию массива случайными целыми числами из промежутка [a; b). Значения n ,m, a, bвводятся с клавиатуры. Выведите массив в виде таблицы. Найдите суммы элементов массива по строкам. Выведите найденные суммы по образцу:

Сумма элементов 0-й строки равна …

Сумма элементов 1-й строки равна ….

.

11. Объявите двумерный целочисленный массив, в котором n строк по m элементов. Выполните генерацию массива случайными целыми числами из промежутка [a; b). Значения n, m, a, bвводятся с клавиатуры. Переставьте столбцы массива так, чтобы их максимальные элементы образовали возрастающую последовательность. Выведите массив на экран в виде таблицы дважды – до и после перестановки.

12. Объявите двумерный целочисленный массив, в котором n ´ m элементов. Выполните генерацию массива случайными целыми числами из промежутка [a; b). Значения n, m, a, bвводятся с клавиатуры. Замените в массиве максимальные элементы каждой строки произведением их цифр. Выведите массив в виде таблицы дважды: до и после замены.

13. Разработать программу вычисления значений функции  на отрезке [a, b] с шагом h(значения a, b, hвводятся с клавиатуры). Результат представить в виде таблицы, первый столбец которой – значения аргумента, второй – значения функции.

14. Разработать программу поиска из введенной последовательности целых чисел максимальной по длине монотонной подпоследовательности (если таких подпоследовательностей несколько, то программа находит только одну из них).

15. Одномерный целочисленный массив размером m, где m – натуральное число, заполнен случайным образом. Найдите в массиве моду. Модой называется элемент ряда, который встречается наиболее часто.

16. Дан одномерный вещественный массив из N элементов (N – нечетное), заданных случайными числами на промежутке [a; b). Значения N, a, bвводятся с клавиатуры. Поменять местами элементы, симметричные относительно центрального.

17. Дан одномерный целочисленный массив из N элементов, заданных случайными числами на промежутке [a; b). Значения N, a, bвводятся с клавиатуры. Поменять местами первый минимальный и последний максимальный элементы массива.

18. Разработать программу, которая формирует матрицу размером mxn (m и n вводятся с клавиатуры, элементы матрицы – случайные целые числа, распределенные по равномерному закону на интервале [-99, 99]), находит среднее арифметическое элементов матрицы, расположенных на главной диагонали и увеличивает каждый элемент матрицы на эту величину.

19. Разработать программу поиска максимального элемента среди минимальных элементов строк целочисленной матрицы размером nxm. Значения элементов матрицы формируются случайным образом в диапазоне [a, b] (значения n, m, a, b вводятся).

20. Разработать программу заполнения квадратной матрицы размера n xn (n вводится) по спирали натуральными числами от 1 до , начиная с левого верхнего угла и двигаясь по часовой стрелке.

 

Практическая работа № 7: Указатели.

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

Общая форма объявления переменной типа указатель:

тип *имя_указателя;

Здесь тип означает базовый тип указателя, который определяет, на переменные какого типа может ссылаться объявленный указатель. Им можетбыть любой допустимый в языке Cтип. Формально указатель любого типа можетссылаться на произвольный адрес памяти. Однако указание базового типа важно для правильной работы адреснойарифметики (рассматривается дальше).

Символ * обозначает, что объявляется именно указатель, а не переменная заданного типа.

Пример объявления указателя на целое число:

int * ptr;

Существуют два специальных оператора для работы с указателями: оператор адресации &и оператор разыменования *.

Оператор & является унарным и возвращает адрес своегооперанда.

Например, приведённый во второй строчке кода оператор присваивания

intx = 5;

ptr = &x;

записывает в указатель ptr адрес переменной x.

Если переменная занимает несколько ячеек памяти, ее адресом считается адрес первой ячейки.

Оператор разыменования * является обратным оператору&. Этот унарный оператор возвращает значение, хранящееся по указанному адресу. Например, если указатель ptr содержит адрес переменной x, то оператор присваивания

y = *ptr;

поместит значение x в переменную y. Следовательно, переменная y станет равной 5, поскольку именно это число записано в ячейке, адрес которой хранится в указателе ptr.

Посредством указателей можно косвенно изменять значения переменных, на которые они указывают (без прямого доступа по имени переменной). В следующей строчке кода значение переменной xменяется на 7.

*ptr = 7;

Приоритет операторов & и * выше, чем приоритет всехарифметических операторов, за исключением унарного минуса.

Указатель можно присваивать другому указателю. Рассмотрим пример:

intx = 5;

int *p1, *p2;

p1 = &x;

p2 = p1;

printf("Переменная x = %d хранится по адресу %p\n", x, &x);

printf("По адресу %p хранится значение %d", p2, *p2);

Здесь на переменную x ссылаются оба указателя p1 и p2. С помощью функции printf() на экран выводятся значение и адрес переменной x. Для вывода адреса используется форматный спецификатор %p.

Следует особо остановиться на правилах использования при объявлении указателя квалификатора (модификатора) const. Как известно, квалификатор const превращает переменную в константу, значение которой не должно менятьсяв процессе выполнения программы. Например, нет смысла изменять число π. Значение константы должно быть инициализировано в месте ее определения. С указателями же может возникнуть неоднозначная ситуация: что именно не должно изменяться сам указатель или переменная, на которую он указывает. В связи с этим различают указатели на константы и константные указатели. Рассмотрим следующий пример:

doublevalue = 10.5;

constdouble *pvalue = &value;

Последняя строчка данного кода представляет собой указатель на константу. Попытка изменить значение переменной value черезссылающийся на него указатель pvalue будет восприниматься компилятором как ошибка. Но само значение переменной value изменять допустимо. Также можно записать в pvalue адрес другой переменной.Указатели на константы часто используются как формальные параметры функций (рассматриваются далее).

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

intvalue = 15;

int *constpvalue = &value;

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

intvalue = 15;

constint *constpvalue = &value;

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

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

ptr++;

переменная ptr будет равна не 2, а 5, поскольку при увеличении указателя ptr на единицу он ссылается на следующее целое число. Это же относится и к оператору декремента. Например, если указатель ptr равен 10, выражение

ptr--;

присвоит указателю ptrзначение 6.

Таким образом, существуют следующие правила адреснойарифметики. При увеличении указатель ссылается на ячейку, вкоторой хранится следующий элемент базового типа. При уменьшении он ссылается на предыдущий элемент. Для указателей насимволы сохраняются правила "обычной" арифметики, посколькуразмер символов равен 1 байт. Все остальные указатели увеличиваются или уменьшаются на длину соответствующих переменных,на которые они ссылаются. Это гарантирует, что указатели всегдабудут ссылаться на элемент базового типа.

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

ptr = ptr + 15;

смещает указатель ptr на 12-й элемент базового типа, расположенный после текущего адреса.

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

Между указателями и массивами существует тесная взаимосвязь. Имя массива является указателем на первый его элемент. Допустим, объявлен одномерный целочисленный массивm и указательна целое ptr:

intm[10], *ptr;

В таком случае два последующих оператора эквивалентны:

ptr = m;

ptr = &m[0];

Подобным образом, используя адресную арифметику, адрес второго элемента массива можно записать как &m[1] или m+1. В общем случае адрес (i+1) – го элемента массива всегда можно записать либо как &m[i], либо как (m+i), а получить доступ к его значению либо через индексное выражение m[i], либо через адресное *(m+i). В последнем случае наличие скобок обязательно, поскольку приоритет оператора разыменования выше, чем у сложения.

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

int m[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, i;

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

{

printf("&m[%d] = %p, m + %d = %p, m[%d] = %d, *(m + %d) = %d\n", i, &m[i], i, m + i, i, m[i], i, *(m + i));

}

При этом надо иметь в виду, что имя массива является константным указателем. Поэтому такие выражения как m, (m+i), &m[i] не могут находиться в левой части оператора присваивания. В частности, не допускаются выражения типа

m++;

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

С указателями можно использовать операторы сравнения. Сравнивать указатели допустимо только с другими указателями того же типа или с константой NULL, обозначающей значение условного нулевого адреса. Константу NULL можно присвоить переменной-указателю любого типа. Оно представляет собой целое число нуль и говорит о том, что указатель ни на что не ссылается. Особое значение имеет сравнение двух указателей, которые связаны с одним и тем же массивом данных.Например, если mэто массив, то m (или &m[0])всегда меньше, чем m+1 (или &m[1]). Если же два указателя ссылаются на одну и ту же область памяти – они считаются равными.

В языке Cвозможны ситуации, когда указательссылается на другой указатель. Такая схема называется двухуровневой адресацией. Глубина многоуровневой адресации не ограничена, однако почтивсегда можно обойтись "указателем на указатель". Более громоздкие схемы адресации труднее понять, следовательно, вероятность ошибок при их использовании резко возрастает.

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

float **ptr;

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

int x, *p, **p2;

x = 10;

p = &x;

p2= &p;

printf("%d", **p2); /* Вывод числа х */

Здесь переменная p объявлена как целочисленный указатель, а переменная p2 представляет собой указатель на целочисленный указатель.

Основываясь на способе представления одномерных массивов в виде указателя (имя массива) и смещения (индекс), можно подобным образом записать представление многомерных массивов. Это возможно потому, что многомерный массив фактически является набором одномерных массивов. Например, двумерный массив можно представить как указатель на группу следующих один за другим одномерных массивов, т.е. указатель на указатель. Исходя из этого, выражение *(m+i)+jопределяет адрес элемента m[i][j], а выражение *(*(m+i)+j) – его значение.

Задания для самостоятельной работы:Написать программу, проверяющую, является ли введенная строка палиндромом (читается одинаково слева направо и справа налево). Для этого:

1. объявите массив символов для хранения введенной пользователем строки и два указателя на символ;

2. сделайте так, чтобы первый указатель ссылался на первый символ строки, а второй на последний, учитывая тот факт, что строка оканчивается нуль-символом ’\0’;

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

Практическая работа № 8: Динамическое распределение памяти.

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

Для динамического распределения используется свободная область памяти в адресном пространстве программы, которую принято называть кучей (heap). В зависимости от принятой модели памяти и операционной среды выполнения программы, куча может быть расположена, либо между границами сегментов данных и стека, либо за верхней границей стека. Требуемые объемы памяти могут распределяться из кучи по адресам сегмента данных. Распределенная память кучи может быть освобождена и становится доступной для повторных распределений. В современных операционных системах прямое обращение за границу сегмента данных блокируют средства защиты памяти. Требуемый доступ в пространство адресов кучи обеспечивает механизм динамического распределения памяти.

Для прикладной реализации механизма динамического распределения памяти в стандарте языка C предусмотрены функции malloc, calloc, free и realloc. Программный интерфейс этих функций обеспечивает заголовочный файл <stdlib.h>, где декларированы типы их аргументов и кода возврата.

Функция malloc позволяет динамически распределить блок памяти заданного размера. Спецификация формата ее вызова имеет вид:

void* malloc(unsigned size);

Функция malloc реализует просмотр свободных блоков из кучи, чтобы найти сплошное пространство памяти, размер которого в байтах не меньше, чем задано параметром size. В случае успеха она возвращает адреса первого свободного блока памяти достаточного размера. Полученный адрес следует использовать для доступа к содержимому выделенного блока памяти после явного преобразования типа. Если требуемый объем памяти не может быть выделен, или значение параметра size равно 0, функция malloc возвращает нулевой указатель NULL.

Функция calloc обеспечивает динамическое распределение памяти кучи под массив элементов. Спецификация формата ее вызова имеет вид:

void* calloc(unsigned num, unsigned size);

Через аргументы num и size в функцию calloc передаются требуемое число элементов и размер каждого элемента массива. Таким образом, суммарный объем памяти, выделенный при обращении к функции calloc, равен (num*size) байтов. Все элементы выделенного массива автоматически инициализируются нулевыми значениями. При успешном завершении функция calloc возвращает адрес динамически распределенного массива. Если требуемый объем памяти не может быть выделен, или значения аргументов равны 0, функция calloc возвращает нулевой указатель NULL.

Эффективность динамического распределения памяти определяет не только способность выделить точно такой объем памяти, какой нужен в программе, но и возможность освобождать распределенную память, когда информация в ней перестает быть необходима. Чтобы освобождать динамически выделенную память, в системе программирования C предусмотрена функция free. Формат ее вызова имеет вид:

void free(void* ptr);

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

В некоторых прикладных программах требуется изменять размер динамически распределенной памяти. Необходимую регулировку размера распределенной памяти выполняет функция realloc. Спецификация формата ее вызова имеет вид:

void* realloc(void* ptr, unsigned size);

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

При нулевом значении параметра размера size действие функции realloc эквивалентно вызову функции free. Когда в функцию realloc вместо адреса блока ptr передается нулевой указатель NULL, ее действие эквивалентно вызову malloc. При ненулевых аргументах она комбинирует вызовы функций malloc и free. Внутренний вызов функции free освобождает блок памяти, адресуемый указателем ptr. Вместо него внутренний вызов функции malloc распределяет новый блок памяти c заданным размером size, где содержимое старого блока сохраняется в максимально возможном объеме.

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

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

В следующем примере с помощью функции malloc() или calloc()сначала выделяется блок памяти для хранения 15целых чисел. Затем,используя функцию realloc(), данный блок увеличивается до размеров, достаточных для размещения 20целых чисел. По окончании работы с динамическим массивом выделенная память освобождается вызовом функции free(). Применение оператора sizeof для определения размера типа данных гарантирует машинонезависимость программы.Статический унарный оператор sizeof вычисляет длину операнда в байтах. Операндом может быть как отдельная переменная,так и имя типа, заключенное в скобки.

#include<stdio.h>

#include<conio.h>

#include<stdlib.h>

 

int main(void)

{

int *p, i;

 

p = (int*) malloc(15 * sizeof(int));

//p = (int*) calloc(15, sizeof(int));

if(!p)

{

       printf("Ошибка при распределении памяти\n");

       exit(1);

}

 

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

{

       *(p + i) = i + 1;

}

 

p = (int*) realloc(p, 20 * sizeof(int));

if(!p)

{

       printf("Ошибка при перераспределении памяти\n");

       exit(1);

}

 

for(i = 15; i < 20; i++)

{

       *(p + i) = i + 1;

}

 

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

{

       printf("m[%d] = %d\n", i + 1, *(p + i));

}

 

free(p);

 

getch();

return 0;

}

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

Практическая работа № 9: Стандартные функции для работы с символами и строками.

Единственным видом строки, предусмотренным в языке C, является массив символов, завершающийся нулевым байтом.

Объявляя массив символов для хранения строки, следует зарезервировать однуячейку для нулевого байта, то есть указать размер, на единицубольше, чем длина наибольшей предполагаемой строки. Например,чтобы объявить массив str, предназначенный для хранения строки,состоящей из 10 символов, следует выполнить следующий оператор:

char str[11];

Строка символов, заключенных в двойные кавычки, называется строковой константой. Компилятор автоматически добавляет к нейнулевой байт, поэтому программист может не беспокоиться обэтом:

char str[] = "Строковая константа";

Для выполнения операций ввода/вывода символов и строк в стандартной библиотеке языка C предусмотрены отдельные функции, определенные в заголовочном файле stdio.h. Ниже приведены прототипы этих функций с кратким описанием.

int getchar(void) – возвращает следующий символ из стандартного потока ввода или EOF в случае достижения конца файла или обнаружения ошибки.

int putchar(int c) – записывает символ, содержащийся в младшем байте параметра c, в стандартный поток вывода.

char*gets(char*s) – считывает следующую строку из стандартного потока ввода в массив s, заменяя символ конца строки на нуль-символ, и возвращает s принормальномзавершенииили NULL, если достигнут конец файла или обнаружена ошибка.

intputs(constchar*s) – записывает строку s и символ конца строки в стандартный поток вывода и возвращает EOF в случае ошибки или неотрицательное число при нормальном завершении.

В заголовочном файле сtype.h объявляются функции, предназначенные для анализа символов. Аргумент каждой из них имеет тип int и должен представлять собой либо EOF, либо unsigned char, приведенный к int. Возвращаемое значение тоже имеет тип int. Функции возвращают ненулевое значение (истина), если аргумент судовлетворяет соответствующему условию или принадлежит указанному классу символов, и нуль (ложь) в противном случае.

isalnum(c) – истинно isalpha(с) или isdigit(с).

isalpha(с) – истинно isupper(с) или islower(с).

iscntrl(c) – управляющий символ.

isdigit(с) – десятичная цифра.

isgraph(с) – отображаемый символ, за исключением пробела.

islower(с) – буква нижнего регистра.

isprint(с) – отображаемый символ, в том числе пробел.

ispunct(с) – отображаемый символ, за исключением пробела, буквы или цифры.

isspace(с) – пробел, прогон страницы, конец строки, возврат каретки, табуляция, вертикальная табуляция.

isupper(с) – буква верхнего регистра.

isxdigit(с) – шестнадцатеричная цифра.

Помимо перечисленных, есть еще две функции, изменяющие регистр букв:

int tolower(int с) –переводитсвнижнийрегистр.

int toupper(int с) – переводитсвверхнийрегистр.

В стандартной библиотеке языка C имеются две группы функций для работы со строками, определенных в заголовочном файле string.h. Имена функций первой группы начинаются с str, а второй – с mem. За исключением memmove, результат работы функций не определен, если выполняется копирование объектов, перекрывающихся в памяти. Функции сравнения воспринимают аргументы как массивы элементов типа unsigned char.

Ниже приведены прототипы этих функций (переменные s и t принадлежат к типу char*, cs и ct – к типу const char*, n – к типу size_t, а сявляется числом типа int, приведенным к типу char).

char*strcpy(s,ct) – копирует строку ct в строку s, включаянуль-символ; возвращаетs.

char*strncpy(s,ct, n) – копирует не более n символов строки ct в s; возвращает s. Дополняет результат нуль-символами, если в ct меньше n символов.

char*strcat(s,ct) – присоединяет ct в конец строки s; возвращает s.

char*strncat(s,ct,n) – присоединяет не болееn символов строки ct к s, завершая sнуль-символом; возвращает s.

intstrcmp(cs,ct) – сравнивает строки cs и ct; возвращает <о, если cs<ct; о, если cs==ct; и >о, если cs>ct.

intstrncmp(cs,ct,n) – сравнивает не более n символов строк cs и ct.

char*strchr(cs,c) – возвращает указатель на первое вхождение с в cs или null при отсутствии такового.

char*strrchr(cs,c) – возвращает указатель на последнее вхождение с в cs или null при отсутствии такового.

size_tstrspn(cs,ct) – возвращает длину начального участка cs, состоящего из символов, которые входят в строку ct.

size_tstrcspn(cs,ct) – возвращает длину начального участка cs, состоящего из символов, которые не входят в строку ct.

char*strpbrk(cs,ct) – возвращает указатель на первый символ в строке cs, который совпадает с одним из символов, входящих в строку ct, или null, если такого не оказалось.

char *strstr(cs,ct) – возвращает указатель на первое вхождение строки ct в строку cs или null, если не найдено ни одного.

size_tstrlen(cs) – возвращает длину строки cs.

Функции семейства mem... предназначены для манипулирования объектами как массивами символов. Они образуют интерфейс к быстродействующим системным функциям. В приведенной ниже таблице параметры s и t относятся к типу void*; cs и ct – к типу const void*; n – к типу size_t; а параметр спредставляет собой число типа int, приведенное к типу char.

void* memcpy(s, ct, n) – копирует n символов из ct в s и возвращает s.

void* memmove(s, ct, n) – делает то же самое, что и memcpy, но работает корректно также в случае перекрывающихся в памяти объектов.

int memcmp(cs, ct, n) – сравнивает первые n символов cs и ct; возвращает те же результаты, что и функция strcmp.

void* memchr(cs, с, n) – возвращает указатель на первое вхождение символа с в cs или null, если он отсутствует среди первых n символов.

void* memset(s, с, n) – помещает символ св первые n позиций массива s и возвращает s.

Заголовочный файл stdlib.h объявляет следующие функции, предназначенные для преобразования строк в числа.

double atof(const char* s) – переводит s в double.

int atoi(const char* s) – переводит s в int.

int atol(const char* s) – переводит s в long.

В следующем примере определяется длина и размер в байтах заданных строк.

#include<stdio.h>

#include<conio.h>

#include<string.h>

 

int main (void)

{

char str[] = {'A','B','C','D','\0'};

char str2[] = "hello, world\0";

 

puts(str);

puts(str2);

 

printf("Длинапервойстроки: %i\n", strlen(str));

printf("Размер первой строки: %i\n", sizeofstr);

printf("Длина второй строки: %i\n", strlen(str2));

printf("Размер второй строки: %i\n", sizeofstr2);

 

_getch();

return 0;

}

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


Дата добавления: 2018-04-05; просмотров: 651; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!