При чтении документации важно понимать заголовки функций. Описание со временем меняется. Для примера рассмотрим описание функции fread() в старой документации для Unix:
#include
freadlptr, sizeof(*ptr), nitems, stream)
FILE ‘stream;
Сначала включается подходящий файл. Типы для fread(), ptr, sizeof (*рtr) и nitems не указаны. В то время для этих элементов по умолчанию принимался тип int, но контекст проясняет тот факт, что ptr является указателем. (В ранних версиях С указатели обрабатывались как целые числа.) Аргумент stream объявлен как указатель на FILE. Объявление создает впечатление, что в качестве второго аргумента применяется операция sizeof. В действительности здесь указано, что значением этого аргумента должен быть размер объекта, указанного с помощью ptr. Часто будет использоваться операция sizeof, как показано выше, но с точки зрения синтаксиса допускается любое значение типа int.
Позже форма изменилась следующим образом:
#include
int freadlptr, size, nitems, stream,};
char *ptr;
int size, nitems;
FILE *stream;
Теперь все типы данных заданы явно, a ptr трактуется как указатель на char.
Стандарт ANSI С90 предоставляет такое описание:
#include
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
Во-первых, в нем применяется новый формат прототипа. Во-вторых, некоторые типы изменились. Тип size t определен как целочисленный тип без знака, возвращаемый операцией sizeof. Обычно им будет либо unsigned int, либо unsigned long. Файл stddef.h содержит определение typedef или #define для size_t, как и несколько других файлов, в том числе stdio.h, обычно за счет включения stddef .It Многие функции, включая fread(), часто встраивают операцию sizeof в виде части фактического аргумента. Тип size_t обеспечивает соответствие формального аргумента этому общему способу использования.
Кроме того, в ANSI С применяется указатель на void в качестве своего рода обобщенного указателя для ситуаций, когда могут использоваться указатели на разные типы данных.
Препроцессор и библиотека С 693
Например, первым аргументом функции fread() может быть указатель на массив значений double или на некоторую структуру. Если фактический аргумент представляет собой указатель, скажем, на массив из 20 значений double, а формальный аргумент является указателем на void, компилятор примет вариант для подходящего типа и не уведомит о несоответствии типов.
Относительно недавно стандарты С99/С11 внедрили в описание функций новое ключевое слово restrict:
#include
size_t fread(void * restrict ptr, size_t size,
size_t nmemb, FILE * restrict stream);
А теперь давайте перейдем к обзору некоторых специфических функций.
Библиотека математических функций
Библиотека математических функций содержит множество удобных функций такого рода. Их объявления или прототипы содержатся в заголовочном файле math.h. В табл. 16.2 перечислено несколько функций, объявленных в math.h. Обратите внимание, что все углы измеряются в радианах (один радиан составляет 180/Pi = 57.296 градуса). В разделе V приложения Б представлен полный список функций, определенных стандартом С99.
Таблица 16.2. Некоторые стандартные математические функции ANSI С

694 глава 16
Немного тригонометрии
Воспользуемся библиотекой математических функций для решения типичной задачи преобразования прямоугольных координат в полярные (модуль и угол). Предположим, что на сетке проведена линия, протяженность которой составляет 4 единицы по горизонтали (значение х) и 3 единицы по вертикали (значение у). Каковы длина (модуль) и направление линии? Согласно тригонометрии:
модуль = квадратный корень (х 2+ у 2)
и
угол = арктангенс (у/х)
Библиотека math предоставляет функцию извлечения квадратного корня и пару функций вычисления арктангенса, поэтому вы можете выразить данное решение на языке С. Функция извлечения квадратного корня, sqrt(), принимает аргумент double и возвращает квадратный корень аргумента также в виде значения double.
Функция atan() принимает аргумент double и возвращает угол, значение тангенса которого равно этому аргументу. К сожалению, функция atan() не учитывает квадрант вектора. Например, если координаты х и у вектора равны -5 и -5, функция atan() даст результат 45°, поскольку (-5)/(-5) = 1. Тот же результат будет для вектора с координатами 5 и 5. Другими словами, функция atan() не различает векторы, углы которых отличаются на 180°. (На самом деле функция atan() выводит результат в радианах, а не в градусах; мы обсудим это преобразование позже.)
К счастью, библиотека С содержит и функцию atan2(). Она принимает два аргумента: значения х и у. Таким образом, функция способна анализировать знаки коор дииат и правильно определять угол. Подобно atan() , функция atan2() возвращает угол в радианах.
Читать дальше