Читаем Язык программирования Си для персонального компьютера полностью

Если список типов аргументов не завершен многоточием, а передается больше фактических аргументов, чем объявлено имен в списке, то компилятор выдаст предупреждающее сообщение в СП MSC и сообщение об ошибке в СП ТС.

Если список типов аргументов содержит специальное имя типа void, то компилятор языка Си ожидает отсутствие фактических аргументов в вызове функции и отсутствие формальных параметров в определении функции. Если какое-либо из этих условий окажется нарушено, то компилятор языка Си выдает предупреждающее сообщение в СП MSC и сообщение об ошибке в СП ТС.

Если в списке типов аргументов используются модификаторы near, far, huge, то компилятор языка Си может также выполнить неявно преобразования аргументов-указателей к соответствующему формату (см. раздел 4.7.3 "Преобразования типов при вызовах функций").

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

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

Пример:

main()

{

void swap(int *, int *);

int x, у;

swap(&x, &y);

}

void swap(int *a, int *b)

{

int t;

t = *a;

*a = *b;

*b = t;

}

В функции main функция swap объявлена как не возвращающая значения, с двумя аргументами типа указатель на int. Формальные параметры а и b также объявлены как указатели на int. При вызове функции

swap(&x, &y)

адрес х запоминается в а, адрес у запоминается в b. Выражения *a и *b в функции swap ссылаются на переменные х и у в main. Присваивания внутри функции swap изменяет содержимое х и у. Компилятор языка Си проведет проверку типов аргументов при вызове swap, поскольку в предварительном объявлении swap задан список типов аргументов. В примере типы фактических аргументов соответствуют и списку типов аргументов, и списку формальных параметров.

Вызов функции с переменным числом аргументов

Для вызова функции с переменным числом аргументов не требуется никаких специальных действий: в вызове функции просто задается то число аргументов, которое нужно. В предварительном объявлении (если оно есть) переменное число аргументов специфицируется записью запятой с последующим многоточием (,…) в конце списка типов аргументов (смотри раздел 3.5). Аналогично, список параметров в определении функции может также заканчиваться запятой с последующим многоточием (,…), что подразумевает переменное число аргументов (см. раздел 6.2.4).

Все аргументы, заданные в вызове функции, размещаются в стеке. Количество формальных параметров, указанных в определении функции, определяет количество аргументов, которые берутся из стека и присваиваются формальным параметрам. В случае переменного числа аргументов программист сам контролирует реальное количество аргументов, находящихся в стеке, и отвечает за выбор из стека лишних аргументов (сверх объявленных).

См. описания макроопределений va_arg, va_end, va_start, которые могут быть полезны при работе с переменным числом аргументов.

Рекурсивные вызовы

Любая функция в Си-программе может быть вызвана рекурсивно; в частности, она может вызвать сама себя. Компилятор не ограничивает число рекурсивных вызовов одной функции. При каждом вызове новые ячейки памяти выделяются для формальных параметров и локальных переменных класса памяти auto и register, так что их значения в предшествующих, незавершенных вызовах недоступны и не портятся.

Для переменных, объявленных на внутреннем уровне с классом памяти static или extern, новые ячейки памяти не выделяются при каждом рекурсивном вызове. Выделенная им память сохраняется в течение всего времени выполнения программы.

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

ДИРЕКТИВЫ ПРЕПРОЦЕССОРА И УКАЗАНИЯ КОМПИЛЯТОРУ

Введение

Перейти на страницу:

Похожие книги

Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript
Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript

Данная книга посвящена программированию игр с помощью ActionScript. Здесь вы найдете подробные указания, необходимые для создания самых разных игр – аркад, головоломок, загадок и даже игровых автоматов. В тексте приведены исходные коды программ и детальные, доступно изложенные инструкции. Базовые принципы программирования ActionScript рассматриваются на примере игр, однако вы без труда сможете применить полученные знания и для разработки неигровых проектов, таких как Web-дизайн и реклама. Рекомендации Гэри Розенцвейга помогут вам не только придумывать занимательные игры и размещать их на Web-сайте, но и оптимизировать скорость их работы, а также защищать свои творения от несанкционированного копирования. Представленный в книге код несложно изменить для использования в других программах.Книга предназначена для широкого круга читателей – создателей анимационных роликов, художников-оформителей, программистов и разработчиков Web-сайтов. Издание может также выступать в качестве практического пособия по изучению ActionScript.

Гэри Розенцвейг

Программирование, программы, базы данных / Программирование / Книги по IT
Секреты приложений Google
Секреты приложений Google

Даже продвинутые пользователи Интернета не подозревают о тех огромных возможностях, которые предоставляют сервисы Google. Автор рассказывает о таких «секретах» сервисов, которые просто немедленно хочется использовать! Создавать сайты и презентации, бродить по улочкам Парижа, изучать звездное небо – все это доступно каждому, кто сидит у экрана монитора и имеет доступ в Интернет. Книга научит вас работать с веб-приложениями и тысячекратно увеличить свои возможности с помощью новейших технологий. Она написана легким, доступным языком и не требует от читателя наличия каких-либо специальных знаний. Книга содержит множество примеров, иллюстраций и будет полезна всем, кто не стоит на месте и стремится сделать свою жизнь более насыщенной и интересной.

Денис Балуев , Денис Игоревич Балуев

Программирование, программы, базы данных / Интернет / Программное обеспечение / Книги по IT