115
return a-b;
}
int main()
{
int a=10,b=10,t;
int (*f)(int,int); /* объявление функциональной переменной */
clrscr();
printf("fplus
адрес %p\n",fplus);
printf("fminus
адрес %p\n",fminus);
f=fplus; /* сопоставляем f первую функцию */
t=f(10,10);
printf("Вызываем %p., получаем %d\n",f,t);
f=fminus; /* сопоставляем f первую функцию */
t=f(10,10);
printf("Вызываем %p, получаем %d\n",f,t);
return 0;
}
Говоря о функциях в Си, нельзя не отметить такую особенность языка, как
функции с переменным числом аргументов. Мы уже пользовались ими —
нетрудно заметить, что printf и scanf принимают произвольное число
выводимых или вводимых значений. А может ли программист
самостоятельно создать подобные функции? Следующий пример это
иллюстрирует:
/* среднее арифметическое переменного числа аргументов */
double f(double n, ...) /* заголовок с
переменным числом
параметров */
{
double *p = &n; /* --
установили на начало списка */
double sum = 0, count = 0;
while (*p) /* пока аргумент не равен нулю */
{
sum+=(*p); /* cуммируем */
p++; /* берем следующий аргумент */
count++; /* подсчет количества аргументов */
116
}
return ((sum)?sum/count:0); /*
вычисляем среднее */
}
Есть одно обстоятельство, которое ограничивает применение таких
функций. Передача аргумента не того типа, который задумывался, или не
тем способом, который подразумевался при разработке, приведет к
катастрофическим последствиям — компилятор Си ничего не проверяет.
Для доступа к списку параметров в примере использован указатель,
значением которого будет адрес последнего явного параметра в списке.
Чтобы перейти к адресу следующего параметра, надо изменить значение
этого указателя. Это означает, что программист при разработке функции с
переменным числом параметров должен отчетливо представлять себе типы
аргументов, которые будет обрабатывать функция. Кроме того, способ
передачи параметров должен быть одинаковым для всех параметров: либо
все по значению, либо все по указателю.
Как в программе указать, каково фактическое число переданных
параметров? Это можно сделать одним из двух способов:
явно передать среди обязательных параметров количество аргументов;
добавить в конец списка аргумент с уникальным значением, по
которому будет определяться конец списка параметров;
И тот, и другой способ имеют право на жизнь — все определяется
потребностями задачи и вкусами программиста. В примере использован
второй способ: последним значением списка параметров считается ноль.
Еще одной интересной особенностью Си являются
смеси и
битовые поля,
представляющие собой особые разновидности структур. Под полем
понимается последовательность соседних битов внутри одного целого
значения, что позволяет обращаться к выделенным частям одного
машинного слова.
Достарыңызбен бөлісу: