|
Программирование >> Элементы языков с и с++
После того как первый элемент перешлется, в теле while произойдет приращение значений указателей на единицу, которое позволит обратиться к следующему элементу объекта. Программа снова возвратится в заголовочную часть while, обеспечивающую пересылку второго элемента в область, на которую указывает s (и т. д., пока не будет переслан последний элемент - признак конца массива). При этом значение выражения в заголовочной части while станет равным нулю, и оператор while завершит работу. Функция char *strsave (char *s) копирует строку символов, на которую указывает указатель s, в буфер памяти, вьщеляемый стандартной функцией mallocO, и возвращает указатель на начало этого буфера, чтобы в дальнейшем можно было извлекать сохраненную в нем строку. Копирование производится с помощью ранее рассмотренной функции strcpy2 о. Работа происходит следующим образом: длина исходной строки с учетом признака конца строки определяется с помощью стандартной функции strlen (). Затем по функции malloc () выделяется участок памяти такого же размера, как длина входной строки. Перед тем как начать копирование с использованием указателя, возвращенного функцией malloc о, проверяется, успешно ли сработала эта функция (т. е. действительно ли выделено место в памяти). Это существенный вопрос, т. к. свободной памяти в данный момент могло не оказаться или мог произойти какой-либо сбой. Если память выделена, то malloc () возвращает ненулевой указатель типа void, который требуется привести к типу char, т. к. в вьщеленном буфере будет размещен объект типа char. После выделения памяти происходит собственно копирование в буфер и возврат указателя на область копирования. При пояснении основной программы стоит обратить внимание только на проверку strcpy2 (). Так как эта функция работает с указателями, то ей мы и передаем указатели: адреса первых элементов массивов. Результат расчета приведен на рис. 7.4. > C:\WINPOWS\system32\cmd.exe Enter string for strcpyl >quer inp.strins=4wer out .string=qvjer 1 nter string for strcpy2 >1234 input string=1234 uutput string=1234 Enter string for strsave>lq2u3e Saved string=lq2vj3e !1ля продолжения нажмите любую клавишу Передача в качестве аргумента функции массивов размерности больше единицы До сих пор мы передавали в качестве аргумента функции только одномерный массив. Можно передавать и массивы большей размерности. Если, например, двумерный массив передается в качестве аргумента функции, то его описание, как аргумента функции, может быть следующим: int m[2] [13]; int m[] [13]; Здесь m указывает на начало массива, поэтому компилятору достаточно знать только количество столбцов массива и начало его первого элемента. Другой вариант описания: int (*m) [13]; Здесь m указывает на начало массива. Массивы указателей Мы видели, что с помощью массива, объявленного, например, как char M[n][m], можно задавать множество символьных строк постоянной длины. Иначе и не задать, потому что компилятор не сможет найти заданный элемент массива. Однако в жизни чаще всего приходится работать со строками переменной длины. Тогда жесткая конструкция двумерного массива для их хранения не подойдет. Для решения этой проблемы существует конструкция, называемая массивом указателей. Создается одномерный массив, элементами которого служат указатели на заданный тип данных. Например, массив char *s[iO]; - это десять указателей (s [ о], s [ i ],..., s [ 9 ]), каждый из них указывает на строку, которая может быть переменной длины. Такой массив формируется так: в некоторой памяти размещается первая строка, ее адрес заносится в s [О]. Затем размещается вторая строка, ее адрес заносится в S [1] и т. д. Чтобы обратиться к элементам такого массива, нужно воспользоваться определением указателя. Обратиться к нулевому элементу нулевой строки следует как *s[0], к первому элементу той же строки как s[0]++ и т. д. К нулевому элементу первой строки нужно обратиться как s[i], к ее первому элементу как *s [1] ++ и т. д. Указатели на функции в языке С возможно определять указатели на функции и, следовательно, обрабатывать указатели, передавать их в качестве аргумента другим функциям и т. д. При объявлении указатель на функцию записывается в виде: <Тип возвращаемого функцией значения> (*имя функции) (список параметров). Например: int (*comp)(char si,char s2); Это указатель на функцию comp(si,s2), которая возвращает результат типа int. Если мы подействуем операцией разыменования (*) на этот указатель (по определению указателя записав воздействие в виде (*сотр) (si,s2)), то функция сотр (si, s2) выполнится и возвратит некое целое число. Ранее мы видели, что имена массивов можно передавать в качестве аргументов функции. Теперь, поскольку есть указатели на функции, функции можно передавать в качестве аргументов другим функциям. В таких функциях и.\ аргументы-функции описываются как указатели на функции, а передача функций в качестве аргументов происходит указанием имени самой функции. Все остальное улаживает компилятор. То есть с функциями, при передаче их в качестве аргументов другим функциям, происходит то же, что и с массивами: их имена считаются внешними переменными. Приведем пример функции genero, которая имеет своими параметрами две функции: ввода Инициализация массива указателей на строки символов, например, char *s [3]; будет выглядеть так: char *s[3]={ Первая строка символов , Вторая строка символов , Третья строка символов }; В чем же различие между записями, например, int n[iO] [20] и int *b[iO]? Под первый вариант компилятор выделяет 200 единиц памяти. И поиск элемента этого массива производится путем вычисления обычных прямоугольных индексов. При втором варианте (если предположить, что и там строки содержат по 20 элементов) под них также будет выделено 200 единиц памяти, но еще понадобится память для хранения десяти указателей. То есть памяти при втором варианте размещения данных требуется больше. Но это неудобство перекрывается тем, что в таких конструкциях можно хранить строки переменной длины, и что доступ к таким строкам происходит напрямую - по их адресам, без вычисления индексов массивов.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |