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

Если список типов аргументов не завершен многоточием, а передается больше фактических аргументов, чем объявлено имен в списке, то компилятор выдаст предупреждающее сообщение в СП 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 задан список типов аргументов. В примере типы фактических аргументов соответствуют и списку типов аргументов, и списку формальных параметров.

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

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

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

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

<p><strong>Рекурсивные вызовы</strong></p>

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

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

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

<p><strong>ДИРЕКТИВЫ ПРЕПРОЦЕССОРА И УКАЗАНИЯ КОМПИЛЯТОРУ</strong></p><p><strong>Введение</strong></p>
Перейти на страницу:

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

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных