Библиотечные функции языка Си

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

Можно создавать функции, количество параметров у которых при компиляции определения функции не определено. Кроме того могут быть не известными и типы параметров. Количество и типы параметров становятся известными только в момент вызова функции, когда явно задан список фактических параметров.

Формат заголовка такой функции:

Тип имя (спецификация_явных_параметров, …)

Явные параметры обязательные. Многоточие после запятой извещает компилятор, что дальнейший контроль соответствия количества и типов параметров при обработке вызова функции проводить не нужно.

Пример:

long summa (int k, …)

{

int *p=&k;

long t=0;

for(;k;k--)t+=*(++p);

return t;

}

У каждой функции c переменным количеством параметров есть механизм определения количества и типов списка параметров функции при ее вызове. Существует два подхода:

1) Предусматривает передачу в функцию значения реального количества фактических параметров. Значения реального количества используемых фактических параметров можно передавать в функцию с помощью одного из явно задаваемых параметров.

2) Предполагает добавление в конец списка реально использованных фактических параметров специального параметра-индикатора с уникальным значением, которое будет сигнализировать об окончании списка. В теле функции параметры последовательно перебираются, и их значения сравниваются с заранее известным концевым признаком.

В обоих подходах переход от одного фактического параметра к другому выполняется с помощью указателей.

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

Пример

#include <stdio.h>

long summa (int k, …) //k - число суммируемых параметров

{

int *p=&k;

long t=0;

for(; k; k--) t+=*(++p);

return t;

}

main()

{

long r,p;

r=summa(2,6,4);

p=summa(6,1,2,3,4,5,6);

printf (“r=%d\n”,r);

printf (“p=%d\n”,p);

}

Результат выполнения программы:

r=10

p=21

Для доступа к списку параметров используется указатель p типа int*. Вначале ему присваивается адрес явно заданного параметра k, т.е. он устанавливается на начало списка параметров в памяти (в стеке). Затем в цикле указатель p перемещается по адресам следующих фактических параметров, соответствующих неявным формальным параметрам. С помощью операции (* p) выполняется выборка их значений. Параметром цикла суммирования служит аргумент k, значение которого уменьшается на 1 после каждой итерации и, наконец, становится равным 0.

Особенность функции – возможность работы только с целочисленными фактическими параметрами, так как указатель p после обработки значения очередного параметра перемещается вперед на величину sizeof(int) и должен быть всегда установлен на начало следующего параметра.

Следующий пример содержит функцию для вычисления произведения переменного количества параметров. Признаком окончания фактических параметров служит параметр с нулевым значением ( т.е. по второму подходу ).

Пример

#include <stdio.h>

double prod (double arg, …)

{

double aa = 1.0; // Формируемое произведение

double *p=&arg; // Настроили указатель на первый параметр

if(*p == 0.0) return 0.0;

for(; *p; p++) aa*=*p;

return aa;

}

void main()

{

double r, p;

r=prod(2.0, 4.0, 3.0, 0.0);

p=prod(1.4, 3.0, 0.0, 16.0);

printf (“r=%d\n”,r);

printf (“p=%d\n”,p);

}

Результат выполнения программы:

r=9.0

p=4.4

В функции prod перемещение указателя p по списку фактических параметров выполняется всегда за счет изменения p на величину sizeof(double). Поэтому все фактические параметры при обращении к функции prod должны иметь тип double. В вызовах функции проиллюстрированы некоторые варианты задания параметров. Обратите внимание на вариант с нулевым значением параметра в середине списка. Параметры вслед за этим значением игнорируются.

Чтобы функция с переменным количеством параметром могла воспринимать параметры различных типов, необходимо в качестве исходных данных каким-то образом передавать ей информацию о типах параметров. Для однотипных параметров возможно, например, такое решение – передавать с помощью дополнительного обязательного параметра признака типа параметров. Запишем функцию, выбирающую минимальное из значений параметров, которые могут быть двух типов: или только long, или только int. Признак типа параметра будем передавать как значение первого обязательного параметра. Второй обязательный параметр определяет количество параметров, из значений которых выбирается минимальное. В следующей программе предложен один из вариантов решения сформулированной задачи:

#include <stdio.h>

long minimum (char z, int k, …)

{

if(z==’i’)

{

int *pi=&k+1; // настроили на первый необязательный параметр

int min =*pi; // значение первого необязательного параметра

for (; k; k--, pi++)

min = min >*pi? *pi: min;

return (long) min;

}

if(z==’l’)

{

long *pl = (long*)(&k+1);

long min = *pl; // Значение первого параметра

for (;k;k--,pl++)

min = min >*pl? *pl: min;

return (long)min;

}

printf(“неверно задан 1-й параметр”);

return 2222L;

}

void main()

{

long p,p1;

p=minimum(‘l’,2,10L,20L);

p1=minimum(‘i’, 3,11,2,3);

}

Библиотечные функции языка Си

Стандартной библиотекой языка Си (также известная как libc, crt) называется часть стандарта ANSI C, посвященная заголовочным файлам и библиотечным функциям. Является описанием реализации таких операций как:

- файловый и консольный ввод-вывод;

- обработка строк;

- вычисление математических функций;

- конвертация типов данных.



Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: