Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование / WORD / Лекции по ЯП (часть 3).doc
Скачиваний:
138
Добавлен:
15.04.2015
Размер:
1.34 Mб
Скачать

Прототипы функций

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

Синтаксис прототипа функции:

тип <имя функции>(список параметров);

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

или так: int func(int a, float b, char* с);

или так: int func(int, float, char*);

Два этих объявления абсолютно равносильны.

Если функция не имеет аргументов, то при объявлении прототипа такой функции следует вместо аргументов писать ключевое слово void.

Это должно касаться и функции main(). Ее объявление должно иметь вид:

void main(void) или main(void).

Прототипы стандартных функций находятся в заголовочных файлах (header files). Примерами таких заголовочных файлов являются файлы stdio.h, string.h. Кроме этого в заголовочных файлах находятся отдельные определения, которые используются функциями.

Указатели типа void

Ключевое слово void в заголовках и прототипах функций, означают что функции не принимают никаких аргументов, либо не возвращают никаких значений.

Указатель типа void – это нетипизированный указатель:

Пример:

void *ptr;

Указатель ptr указывает на какой-то объект памяти с временно неопределенным типом.

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

Пример.

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

void half(void *val);

Однако, перед тем как выполнять операции над объектом по указателю, необходимо определить его тип. Это делается с помощью приведения типа.

Пусть pval — указатель типа void. Тогда приведение его типа выполняется следующим образом:

(тип *)pval

тип – тип данных, к которому приводится указатель. Например, чтобы привести указатель pval к типу int, запишем следующее: (int *)pval.

Чтобы обратиться по указателю pval к значению типа int, используется следующее выражение:

*(int *)pval

Т.о., чтобы воспользоваться указателем, функция должна иметь информацию о том, на значение какого типа он указывает. Т.е. необходимо сообщить функции тип переменной из четырех возможных - int, long, float, double.

Определение функции можно изменить, например, следующим, образом:

Void half(void *pval, char type);