Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2009 лекции ПЯВУ часть1.doc
Скачиваний:
22
Добавлен:
27.03.2015
Размер:
823.3 Кб
Скачать

6.11 Неопределенное количество аргументов

Иногда при работе с функцией неизвестно [3], какое число аргументов она будет фактически принимать. Например, так работают функции printf и scanf библиотеки stdio.h.

Для создания пользовательской функции с неопределенным количеством аргументов нужно подключить библиотеку stdarg.h, где определены необходимые структуры и функции. В объявлении функции с неопределенным числом параметров используется многоточие («эллипсис»), означающее «и еще, возможно, несколько аргументов». До него перечисляются точно известные параметры.

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

#include <stdarg.h>

#include <iostream>

using namespace std;

int test(char*,...);

int main()

{

test("Hello!",(char*)0);

test("Hello", "world!", (char*)0);

test("Just", "simple", "test",(char*)0);

return 0;

}

int test(char* first,...)

{

va_list ap;

va_start(ap, first);

cout<<first<<endl;

char* p = va_arg(ap,char*);

while(p)

{

cout<<p<<endl;

p = va_arg(ap,char*);

}

va_end(ap);

return 0;

}

Рис. 6.29. Использование функции с неопределенным количеством аргументов

Есть стандартный набор макроопределений, находящийся в <stdarg.h>, для выбора незаданных параметров этих функций. В начале функцииtestпри вызовеva_start()определяется и инициализируетсяva_list. Параметрами макроопределенияva_startявляются имя типаva_listи последний формальный параметр. Для выборки по порядку неописанных параметров используется макроопределениеva_arg(). В каждом обращении кva_argнужно задавать тип ожидаемого фактического параметра. Вva_arg()предполагается, что параметр такого типа присутствует в вызове, но обычно нет возможности проверить это. Перед выходом из функции, в которой было обращение кva_start, необходимо вызватьva_end. Причина в том, что вva_start()могут быть такие операции со стеком, из-за которых корректный возврат из функции становится невозможным. Вva_end()устраняются все нежелательные изменения стека. Приведение0к(char*)0необходимо потому, чтоsizeof(int)не обязано совпадать сsizeof(char*). Этот пример демонстрирует все те сложности, с которыми приходится сталкиваться программисту, если он решил обойти контроль типов, используя эллипсис.

Тема 7 Введение в обработку строк

7.1. Работа со строками в с

Понятие символов и строк в с

Символы– это фундаментальные стандартные блоки исходных программ на С++ [1]. Каждая программа составлена из последовательности символов, которые, если их объединение в группу имеет смысл, интерпретируются компилятором как последовательности инструкций, используемых для выполнения задачи. Программа может содержать символьные константы.Символьная константа– это целое значение, представленное как символ в одинарных кавычках. Значение символьной константы – это целочисленное значение в наборе машинных символов. Например,‘z’представляет собой целое значениеz, а‘\n’представляет собой целое значение символа перехода на новую строку.

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

Строка может включать буквы, цифры, и разнообразные символы, например, такие как +, -, *, / , $ и другие.

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