Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
A.doc
Скачиваний:
36
Добавлен:
09.04.2015
Размер:
5.6 Mб
Скачать

223 Глава 5

Это просто имя исполняемого файла .ехе программы, поэтому argc равно 1, и массив argv содержит два элемента — argv [ 0 ], указывающий на строку "DoThat. ехе", и argv [1], содержащий null.

Предположим, вы вводите в командной строке следующее:

Теперь argc равно 5, a argv содержит шесть элементов, из которых последний равен 0, а остальные пять указывают на строки:

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

Эта программа просто перечисляет переданные ей в командной строке аргументы.

У вас есть два варианта ввода аргументов командной строки. После того, как при- мер программы собран в IDE, можно открыть командное окно в папке, содержащей файл .ехе, и затем ввести имя программы с последующими аргументами командной строки. Альтернативно вы можете специфицировать аргументы командной строки в IDE, прежде чем запускать программу. Для этого просто откройте окно свойств проек- та, выбрав Projects Properties (Проект^Свойства) в главном меню, и затем разверни- те дерево Configuration Properties (Свойства конфигурации) в левой панели, щелкнув на значке "плюс" (+). Затем щелкните на папке Debugging (Отладка), чтобы увидеть на правой панели место, куда можно ввести аргументы командной строки.

Вот типичный пример запуска этого примера в командном окне:

Структурная организация программ 224

Описание полученных результатов

Во-первых, программа выводит значение argc, а затем значения каждого аргумен- та из массива argv в цикле for. Можно воспользоваться тем фактом, что последний элемент argv равен null, тогда код вывода значений аргументов будет таким:

Выполнение цикла завершится по достижении элемента массива argv [argc], ко- торый равен null.

Прием функцией переменного количества аргументов

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

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

Очевидно, что в переменном списке параметров нет информации о числе и типах аргументов, поэтому ваш код должен каким-то образом определять, что ему передано при вызове функции. Стандартная библиотека "родного" С++ определяет в заголовоч- ном файле stdarg.h макросы vastart, vaarg и vaend, которые могут в этом по- мочь. Легче всего продемонстрировать их применение на примере.

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

225 Глава 5

Этот пример сгенерирует следующий вывод:

Описание полученных результатов

Функция main () вызывает функцию sum () в двух операторах вывода, в первом случае с шестью аргументами, а во втором — с девятью.

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

Для начала обработки переменного списка аргументов объявляется указатель типа va_list:

Тип valist определен в заголовочном файле stdarg.h, и этот указатель исполь- зуется для указания на каждый аргумент в списке по порядку.

Макрос va_start служит для инициализации argptr, так что он указывает на первый аргумент в списке:

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

Значения аргументов из списка извлекаются в цикле for:

Макрос va_arg возвращает значение аргумента, находящегося по адресу arg_ptr, и увеличивает его с тем, чтобы он указывал на следующее по порядку значение. Второй аргумент макроса vaarg — тип аргумента, и он определяет интерпретацию значе- ния, которое вы получаете, а также размер инкремента argptr, потому что если он будет неправильным, вы получите хаос; программа в этом случае, возможно, будет вы- полняться, но полученные значения окажутся мусором, и argptr, увеличенный не- правильно, только породит еще больше мусора.

Когда завершается извлечение значений аргументов, с помощью следующего опе- ратора argptr сбрасывается:

Структурная организация программ 226

Макрос vaend устанавливает указатель типа va_list, который передается ему в качестве аргумента, равным null. Это нужно делать всегда, потому что после обра- ботки arg_ptr указывает на адрес, который не содержит корректных данных.

Возврат значений функциями

Все примеры функций, который вы создавали, возвращали единственное значе- ние. Можно ли вернуть что-то другое, отличное от единственного значения? Вообще- то нет, но как я уже говорил, возвращаемое единственное значение не обязательно должно быть числовым; оно может быть адресом, что является ключом к возврату лю- бого объема данных. Вы просто используете указатель. К сожалению, здесь начинают- ся ловушки, поэтому вам нужно быть заранее готовым к некоторым "приключениям".

Возврат указателя

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

До тех пор, пока заголовок функции и ее прототип правильно и согласованно указывают тип возврата, у вас нет никаких проблем — по крайней мере, никаких ви- димых проблем. Предполагая, что переменная value имеет тип double, прототип функции по имени treble, которая может содержать приведенный выше оператор return, должен быть таким:

Список параметров я указал произвольным образом.

Давайте рассмотрим функцию, возвращающую указатель. Заранее должен предупре- дить — эта функция работать не будет, но она нам понадобиться в качестве наглядного пособия. Предположим, что вам нужна функция, которая возвращает указатель на ме- стоположение в памяти, где находится значение ее аргумента, умноженное на 3. Первая попытка реализовать такую функцию могла бы выглядеть следующим образом:

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