Программирование >>  Процедурные приложения 

1 ... 54 55 56 [ 57 ] 58 59 60 ... 150


пользователем с клавиатуры, но не воспринимает символ новой строки \n. Исправляет ситуацию функция cin. get (cnewline) .

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

psz = new char[ISTRING MAX]; pi = new int; pf = new float;

Следующее выражение предназначено для считывания введенной строки текста, длина которой не может превышать значение, заданное константой istring max, - 50 символов:

cin.get(psz, ISTRING MAX) ;

Поскольку функция cin . get() ожидает в качестве первого аргумента указатель на строку, при вызове функции voutput( ) нет необходимости выполнять операцию раскрытия указателя:

voutput (psz, cresponse) ;

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

voutput(psz,cresponse);

voutput(pi,cresponse);

voutput(pf,cresponse);

Функция voutput() воспринимает все эти аргументы независимо от их типа только благодаря тому, что в объявлении функции указан параметр типа void*. Напомним, что для извлечения содержимого указателей, заданных как void*, их сначала нужно привести к конкретному типу данных, например char*.

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

Подробнее об указателях и массивах

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

Строки (массивы типа char)

Многие операции со строками в языках C/C++ выполняются с применением указателей и арифметических операций над ними, поскольку доступ к отдельным символам строки осуществляется, как правило, последовательно. Следующая программа на языке C++ является модификацией рассмотренной ранее в этой главе программы для вывода строки-палиндрома:

chrarray.c

Эта программа на C++ выводит на экран массив символов в обратной

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

#include <iostream.h> #include <string.h> void main () {

char pszpalindrome[] = Дом мод ; char *pc;

pc = pszpalindrome + (strlen(pszpalindrome) - 1);

do {

cout << *pc; pc-- ;

} while (pc >= pszpalindrome); }



После объявления и инициализации массива pszpalindrome создается указатель рс типа char*. Вспомните, что имя массива само по себе является адресом. Сначала указателю рс присваивается адрес последнего символа массива. Это осуществляется с помощью функции strlen(), которая возвращает длину массива символов.

Функция strlen() не учитывает символ окончания Строки \0.

Почему от полученной длины массива отнимается единица? Не забывайте, что первый элемент массива имеет нулевое смещение, т.е. ею индекс равен 0, а не 1. Поэтому вывод следует выполнять начиная с индекса, на единицу меньшего, чем количество символов в массиве.

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

Массивы указателей

В языках C/C++ имеется еще одна интересная возможность - создавать массивы указателей. Такой массив представляет собой совокупность элементов, каждый из которых является указателем на другие объекты. Эти объекты, в свою очередь, также могут быть указателями.

Концепция построения массивов указателей на указатели широко используется при работе с параметрами argc и argv функции main() , с которыми вы познакомились в главе Функции . В следующей программе определяется максимальное или минимальное из значений, введенных в командной строке (ожидается ввод неотрицательных чисел). Аргументами могут быть либо только числа, либо, в дополнение к ним, специальная опция, задающая режим работы: поиск минимального (-s, -S) или максимального (-l, -L) значений.

argcargv.cpp

Эта программа на языке C++ демонстрирует работу с массивами указателей

на указатели на примере параметров argcи argvфункции main().

#include <iostream.h>

#include <process.h> exit()

#include <stdlib.h> atoi()

#define IFIND LARGEST 1 #define IFIND SMALLEST 0

#define IMAX32767

int main(int argc, char *argv[]) f char *psz; int ihow many;

int iwhich extreme = IFIND SMALLEST; int irange boundary = IMAX; if(argc-- < 2) {

cput<< \nВведите одну из опций -S, -s,-L, -l

<< и, как минимум, одно целое число. ; exit(l); }

if ((*++argv) [0] == -) {

psz = argv[0] + 1; switch (*psz) {

case s : case S:

iwhich extreme = IFIND SMALLEST;

irange boundary = IMAX;

break;

case l:

case L:

iwhich extreme = IFIND LARGEST; irange boundary =0;



break; default:

cout << Нераспознанныйаргумент << *psz <<, \n ; exit(1) ;

if(*++psz != \0){

cout<< Нераспознанный аргумент << *psz << \n ; exitfl.); )

if (--argc == 0) {

cout<< Введите как минимум одно число\п ;

exit(l); }

argv++; } ihow many = argc; while (argc-- ) { int present value; present value = atoi(*argv++);

if(iwhich extreme .== IFIND LARGEST && present value >

irange boundary) irange boundary = present value;

if(iwhich extreme == IFIND SMALLEST S& present value <

irange boundary) irange boundary = present value; }

cout << ( (iwhich extreme) ? Максимальное : Минимальное );

cout<< значение в ряду из << ihow many

<< введенных чисел =

<< irange boundary << \n ;

return(0); }

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

argcargv argcargv98 argcargv98 21 argcargv -s 98 argcargv -S 98 21

argcargv -l 14 argcargv -L 14 67

Напомним, что параметр а где функции main() представляет собой целое число, равное количеству аргументов командной строки, включая имя программы. Параметр argvпредставляет собой указатель на массив строковых указателей.

Примечание

Параметр argv не является константой. Напротив, это переменная, чье значение может быть изменено. Об этом важно помнить при изучении работы программы. Первый элемент массива - argv[0] - является указателем на строку символов, содержащую имя программы.

В первую очередь в программе проверяется, не является ли значение параметра argc меньшим 2. Если это так, значит, пользователь ввел в командной строке только имя программы без аргументов. По-видимому, пользователь не знает назначения программы или того, какие аргументы должны быть заданы в командной строке. Поэтому программа отобразит на экране информацию о своих аргументах и завершится выполнением функции exit().Обратите внимание, что после выполнения проверки счетчик аргументов уменьшается на единицу (argc--). К моменту начала цикла while счетчик должен стать равным количеству числовых аргументов, заданных в командной строке, здесь же мы уменьшили его на единицу, чтобы учесть аргумент, содержащий имя программы.

Затем происходит обращение к первому символу второго аргумента, и если полученный символ является дефисом, то программа определяет, какая именно опция, -s или -l, задана в командной строке. Заметьте, что к указателю массива argv сначала добавляется единица (++argv), в результате чего аргумент с именем программы (первый элемент массива)



1 ... 54 55 56 [ 57 ] 58 59 60 ... 150

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика