Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Костюк - Основы программирования

.pdf
Скачиваний:
134
Добавлен:
30.05.2015
Размер:
1.3 Mб
Скачать

191

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

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

го транслятора Си заголовочных файлов: assert.h – средства диагностики;

ctype.h – проверка символов и их преобразование; errno.h – проверка ошибок выполнения программы; float.h – предельные значения вещественных чисел; limits.h – предельные значения целочисленных данных; math.h – математические функции;

signal.h – средства обработки исключительных ситуаций; stdio.h – средства ввода-вывода;

stdlib.h – функции общего назначения; string.h – функции обработки символьных строк;

time.h – функции определения даты и времени.

В трансляторе Turbo C имеются дополнительные заголовочные файлы, в частности dir.h и dos.h – для работы с каталогами файлов, graphics.h

для графического вывода.

Функции и константы, описанные в файле graphics.h полностью аналогич­ ны функциям и константам библиотеки graph системы Turbo Pascal.

Втабл. Б.5 приведены основные математические функции и макросы, описанные

вфайле math.h.

 

 

Таблица Б.5

 

 

 

 

Функция

Тип

Тип

Пояснение

аргументов

результата

 

 

abs

int

int

Абсолютное значение

acos

double

double

Арккосинус, главное значение

asin

double

double

Арксинус, главное значение

atan

double

double

Арктангенс, главное значение

atan2

double x,

double

Круговой арктангенс значения x/y

 

double y

 

 

ceil

double

double

Ближайшее целое, не меньшее аргумента

cos

double

double

Косинус

exp

double

double

Экспонента

fabs

double

double

Абсолютное значение

floor

double

double

Ближайшее целое, не большее аргумента

fmod

double x,

double

Остаток от деления нацело x на y

 

double y

 

 

frexp

double x,

double

Возвращает мантиссу x. Двоичный по­

 

int *p

 

рядок x записывается по адресу *p

192

 

hypot

 

double x,

 

double

 

 

Вычисляет результат по формуле

 

 

 

 

 

 

 

 

 

 

double y

 

 

 

 

sqrt(x*x+y*y)

 

 

 

labs

 

long

 

long

 

 

Абсолютное значение

 

 

 

 

 

 

Таблица Б.5 (продолжение)

 

 

 

 

 

 

 

 

 

 

Функция

 

Тип

 

Тип

 

 

Пояснение

 

 

 

 

аргументов

 

результата

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ldexp

 

double x,

 

double

 

 

Вычисляет результат по формуле

 

 

 

 

 

int e

 

 

 

 

x * 2 e

 

 

 

log

 

double

 

double

 

 

Натуральный логарифм

 

 

 

log10

 

double

 

double

 

 

Десятичный логарифм

 

 

 

modf

 

double x,

 

double

 

 

Возвращает дробную часть x. Целая

 

 

 

 

 

double *p

 

 

 

 

часть x записывается по адресу *p

 

 

 

pow

 

double x,

 

double

 

 

Вычисляет результат по формуле x y

 

 

 

 

 

double y

 

 

 

 

 

 

 

 

pow10

 

double x

 

double

 

 

Вычисляет результат по формуле 10 x

 

 

 

sin

 

double

 

double

 

 

Синус

 

 

 

sinh

 

double

 

double

 

 

Гиперболический синус

 

 

 

sqrt

 

double

 

double

 

 

Квадратный корень

 

 

 

tan

 

double

 

double

 

 

Тангенс

 

 

 

tanh

 

double

 

double

 

 

Гиперболический тангенс

 

 

 

В файле

math.h, кроме того, приведены значения математических констант с

точностью до 21 десятичной цифры. Имена некоторых из имеющихся констант: M_E

– число e, M_LOG2E – log 2 e, M_LN2

ln 2, M_PI π, M_1_PI – 1/π.

 

В табл. Б.6 приведены наиболее важные функции и макросы, описанные в файле

stdlib.h.

 

Таблица Б.6

 

 

 

 

 

 

 

 

 

 

 

 

Функция

 

Тип

Тип

Пояснение

 

 

 

аргументов

результата

 

 

 

 

 

 

 

atof

 

char *

double

Преобразует символьную строку в число

 

 

atoi

 

char *

int

Преобразует символьную строку в число

 

 

atol

 

char *

long

Преобразует символьную строку в число

 

 

calloc

 

unsigned n,

void *

Выделяет область динамической памяти

 

 

 

 

unsigned m

 

размером n*m байт, возвращает ее адрес

 

 

coreleft

 

void

unsigned

Возвращает размер доступной памяти в

 

 

 

 

 

 

схемах распределения Turbo C: tiny, small,

 

 

 

 

 

 

medium, устанавливаемых в опциях

 

 

coreleft

 

void

unsigned

Возвращает размер доступной памяти в

 

 

 

 

 

long

схемах распределения Turbo C: compact,

 

 

ecvt

 

double x,

char *

large, huge, устанавливаемых в опциях

 

 

 

Преобразует число x в символьную стро­

 

193

int n, int &d, int &z,

ку из цифр длиной n. Переменной d при­

сваивается номер позиции десятичной точки; z=0 при x<0, z=1 при x≥0

 

 

 

Таблица Б.6 (продолжение)

 

Функция

Тип

Тип

Пояснение

 

 

аргументов

результата

 

free

 

 

void *p

void

Возвращает область динамической памя­

 

gcvt

double x,

char *

ти, которую адресует указатель p

 

Преобразует число x в символьное пред­

 

 

int n,

 

ставление в строке s длиной n

 

 

char *s

 

 

 

itoa

int i,

char *

Преобразует число i в символьную

 

 

char *s,

 

строку s, состоящую из цифр в r-ичной

 

 

int r

 

системе счисления

 

ltoa

long l,

char *

Преобразует число l в символьную

 

 

char *s,

 

строку s, состоящую из цифр в r-ичной

 

 

int r

 

системе счисления

 

malloc

unsigned n

void *

Выделяет область динамической памяти

 

 

 

 

размером n байт, возвращая ее адрес

 

max

Два числовых Тип, как у

Максимальное значение

 

 

аргумента

аргументов

 

 

min

Два числовых Тип, как у

Минимальное значение

 

 

аргумента

аргументов

 

 

rand

void

int

Генерирует случайное число от 0 до 215 –1

 

randomize

void

void

Задает начальное значение для генератора

 

srand

unsigned

void

случайных чисел от часов компьютера

 

Задает начальное значение для генера­

 

stime

long *t

int

тора случайных чисел

 

Устанавливает текущее время в секун­

 

 

 

 

дах с момента 1 января 1970 г.

 

system

char *s

int

Выполняет команду ОС или exe–модуль

 

 

 

 

(то, что записано в строке s). Возвращает

 

 

 

 

0, если не было ошибки

 

time

long *t

long

Выдает текущее время в секундах с мо­

 

 

 

 

мента 1 января 1970 г.

Файл stdio.h содержит средства ввода-вывода. В табл. Б.7 приведены наибо­ лее важные функции стандартного ввода из потока stdin и вывода в поток std­

out, а в табл. Б.8 – функции для работы с файлами.

Функции printf, putchar, puts, scanf, sprintf, sscanf возвращают 0, если не произошло ошибки. При этом функции sprintf и sscanf моделиру­

ют ввод-вывод, используя строку символов вместо устройства ввода или вывода.

194

Первый параметр в функциях printf, scanf и второй параметр в sprintf, sscanf – формат, строка символов, содержащая спецификации преобразования. Каждая спецификация преобразования соответствует одному значению в списке вы­ вода (или одному указателю на переменную в списке ввода). В общем случае специ­ фикация имеет вид:

%[<флаг>][<ширина поля>][.<точность>][<модификатор>]<спецификатор>

 

 

Таблица Б.7

 

 

 

 

Функция

Тип

Тип

Пояснение

аргументов

результата

 

 

getchar

void

int

Считывает очередной символ из stdin.

 

 

 

Возвращает код символа

gets

char *

char *

Считывает строку символов из stdin.

 

 

 

Возвращает указатель на строку

printf

char *f,

int

Форматированный вывод в stdout. f

 

...

 

строка форматов вывода, далее идут вы­

putchar

int

int

водимые значения (их количество ≥ 0).

Записывает символ в stdout

puts

char *

int

Записывает строку символов в stdout

scanf

char *f,

int

Форматированный ввод из stdin. f

 

...

 

строка форматов ввода, далее идут ука­

 

 

 

затели на переменные

sprintf

char *s,

int

Форматированное вывод в строку s. f

 

char *f,

 

строка форматов вывода, далее идут вы­

 

...

 

водимые значения (их количество ≥ 0)

sscanf

char *s,

int

Форматированный ввод из строки s.

 

char *f,

 

f – строка форматов ввода, далее идут

 

...

 

указатели на переменные

Спецификатор состоит из одной буквы и определяет тип вводимых или выводи­

мых данных:

d или i – тип int, изображается в виде десятичных цифр;

u – тип

unsigned, изображается в виде десятичных цифр;

o – тип

unsigned или int, изображается в виде восьмеричных цифр;

x или X – тип unsigned или int, изображается шестнадцатеричными циф­

рами;

f – тип float или double, изображается в виде целой и дробной части; e или E – тип float или double, изображается мантисса и показатель; g или G – тип float или double, выбирается наилучшее представление.

c – тип char, изображается в виде символа;

s – тип char *, изображается в виде символьной строки.

195

Спецификатор состоит из буквы l или L. Буква l задает тип данных long

или unsigned long, буква L – тип long double.

Ширина поля – целое число, задающее количество символьных позиций в пред­ ставлении элемента данных. Точность – целое число, задающее количество цифр в дробной части или мантиссы в представлении вещественного числа. Если ширина поля и точность не заданы, то используется столько позиций, сколько необходимо. Флаг (знак + или -) задает обязательное изображение знака в представлении числа.

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

В файле stdio.h описан специальный тип данных FILE как структура, со­

держащая поля с характеристиками файла. Для работы с файлом в программе необ­ ходимо описать переменную-указатель на тип FILE. Открытие файла и связывание

его с указателем типа FILE * производится функцией fopen, закрытие – функци­ ей fclose.

 

 

Таблица Б.8

 

 

 

 

Функция

Тип

Тип

Пояснение

аргументов

результата

 

 

clearerr

FILE *

void

Сбрасывает ошибки ввода-вывода файла

fclose

FILE *

int

Закрывает файл

foef

FILE *

int

Если достигнут конец файла, возвращает

 

 

 

0, иначе 1

ferror

FILE *

int

Если нет ошибки ввода-вывода файла,

 

 

 

возвращает 0, иначе код ошибки

fgetc

FILE *

int

Считывает очередной символ из файла,

 

 

 

возвращает код символа

fgetpos

FILE *F,

int

Переменной p присваивает значение

 

long *p

 

указателя на текущую позицию файла F

fgets

char *s,

char *

Читает не более n-1 символов из файла

 

int n,

 

F в строку s и записывает последним

fopen

FILE * F

FILE *

символ ’\0’

char *f,

Открывает файл с именем, записанным

 

char *m

 

в строке f, с режимом работы, запи­

 

 

 

санным в строке m. Возвращает указа­

 

 

 

тель на структуру типа FILE

fprintf

FILE *F,

int

Форматированный вывод в файл F. f

 

char *f,

 

строка форматов вывода, далее идут вы­

 

...

 

водимые значения (их количество ≥ 0).

fputc

int c,

int

Записывает символ с кодом c в файл F

 

FILE *F

 

 

196

 

fputs

 

char *s,

 

int

 

Записывает символьную строку s в

 

 

 

 

 

 

 

 

 

FILE *F

 

 

 

файл F

 

 

 

Таблица Б.8 (продолжение)

 

 

 

 

Функция

Тип

Тип

Пояснение

аргументов

результата

 

 

fread

void *b,

unsigned

Считывание n групп данных длиной по

 

unsigned m,

 

m байт из файла F в область памяти, ад­

 

unsigned n,

 

ресуемой указателем b. Возвращает ко­

fscanf

FILE *F

int

личество считанных групп данных

FILE *F,

Форматированный ввод из файла F. f

 

char *f,

 

строка форматов ввода, далее идут указа­

 

...

 

тели на переменные

fseek

FILE *F,

int

Перемещает значение указателя текущей

 

long *p,

 

позиции файла на p байт относительно

 

int r

 

начала файла (r=0), текущей позиции

 

 

 

(r=1) или конца файла (r=2)

ftell

FILE *

long

Возвращает значение указателя текущей

 

 

 

позиции файла

fwrite

void *b,

unsigned

Запись n групп данных длиной по m

 

unsigned m,

 

байт из файла F в область памяти, адре­

 

unsigned n,

 

суемой указателем b. Возвращает коли­

 

FILE *F

 

чество записанных групп данных

remove

char *f

int

Удаляет файл с именем, записанным в f

rename

char *f1,

int

Заменяет имя файла, записанное в строке

rewind

char *f2

int

f1 на имя файла, записанное в f2

FILE *

Значение указателя текущей позиции

 

 

 

файла устанавливает в начало файла

Функции fprintf, fputc, fputs, fscanf, fseek, remove, rename, rewind возвращают 0, если не произошло ошибки.

Режим работы открываемого файла, задаваемый в функции fopen, записывает­

ся в виде строки символов. Возможны следующие режимы:

”r” – последовательное чтение существовующего файла от начала к концу; ”w” – последовательная запись в файл, если открываемый файл с указанным

именем существует, то он считается пустым, а если его нет, то файл создается;

”a” – последовательная дозапись в файл, если открываемый файл с указанным именем существует. Если такого файла нет, то файл создается для записи;

197

”r+” – чтение файла в произвольном порядке и перезаписывание внутри него

данных, открываемый файл должен существовать. Перед функциями чтения или за­ писи используется функция fseek;

”w+” – если открываемый файл с указанным именем существует, то он считает­ ся пустым, а если его нет, то файл создается для последовательной записи, а также чтения и перезаписи отдельных данных в нем. Перед функциями чтения или записи в произвольном порядке используется функция fseek;

”a+” – если открываемый файл с указанным именем существует, то он дописы­ вается, а если его нет, то файл создается для последовательной записи, а также чте­ ния и перезаписи отдельных данных в нем. Перед функциями чтения и записи в произвольном порядке используется функция fseek.

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

работы с двоичным файлом, содержащим произвольные данные, необходимо доба­ вить букву b, например, ”rb”, ”wb+” и др.

Вфайле string.h описаны прототипы функций обработки символьных строк

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

char. Элементы в таком массиве могут иметь любое значение, кроме нуля, так как нуль отмечает конец содержимого строки. При работе со строками необходимо га­

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

ведены в табл. Б. 9. Функции, оперирующие со строками, имеют имена, начинающие­ ся с символов str, а имена функций, оперирующих с массивами произвольного типа, начинаются с символов mem.

 

 

Таблица Б.9

 

 

 

 

Функция

Тип

Тип

Пояснение

аргументов

результата

 

 

memchr

void *s,

void *

В массиве s производит поиск байта с

 

char c,

 

кодом c среди первых n байтов. Воз­

 

unsigned n

 

вращает указатель на найденный байт

memcmp

void *s1,

int

Сравнивает лексикографически массивы

 

void *s2,

 

s1 и s2 (первые n байтов). Возвращает

 

unsigned n

 

0, если они равны, <0, если s1<s2, и >0,

 

 

 

если s1>s2

memcpy

void *s1,

void *

Копирует n байт из массива s2 в мас­

 

void *s2,

 

сив s1. Возвращает указатель на массив

 

unsigned n

 

s1

memset

void *s,

void *

Заполняет n байт массива s симво­

 

char c,

 

лом c. Возвращает указатель на массив s

 

 

 

 

198

 

 

unsigned n

 

 

 

 

 

 

 

 

 

strcat

char *s1,

char *

Конкатенация строк. После символов

 

 

 

char *s2

 

строки s1 дописываются символы из s2.

 

 

strchr

char *s,

char *

Возвращает указатель на строку s1

 

 

В строке s производит поиск символа c.

 

 

 

char c

 

Возвращает указатель на найденный сим­

 

 

 

 

 

вол

 

 

 

Таблица Б.9 (продолжение)

 

 

 

 

 

 

 

Функция

Тип

Тип

Пояснение

 

 

аргументов

результата

 

 

 

 

 

 

strcmp

char *s1,

int

Сравнивает лексикографически строки

 

 

 

char *s2

 

s1 и s2. Возвращает 0, если они равны,

 

 

 

 

 

<0, если s1<s2, и >0, если s1>s2

 

 

strcpy

char *s1,

char *

Копирует строку s2 в строку s1. Воз­

 

 

 

char *s2

 

вращает указатель на строку s1

 

 

strlen

char *

unsigned

Вычисляет длину строки

 

 

 

 

 

 

 

 

strncat

char *s1,

char *

После символов строки s1 дописывает­

 

 

char *s2,

 

ся не более n символов из s2. Возвра­

 

 

 

unsigned n

 

щает указатель на строку s1

 

 

strncmp

char *s1,

int

Сравнивает лексикографически не бо­

 

 

 

char *s2,

 

лее чем n символов строк s1 и s2.

 

 

 

unsigned n

 

Возвращает 0, если они равны, <0, если

 

 

 

 

 

s1<s2, и >0, если s1>s2

 

 

strncpy

char *s1,

char *

Копирует не более чем n символов стро­

 

 

 

char *s2,

 

ки s2 в строку s1. Возвращает указа­

 

 

 

unsigned n

 

тель на строку s1

 

 

strnset

char *s,

char *

Заполняет не более чем n символов

 

 

 

char c,

 

строки s символом c. Возвращает ука­

 

 

 

unsigned n

 

затель на строку s

 

 

strset

char *s,

char *

Заполняет строку s символом c. Воз­

 

 

 

char c

 

вращает указатель на строку s

 

 

strstr

char *s1,

char *

В строке s1 производит поиск подстро­

 

 

 

char *s2

 

ки s2. Возвращает указатель на найден­

 

 

 

 

 

ную подстроку

 

Б.4 Программирование на Си

199

В разделе приведено несколько примеров программ на Си, реализующих рассмотренные в книге алгоритмы на Паскале.

Пример Б.1. Программа вводит n – количество элементов целочисленного мас­ сива X, а затем сами эти элементы, после чего упорядочивает их алгоритмом (2.7) и выводит в упорядоченном виде.

Пояснения к тексту программы:

/*1*/ – препроцессорная директива включения заголовочного файла с описани­

ем библиотеки ввода-вывода;

 

 

 

/*2*/ – заголовок главной функции;

 

 

 

 

#include <stdio.h>

/*1*/

 

 

 

void main(void)

/*2*/

 

 

 

{int i,n,z,X[1000];

/*3*/

 

 

 

scanf(”%d”,&n);

/*4*/

 

 

 

for(i=0;i<n;i++) scanf(”%d”,&X[i]);

/*5*/

 

 

 

i=0;

 

/*6*/

 

 

 

while(i<n-1)

/*7*/

 

 

 

if(X[i]<=X[i+1]) i++;

/*8*/

 

(Б.1)

 

else

/*9*/

 

 

 

{z=X[i];X[i]=X[i+1];X[i+1]=z;

/*10*/

 

 

 

if(i>0)i--;

/*11*/

 

 

 

}

 

/*12*/

 

 

 

for(i=0;i<n;i++) printf(”%8d”,X[i]); /*13*/

 

 

 

printf(”\n”);

/*14*/

 

 

 

}

 

/*15*/

 

 

/*3*/ – описания, массив X содержит 1000 элементов типа int;

 

 

/*4*/ – ввод

n (числа вводимых элементов массива X), спецификация в фор­

мате ввода – %d,

т.е. количество цифр в изображении числа

не задано, конец числа

определяется пробелом или переводом строки. В списке ввода указано

n с операци­

ей &, выдающей указатель на переменную;

 

 

 

/*5*/ – цикл ввода n элементов массива X, элементы нумеруются от 0 до n- 1, изображения элементов при вводе разделяются между собой пробелами. В цикле переменная i изменяется от 0 до n-1 , причем проверка того, что n ≤ 1000, не производится, поэтому при попытке ввести 1001–й элемент массива X програм­

ма (Б.1) аварийно прекратит свое исполнение; /*6*/ /*12*/ – алгоритм (2.7), переписанный на Си;

/*13*/ – цикл вывода n элементов массива X (упорядоченного), специфика­ ция в формате ввода – %8d, т.е. задано 8 цифр в изображении каждого элемента мас­

сива, лишние позиции будут выведены в виде пробелов; /*14*/ – вывода управляющего символа перевода строки.

Пример данных для ввода:

6

200

173 -14 45 11666 3 45

После выполнения программы будет выведено:

-14 3 45 45 173 11666

Конец примера.

Пример Б.2. Программа copyr.exe копирует содержимое первого файла во второй и выводит длину файла. Программа запускается из командной строки, в кото­

рой после имени программы задаются имена файлов. Пусть, например, имя первого файла – f1.dat, второго – f2.dat. Тогда команда запуска будет иметь вид:

copyr f1.dat f2.dat

Чтобы после трансляции имя программы было copyr.exe, ее исходный текст необходимо записать в файл с именем copyr.c.

 

 

 

#include <stdio.h>

/*1*/

 

void main(int p,char *S[])

/*2*/

 

{FILE *F1,*F2;

/*3*/

 

long n,k; char X[1000];

/*4*/

 

if(p!=3||(F1=fopen(S[1],"rb"))==NULL||/*5*/

 

(F2=fopen(S[2],"wb"))==NULL)

/*6*/

 

puts("Ошибка!\n");

/*7*/

 

else

/*8*/

 

{n=0;

/*9*/

(Б.2)

while(feof(F1)==0)

/*10*/

{k=fread(X,1,1000,F1);

/*11*/

 

fwrite(X,1,k,F2);

/*12*/

 

n+=k;

/*13*/

 

}

/*14*/

 

fclose(F1); fclose(F2);

/*15*/

 

printf("Длина файла=%ld\n",n);

/*16*/

 

}

/*17*/

 

}

/*18*/

 

Пояснения к тексту программы:

/*1*/ – директива включения заголовочного файла stdio.h; /*2*/ – заголовок главной функции, исполняемой с параметрами; /*3*/ – описания переменных – указателей на файлы;

/*4*/ – описания, n – длина файла, массив X (длиной 1000 байт) для чтения

данных; /*5*/ /*7*/ – проверка того, что программа запущена с двумя параметрами,

и что удалось открыть первый файл для чтения, второй файл – для записи; /*10*/ – заголовок цикла, в котором проверяется, что первый файл еще не до­

читан до конца;