Форум программистов, компьютерный форум CyberForum.ru

Функции с переменным числом аргументов - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ где РЕАЛИЗАЦИЯ класса string? http://www.cyberforum.ru/cpp-beginners/thread158414.html
объявление нашёл, а реализацию нет..
C++ Как преобразовать часть массива char в double есть большой массив char в нем есть несколько элементов которые нужно преобразовать в число типа double например char X; X='0'; X='.'; X='5'; http://www.cyberforum.ru/cpp-beginners/thread158393.html
C++ Эмулятор CHIP-8
Мы с fasked написали простенький эмулятор для платформы CHIP-8. CHIP-8 Остались вопросы по графике и клавиатуре. Если кто знает как реализовать - помогите, пожалуйста. Так же приглашаем для участия в доработке этого проекта, а так же следующих проектах всех, кто желает учиться и трудиться. Кому интересна работа эмулятора все вопросы к fasked) Полный проект в прикрепленном архиве в сообщении...
C++ Написать перегруженные функции.
Написать перегруженные функции и протестировать их в основной программе: А) перевода минут, часов и секунд в секунды; Б) перевода секунд в часы минуты секунды.
C++ Не устанавливается VC++6 Professional Edition http://www.cyberforum.ru/cpp-beginners/thread158303.html
Подскажите пожалуйста, при установке VC++6 Professional Edition выдаёт сообщение: Не найден файл D:\Mein Programen\VISUAL~1\VISUAL~1.EDI\acmboot.exe или один из его компонентов. Проверьте правильность пути и имени файла, а также наличие необходимых библиотек. Следующее сообщение:Couldn't find Acme setup У мени установлен Windows XP SP3. Пробовал несколько разных установочных пакетов....
C++ Функция, формирующая массив Ребят тпомогите написать программу, подскажите с чего начать... Вот задание - Функция, формирующая новый массив, упорядоченный по неубыванию, из двух массивов-параметров, уже упорядоченных по неубыванию. Заранее благодарен подробнее

Показать сообщение отдельно
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
11.08.2010, 22:33     Функции с переменным числом аргументов
Итак.
Никакой информации от разработчика языка по поводу использования func(...) без параметров
Страуструп. Язык программирования С++
Существуют функции, в описании которых невозможно указать число
и типы всех допустимых параметров. Тогда список формальных
параметров завершается эллипсисом (...), что означает:
"и, возможно, еще несколько аргументов". Например:

int printf(const char* ...);

При вызове printf обязательно должен быть указан параметр
типа char*, однако могут быть (а могут и не быть) еще другие
параметры. Например:

printf("Hello, world\n");
printf("My name is %s %s\n", first_name, second_name);
printf("%d + %d = %d\n", 2,3,5);

Такие функции пользуются для распознавания своих фактических
параметров недоступной транслятору информацией. В случае функции
printf первый параметр является строкой, специфицирующей формат вывода.
Она может содержать специальные символы, которые позволяют правильно
воспринять последующие параметры. Например, %s означает -"будет
фактический параметр типа char*", %d означает -"будет фактический
параметр типа int" (см. $$10.6). Но транслятор этого не знает, и
поэтому он не может убедиться, что объявленные параметры действительно
присутствуют в вызове и имеют соответствующие типы. Например,
следующий вызов

printf("My name is %s %s\n",2);

нормально транслируется, но приведет (в лучшем случае) к неожиданной
выдаче. Можете проверить сами.
Очевидно, что раз параметр неописан, то транслятор не имеет сведений
для контроля и стандартных преобразований типа этого параметра.
Поэтому char или short передаются как int, а float как double, хотя
пользователь, возможно, имел в виду другое.
В хорошо продуманной программе может потребоваться, в виде
исключения, лишь несколько функций, в которых указаны не все типы
параметров. Чтобы обойти контроль типов параметров, лучше использовать
перегрузку функций или стандартные значения параметров, чем
параметры, типы которых не были описаны. Эллипсис становится
необходимым только тогда, когда могут меняться не только типы, но
и число параметров. Чаще всего эллипсис используется
для определения интерфейса с библиотекой стандартных функций на С,
если этим функциям нет замены:

extern "C" int fprintf(FILE*, const char* ...);
extern "C" int execl(const char* ...);

Есть стандартный набор макроопределений, находящийся в <stdarg.h>,
для выбора незаданных параметров этих функций. Рассмотрим функцию
реакции на ошибку, первый параметр которой показывает степень тяжести
ошибки. За ним может следовать произвольное число строк. Нужно
составить сообщение об ошибке с учетом, что каждое слово из него
передается как отдельная строка:

extern void error(int ...)
extern char* itoa(int);

main(int argc, char* argv[])
{
switch (argc) {
case 1:
error(0,argv[0],(char*)0);
break;
case 2:
error(0,argv[0],argv[1],(char*)0);
break;
default:
error(1,argv[0],
"With",itoa(argc-1),"arguments",(char*)0);
}
// ...
}

Функция itoa возвращает строку символов, представляющую ее целый
параметр. Функцию реакции на ошибку можно определить так:

#include <stdarg.h>

void error(int severity ...)
/*
за "severity" (степень тяжести ошибки) следует
список строк, завершающийся нулем
*/
{
va_list ap;
va_start(ap,severity); // начало параметров

for (; {
char* p = va_arg(ap,char*);
if (p == 0) break;
cerr << p << ' ';
}

va_end(ap); // очистка параметров

cerr << '\n';
if (severity) exit(severity);
}

Вначале при вызове 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*). Этот пример демонстрирует
все те сложности, с которыми приходится сталкиваться
программисту, если он решил обойти контроль типов, используя
эллипсис.
Добавлено через 17 минут
Собственно вот. Линк: Тут

Функции без аргументов и с неизвестными аргументами
При описании функции, отсутствие аргументов в скобках означает, что их нет, а не что они неизвестны (как в Си). В Си++ записи f() и f(void) строго равносильны.

Если количество или типы некоторых аргументов неизвестны, надо заменить их многоточием. При этом:

хотя бы один аргумент должен быть известен (иначе откуда функция узнает количество и типы аргументов?)
Известные аргументы должны быть в начале списка
void f(); // функция без аргументов
void g(void); // тоже функция без аргументов
int printf(const char* fmt, ...); // функция с неизвестными аргументами
int sprintf(char* s, const char* fmt, ...); // ещё одна
// int bad1(...); // Неправильно! Нужен хотя бы один известный аргумент. (Стандарт позволяет, проверьте!)
// int bad2(..., char* fmt); // Неправильно! Известные аргументы должны быть в начале списка
Доступ к дополнительным аргументам такой функции в ее теле требует средств из stdarg.h

При совместном использовании нескольких функций та, что имеет многоточие в параметрах, считается хуже всех других при выборе, какую именно функцию звать (т.е. используется только тогда, когда ни одна без многоточия не подошла).
 
Текущее время: 18:42. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru