4.6.8 Неопределенное число параметров.

   


Назад  |  Вперёд

Существуют функции, в описании которых невозможно указать число и типы всех допустимых параметров. Тогда список формальных параметров завершается эллипсисом (...), что означает: "и, возможно, еще несколько аргументов". Например:

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


Назад  |  Вперёд


OtDiatlovaOU
К началу книги

Оформление и дизайн книги OtDiatlovaOU.
Вся книга, архив.

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

Rambler's Top100
Hosted by uCoz