Форекс

Плотность газа при нормальных условиях. Плотность природного газа при нормальных условиях

Функции printf() и scanf() дают нам возможность взаимодействовать с программой. Мы называем их функциями ввода-вывода. Это не единственные функции, которыми мы можем воспользоваться для ввода и вывода данных с помощью программ на языке Си, но они наиболее универсальны. Эти функции входят в описание языка Си и они даны в библиотеке stdio.h. Обычно функции printf() и scanf() работают во многом одинаково - каждая использует управляющую строку и список аргументов. Сначала мы рассмотрим работу функции printf(), затем scanf().

Формат

Тип выводимой информации

десятичное целое число

один символ

строка символов

экспоненциальная запись

число с плавающей точкой, десятичная запись

используется вместо записи %f или %e

десятичное целое число без знака

восьмеричное целое число без знака

шестнадцатеричное целое число без знака

Инструкции, передаваемые функции printf(), когда мы хотим напечатать некоторую переменную, зависят от того, какого типа эта переменная. Например, при выводе на печать целого числа применяется формат %d, а при выводе символа - %c. Форматы перечислены в таблице.

Посмотрим теперь, как эти формы применяются:

/* печать */

#include

#define PI 3.14159

int number = 2003;

printf("Интернет-университет информационных технологий был открыт в %d году \n", number);

printf("Значение числа pi равно %f.\n", PI);

Формат, указываемый при обращении к функции printf(), выглядит следующим образом:

printf(Управляющая строка, аргумент1, аргумент2,_);

аргумент 1, аргумент 2 и т.д. - это печатаемые параметры, которые могут быть переменными, константами или даже выражениями , вычисляемыми перед выводом на печать.

Управляющая строка - строка символов, показывающая, как должны быть напечатаны параметры. Например, в операторе

printf("%d студентов получили оценку %f.\n",

управляющей строкой служит фраза в кавычках, а number и z - аргументы или в данном случае значения двух переменных.

Мы видим, что в управляющей строке содержится информация двух различных типов:

    Символы, печатаемые текстуально.

    Идентификаторы данных, называемые также спецификациями преобразования .

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

printf("Эта книга не очень дорогая!\n");

printf("%c%d\n","$",cost);

Если нужно напечатать сам символ %, то компилятор примет его за ошибочную спецификацию преобразования . Выходом из создавшейся ситуации служит довольно простое решение - писать два символа % подряд.

Например:

printf("Только %d%% населения способно учиться самостоятельно! \n",i);

Результат работы программы будет выглядеть следующим образом:

Только 5% населения способно учиться самостоятельно!

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

Модификаторы

Значение

Аргумент будет печататься с левой позиции поля заданной ширины. Обычно печать аргумента оканчивается в самой правой позиции поля. Пример: %-10

строка цифр

Задает минимальную ширину поля. Большее поле будет использоваться, если печатаемое число или строка не помещается в исходном поле Пример: %4d

строка цифр

Определяет точность: для типов данных с плавающей точкой число печатаемых цифр справа от десятичной точки; для символьных строк - максимальное число печатаемых символов Пример:

%4.2f(две десятичные цифры для поля шириной в четыре символа)

Соответствующий элемент данных имеет тип long, а не int Пример: %ld

printf("/%d/\n",135);

printf("/%2d/\n",135);

printf("/%10d/\n",135);

printf("/%-10d/\n",135);

Первая спецификация преобразования %d не содержит модификаторов. Это так называемый выбор по умолчанию, т. е. результат действия компилятора в случае, если вы не дали ему никаких дополнительных инструкций. Вторая спецификация преобразования - %2d. Она указывает, что ширина поля должна равняться 2, но, поскольку число состоит из трех цифр, поле автоматически расширяется до необходимого размера. Следующая спецификация %10d показывает, что ширина поля равна 10. Последняя спецификация %-10d также указывает ширину поля, равную 10, а знак - приводит к сдвигу всего числа к левому краю.

Стандартная библиотека C/C++ включает ряд функций для чтения и записи на консоли (клавиатура и монитор). Эти функции читают и пишут данные как простой поток символов.

Понятие потока (stream), использованное в программировании, тесно связано с обычным, бытовым пониманием этого слова. Поток ввода можно сравнить с трубой, по которой вода (информация) поступает в бассейн (память компьютера), поток вывода - с трубой, по которой вода выходит из бассейна. Важной особенностью этой трубы является то, что в каждый момент времени данные могут двигаться только в одном направлении. Даже если одна и та же труба используется для ввода и вывода, это не может происходить одновременно: для переключения направления потока его нужно остановить, выполнить некие действия и лишь затем направить поток в обратном направлении. Другой особенностью потока является то, что он почти никогда не иссякает. Иногда он высыхает, но этот период не может быть долгим, если система функционирует нормально.

Функция стандартного вывода printf()

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

Функция printf() имеет прототип в файле stdio.h
int printf(char *управляющая строка, ...);

В случае успеха функция printf() возвращает число выведенных символов.

Управляющая строка содержит два типа информации: символы, которые непосредственно выводятся на экран, и спецификаторы формата, определяющие, как выводить аргументы.

Функция printf() это функция форматированного вывода. Это означает, что в параметрах функции необходимо указать формат данных, которые будут выводиться. Формат данных указывается спецификаторами формата. Спецификатор формата начинается с символа % за которым следует код формата.

Спецификаторы формата:

символ
%d целое десятичное число
%i целое десятичное число
%e десятичное число в виде x.xx e+xx
%E десятичное число в виде x.xx E+xx
%f
%F десятичное число с плавающей запятой xx.xxxx
%g %f или %e, что короче
%G %F или %E, что короче
%o восьмеричное число
%s строка символов
%u беззнаковое десятичное число
%x шестнадцатеричное число
%X шестнадцатеричное число
%% символ %
%p указатель
%n указатель

Кроме того, к командам формата могут быть применены модификаторы l и h.

%ld печать long int
%hu печать short unsigned
%Lf печать long double

В спецификаторе формата, после символа % может быть указана точность (число цифр после запятой). Точность задаётся следующим образом: %.n<код формата>. Где n - число цифр после запятой, а <код формата> - один из кодов приведённых выше.

Например, если у нас есть переменная x=10.3563 типа float и мы хотим вывести её значение с точностью до 3-х цифр после запятой, то мы должны написать:

printf("Переменная x = %.3f",x);

Результат:
Переменная x = 10.356

Вы также можете указать минимальную ширину поля отводимого для печати. Если строка или число больше указанной ширины поля, то строка или число печатается полностью.

Например, если вы напишите:

printf("%5d",20);

то результат будет следующим:
20

Обратите внимание на то, что число 20 напечаталось не с самого начала строки. Если вы хотите чтобы неиспользованные места поля заполнялись нулями, то нужно поставить перед шириной поля символ 0.

Например:

printf("%05d",20);

Результат:
00020

Кроме спецификаторов формата данных в управляющей строке могут находиться управляющие символы:

\b BS, забой
\f Новая страница, перевод страницы
\n Новая строка, перевод строки
\r Возврат каретки
\t Горизонтальная табуляция
\v Вертикальная табуляция
\" Двойная кавычка
\" Апостроф
\\ Обратная косая черта
\0 Нулевой символ, нулевой байт
\a Сигнал
\N Восьмеричная константа
\xN Шестнадцатеричная константа
\? Знак вопроса

Чаще всего вы будете использовать символ \n. С помощью этого управляющего символа вы сможете переходить на новую строку. Посмотрите примеры программ и вы всё поймёте.

Примеры программ.

/* Пример 1 */
#include

void main(void)
{
int a,b,c; // Объявление переменных a,b,c
a=5;
b=6;
c=9;
printf("a=%d, b=%d, c=%d",a,b,c);
}

Результат работы программы:
a=5, b=6, c=9

/* Пример 2 */
#include

void main(void)
{
float x,y,z;

X=10.5;
y=130.67;
z=54;

Printf("Координаты объекта: x:%.2f, y:%.2f, z:%.2f", x, y, z);
}

Результат работы программы:
Координаты объекта: x:10.50, y:130.67, z:54.00

/* Пример 3 */
#include

void main()
{
int x;

X=5;
printf("x=%d", x*2);
}

Результат работы программы:
x=10

/* Пример 4 */
#include

void main(void)
{
printf("\"Текст в кавычках\"");
printf("\nСодержание кислорода: 100%%");
}

Результат работы программы:
"Текст в кавычках"
Содержание кислорода: 100%

/* Пример 5 */
#include

void main(void)
{
int a;

A=11; // 11 в десятичной равно b в шестнадцатеричной
printf("a-dec=%d, a-hex=%X",a,a);
}

Результат работы программы:
a-dec=11, a-hex=b

/* Пример 6 */
#include

void main(void)
{
char ch1,ch2,ch3;

Ch1="A";
ch2="B";
ch3="C";

Printf("%c%c%c",ch1,ch2,ch3);
}

Результат работы программы:
ABC

/* Пример 7 */
#include

void main(void)
{
char *str="Моя строка.";

Printf("Это %s",str);
}

Результат работы программы:
Это Моя строка.

/* Пример 8 */
#include

void main(void)
{
printf("Здравствуйте!\n"); // После печати будет переход на новую строку - \n
printf("Меня зовут Павел."); // Это будет напечатано на новой строке
}

Результат работы программы:
Здравствуйте!
Меня зовут Павел.

Функция стандартного ввода scanf()

Функция scanf() - функция форматированного ввода. С её помощью вы можете вводить данные со стандартного устройства ввода (клавиатуры). Вводимыми данными могут быть целые числа, числа с плавающей запятой, символы, строки и указатели.

Функция scanf() имеет следующий прототип в файле stdio.h:
int scanf(char *управляющая строка);

Функция возвращает число переменных которым было присвоено значение.

Управляющая строка содержит три вида символов: спецификаторы формата, пробелы и другие символы. Спецификаторы формата начинаются с символа %.

Спецификаторы формата:

При вводе строки с помощью функции scanf() (спецификатор формата %s), строка вводиться до первого пробела!! т.е. если вы вводите строку "Привет мир!" с использованием функции scanf()


scanf("%s",str);

то после ввода результирующая строка, которая будет храниться в массиве str будет состоять из одного слова "Привет". ФУНКЦИЯ ВВОДИТ СТРОКУ ДО ПЕРВОГО ПРОБЕЛА! Если вы хотите вводить строки с пробелами, то используйте функцию

char *gets(char *buf);

С помощью функции gets() вы сможете вводить полноценные строки. Функция gets() читает символы с клавиатуры до появления символа новой строки (\n). Сам символ новой строки появляется, когда вы нажимаете клавишу enter. Функция возвращает указатель на buf. buf - буфер (память) для вводимой строки.

Хотя gets() не входит в тему этой статьи, но всё же давайте напишем пример программы, которая позволяет ввести целую строку с клавиатуры и вывести её на экран.

#include

void main(void)
{
char buffer; // массив (буфер) для вводимой строки

Gets(buffer); // вводим строку и нажимаем enter
printf("%s",buffer); // вывод введённой строки на экран
}

Ещё одно важное замечание! Для ввода данных с помощью функции scanf(), ей в качестве параметров нужно передавать адреса переменных, а не сами переменные. Чтобы получить адрес переменной, нужно поставить перед именем переменной знак &(амперсанд). Знак & означает взятие адреса.

Что значит адрес? Попробую объяснить. В программе у нас есть переменная. Переменная хранит своё значение в памяти компьютера. Так вот адрес, который мы получаем с помощью & это адрес в памяти компьютера где храниться значение переменной.

Давайте рассмотрим пример программы, который показывает нам как использовать &

#include

void main(void)
{
int x;

Printf("Введите переменную x:");
scanf("%d",&x);
printf("Переменная x=%d",x);
}

Теперь давайте вернёмся к управляющей строке функции scanf(). Ещё раз:

int scanf(char *управляющая строка);

Символ пробела в управляющей строке дает команду пропустить один или более пробелов в потоке ввода. Кроме пробела может восприниматься символ табуляции или новой строки. Ненулевой символ указывает на чтение и отбрасывание этого символа.

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

Например:

scanf("%d%*c%d",&i,&j);

при вводе 50+20 присвоит переменной i значение 50, переменной j - значение 20, а символ + будет прочитан и проигнорирован.

В команде формата может быть указана наибольшая ширина поля, которая подлежит считыванию.

Например:

scanf("%5s",str);

указывает необходимость прочитать из потока ввода первые 5 символов. При вводе 1234567890ABC массив str будет содержать только 12345, остальные символы будут проигнорированы. Разделители: пробел, символ табуляции и символ новой строки - при вводе символа воспринимаются, как и все другие символы.

Если в управляющей строке встречаются какие-либо другие символы, то они предназначаются для того, чтобы определить и пропустить соответствующий символ. Поток символов 10plus20 оператором

scanf("%dplus%d",&x,&y);

присвоит переменной x значение 10, переменной y - значение 20, а символы plus пропустит, так как они встретились в управляющей строке.

Одной из мощных особенностей функции scanf() является возможность задания множества поиска (scanset). Множество поиска определяет набор символов, с которыми будут сравниваться читаемые функцией scanf() символы. Функция scanf() читает символы до тех пор, пока они встречаются в множестве поиска. Как только символ, который введен, не встретился в множестве поиска, функция scanf() переходит к следующему спецификатору формата. Множество поиска определяется списком символов, заключённых в квадратные скобки. Перед открывающей скобкой ставиться знак %. Давайте рассмотрим это на примере.

#include

void main(void)
{
char str1, str2;
scanf("%%s", str1, str2);
printf("\n%s\n%s",str1,str2);
}
Введём набор символов:
12345abcdefg456

На экране программа выдаст:
12345
abcdefg456

При задании множества поиска можно также использовать символ "дефис" для задания промежутков, а также максимальную ширину поля ввода.

scanf("%10", str1);

Можно также определить символы, которые не входят в множество поиска. Перед первым из этих символов ставиться знак ^. Множество символов различает строчные и прописные буквы.

Напомню, что при использовании функции scanf(), ей в качестве параметров нужно передавать адреса переменных. Выше был написан код:

char str; // массив на 80 символов
scanf("%s",str);

Обратите внимание на то, что перед str не стоит символ &. Это сделано потому, что str является массивом, а имя массива - str является указателем на первый элемент массива. Поэтому знак & не ставиться. Мы уже передаем функции scanf() адрес. Ну проще говоря str это адрес в памяти компьютера где будет храниться значение первого элемента массива.

Примеры программ.

Пример 1.
Эта программа выводит на экран запрос "Сколько вам лет?:" и ждёт ввода данных. Если, например, ввести число 20, то программа выведет строку "Вам 20 лет.". При вызове функции scanf(), перед переменной age мы поставили знак &, так как функции scanf() нужны адреса переменных. Функция scanf() запишет введённое значение по указанному адресу. В нашем случае введённое значение 20 будет записано по адресу переменной age.

/* Пример 1 */

#include

void main(void)
{
int age;

Printf("\nСколько вам лет?:");
scanf("%d",&age);
printf("Вам %d лет.", age);
}

Пример 2.
Программа калькулятор. Этот калькулятор может только складывать числа. При вводе 100+34 программа выдаст результат: 100+34=134.

/* Пример 2 */

#include

void main(void)
{
int x, y;

Printf("\nКалькулятор:");
scanf("%d+%d", &x, &y);
printf("\n%d+%d=%d", x, y, x+y);
}

Пример 3.
Этот пример показывает как установить ширину поля считывания. В нашем примере ширина поля равна пяти символам. Если вы введёте строку с большим количеством символов, то все символы после 5-го будут отброшены. Обратите внимание на вызов функции scanf(). Знак & не стоит перед именем массива name так как имя массива name является адресом первого элемента массива.

/* Пример 3 */

#include

void main(void)
{
char name;

Printf("\nВведите ваш логин (не более 5 символов):");
scanf("%5s", name);
printf("\nВы ввели %s", name);
}

Пример 4.
Последний пример в этой статье показывает как можно использовать множество поиска. После запуска программы введите число от 2 до 5.

/* Пример 4 */

#include

void main(void)
{
char bal;

Printf("Ваша оценка 2,3,4,5:");
scanf("%", &bal);
printf("\nОценка %c", bal);
}

#include
int scanf (const char *format, ...);

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

В версии С99 к параметру format применен квалификатор restrict .

Управляющая строка, задаваемая параметром format , состоит из символов трех категорий:

  • спецификаторов формата;
  • пробельных символов;
  • символов, отличных от пробельных.

  • Спецификации формата начинаются знаком % и сообщают функции scanf() тип данного, которое будет прочитано. Например, по спецификации %s будет прочитана строка, а по спецификации %d - целое значение. Строка форматирования читается слева направо, и спецификации формата сопоставляются аргументам в порядке их перечисления в списке аргументов.

    Спецификации формата функции scanf() :
    Читает значение с плавающей точкой (только С99)
    Аналогично коду (только С99)
    Читает один символ
    %d Читает десятичное целое
    %i Читает целое в любом формате (десятичное, восьмеричное или шести ад цате ричное)

    Аналогично коду
    %f Читает число с плавающей точкой
    %F Аналогично коду %f (только С99)
    %g Читает число с плавающей точкой
    %G Аналогично коду %g
    %o Читает восьмеричное число
    %s Читает строку
    Читает шести ад цате ричное число
    Аналогично коду
    Читает указатель
    %n Принимает целое значение, равное количеству прочитанных до сих пор символов
    %u Читает десятичное целое без знака
    % Просматривает набор символов
    %% Читает знак процента

    По умолчанию спецификации a , f , е и g заставляют функцию scanf() присваивать данные переменным типа float . Если перед одной из этих спецификаций поставить модификатор l , функция scanf() присвоит прочитанные данные переменной типа double . Использование же модификатора L означает, что полученное значение присвоится переменной типа long double .

    Современные компиляторы, поддерживаюшие добавленные в 1995 году средства работы с двухбайтовыми символами, позволяют к спецификации с применить модификатор l ; тогда будет считаться, что соответствующий указатель указывает на двухбайтовый символ (т.е. на данное типа wchar_t ). Модификатор l также можно использовать с кодом формата s ; тогда будет считаться, что соответствующий указатель указывает на строку двухбайтовых символов. Кроме того, модификатор l можно использовать для того, чтобы указать, что набор сканируемых символов состоит из двухбайтовых символов.

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

    Если в строке форматирования встретился символ, отличный от разделителя, то функция scanf() прочитает и отбросит его. Например, если в строке форматирования встретится %d , %d , то функция scanf() сначала прочитает целое значение, затем прочитает и отбросит запятую и, наконец, прочитает еще одно целое. Если заданный символ не найден, функция scanf() завершает работу.
    Все переменные, получающие значения с помощью функции scanf() , должны передаваться посредством своих адресов. Это значит, что все аргументы должны быть указателями на переменные.
    Элементы входного потока должны быть разделены пробелами, символами табуляции или разделителями строк. Такие символы, как запятая, точка с запятой и т.п., не распознаются в качестве разделителей. Это означает, что оператор
    scanf ("%d%d", &r, &c); примет значения, введенные как 10 20, но откажется от последовательности символов 10,20.

    Символ * , стоящий после знака % и перед кодом формата, прочитает данные заданного типа, но запретит их присваивание. Следовательно, оператор
    scanf ("%d%*c%d", &x, &y); при вводе данных в виде 10/20 поместит значение 10 в переменную х, отбросит знак деления и присвоит значение 20 переменной у.

    Команды форматирования могут содержать модификатор максимальной длины поля. Он представляет собой целое число, располагаемое между знаком % и кодом формата, которое ограничивает количество читаемых для всех полей символов. Например, если в переменную address нужно прочитать не более 20 символов, используется следующий оператор.
    scanf ("%20s", address);
    Если входной поток содержит более 20 символов, то при последующем обращении к операции ввода чтение начнется с того места, в котором "остановился" предыдущий вызов функции scanf() . Если разделитель встретится раньше, чем достигнута максимальная длина поля, ввод данных завершится. В этом случае функция scanf() переходит к чтению следующего поля.

    Хотя пробелы, символы табуляции и разделители строк используются в качестве разделителей полей, при чтении одиночного символа они читаются подобно любому другому символу. Например, если входной поток состоит из символов х у, то оператор
    scanf ("%c%c%c", &a, &b, &c); поместит символ х в переменную а, пробел - в переменную b, а символ у - в переменную с.

    Помните, что любые символы управляющей строки (включая пробелы, символы табуляции и новой строки), не являющиеся спецификациями формата, используются для установки соответствия и отбрасывания символов из входного потока. Любой соответствующий им символ отбрасывается. Например, если поток ввода выглядит, как 10t20, оператор
    scanf ("%dt%d", &x, &y); присвоит переменной х значение 10, а переменной у - значение 20. Символ t отбрасывается, так как он присутствует в управляющей строке.

    Функция scanf() поддерживает спецификатор формата общего назначения, называемый набором сканируемых символов (scanset) , В этом случае определяется набор символов, которые могут быть прочитаны функцией scanf() и присвоены соответствующему массиву символов. Для определения такого набора символы, подлежащие сканированию, необходимо заключить в квадратные скобки. Открывающая квадратная скобка должна следовать сразу за знаком процента. Например, следующий набор сканируемых символов указывает на то, что необходимо читать только символы А, B и С.
    % При использовании набора сканируемых символов функция scanf() продолжает читать символы и помещать их в соответствующий массив символов до тех пор, пока не встретится символ, отсутствующий в заданном наборе. Соответствующая набору переменная должна быть указателем на массив символов. При возврате из функции scanf() этот массив будет содержать строку из прочитанных символов, завершающуюся символом конца строки.

    Если первый символ в наборе является знаком ^ , то получаем обратный эффект: входное поле читается до тех пор, пока не встретится символ из заданного набора сканируемых символов, т.е. знак ^ заставляет функцию scanf() читать только те символы, которые отсутствуют в наборе сканируемых символов.
    Во многих реализациях допускается задавать диапазон с помощью дефиса. Например, функция scanf() , встречая набор сканируемых символов в виде % , будет читать символы, попадающие в диапазон от А до Z.

    Важно помнить, что в наборе сканируемых символов различаются прописные и строчные буквы. Следовательно, чтобы сканировать как прописные, так и строчные буквы, в наборе сканируемых символов придется задать их отдельно.

    Функция scanf() возвращает число, равное количеству полей, для которых успешно присвоены значения. К этим полям не относятся поля, которые были прочитаны, но присвоение не состоялось в связи с использованием модификатора * , подавляющего присваивание. При обнаружении ошибки до присвоения значения первого поля функция scanf() возвращает значение EOF .

    Модификаторы формата, добавленные к функции scanf() Стандартом С99

    В версии С99 для использования в функции scanf() добавлены модификаторы формата hh , ll , j , z и t . Модификатор hh можно применять к спецификациям d , i , о , u , х и n signed char или unsigned char . Модификатор ll также можно применять к спецификациям d , i , о , u , х и n . Он означает, что соответствующий аргумент является указателем на значение типа signed long long int или unsigned long long int .

    Модификатор формата j d , i , о , u , х и n , означает, что соответствующий аргумент является указателем на значение типа intmax_t или uintmax_t . Эти типы объявлены в заголовке и служат для хранения целых максимально возможной разрядности.

    Модификатор формата z , который применяется к спецификациям d , i , о , u , х и n size_t и служит для хранения результата операции sizeof .

    Модификатор формата t , который применяется к спецификациям d , i , о , u , х и n , означает, что соответствующий аргумент является указателем на объект типа ptrdiff_t . Этот тип объявлен в заголовке и служит для хранения значения разности между двумя указателями.