
- •Федеральное агентство по образованию
- •Краткая история языка с
- •Особенности и основные понятия языка Си
- •Структура программы
- •Типы данных
- •Классификация типов данных
- •Вещественные
- •Логический
- •Диапазоны представления данных
- •Объявление переменных
- •Константы в языке Си
- •Операции языка Си. Приоритет операций
- •Операция присваивания
- •Арифметические операции
- •Операции отношения
- •Логические операции
- •Поразрядные операции
- •Операцияsizeof
- •Операция выбора по условию
- •Операция запятая
- •Приведение типов Неявное преобразование типов
- •Явное преобразование типов
- •Основные средства ввода-вывода на Си Понятие потока
- •Стандартные потоки
- •Функции потокового ввода-вывода
- •Функции ввода
- •Ввод символов
- •Ввод строк
- •Форматированный ввод
- •Операторы языка Си
- •Оператор if
- •Оператор switch
- •Оператор while
- •Оператор do while
- •Оператор for
- •Оператор break
- •Оператор continue
- •Функции вывода на экран
- •Вывод символов
- •Функция вывода строк puts()
- •Форматированный вывод
- •Указатели в языке Си
- •Адресная арифметика
- •Массивы
- •Функции в языке с
- •Прототипы функций
- •Указатели типа void
- •Функции, возвращающие указатели
- •Встраиваемые функции
- •Рекурсивные функции
- •Функции с переменным числом аргументов
- •Аргументы функции main()
- •Область действия и область видимости
- •Локальные переменные
- •Локальные переменные в функции Main()
- •Глобальные переменные
- •Классы памяти
- •Указатели на указатели
- •Указатели и многомерные массивы
- •Массивы указателей
- •Указатели на функции
- •Операции над строками символов Определение длины строки
- •Копирование строк
- •Поиск в строках
- •Преобразования символов в строках
- •Другие функции для работы со строками
- •Преобразования строк в числа
- •Преобразования чисел в строки
- •Функции анализа символов
- •Распределение памяти
- •Манипулирование блоками памяти
- •Типы, определяемые пользователем
- •Перечислимый тип
- •Структуры
- •Сложные структуры
- •Битовые поля в структурах
- •Объединения
- •Работа с файлами Связь между потоками и файлами
- •Типы дисковых файлов
- •Открытие файла
- •Запись и чтение данных
- •Форматированный ввод-вывод Форматированный вывод
- •Int fprintf (file *fp, char *fmt, ...);
- •Форматированный ввод
- •Символьный ввод
- •Символьный вывод
- •Блочный ввод-вывод
- •Закрытие файла
- •Директивы препроцессора
- •Директива #include
- •Директива #define
- •Директивы условной компиляции
- •Директива #undef
- •Предопределенные макросы
- •69 Лекции по курсу «Языки программирования» Часть III
Прототипы функций
Особенностью стандарта 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);