Академический Документы
Профессиональный Документы
Культура Документы
Ричи
Язык программирования С
2-е и з,цани (', и слравл(' нно е
Керни га н Б.В.
Ричи Д.М.
20 16
2
Б.8. К<'рниган, Д. М. Ричи ЯЗЫК "JIOграм""ирования С
з
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Аннотация и введение
Аннотация
,
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
Брайен В. Керниган
Деннис М. Ричи
0.1 . Введение
5
Б.8. К <'рниган, Д. М. Р ич и Я з ык "JIOграм""ирования С
Язык "С " это язык относительно ''н изкого уровня". В такой
характеристике нет ничего оскорбительного; это просто означает, что
'С" и меет дело с объектами того же вида, что и болыl.в1ствоo ЭВМ, а
именно, с символами, числами и адресами. Они могут объединяться и
пересылаться посредством обычных арифvtетических и ЛОЛ1ческих
операций, осyrцeствляемых реальными Э ВМ.
6
Б.8. К <'рниган, Д. М. Р ич и Я з ык "JIOграм""ирования С
7
Б.8. К <'рниган, Д. М. Р ич и Я з ык "JIOграм""ирования С
структурное программирование).
8
Б.8. К <'рниган, Д. М. Р ич и Я з ык "JIOграм""ирования С
маl.LIИННЫМИ реЛ1страм и.
9
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
Учебное введение
1. Учебное введение
1.1. Начинаем
сравнительно просто.
#include <s(dio.h>
int main О
{
print~'hello , worklln');
гeturn О ;
}
се hello.c
а . ОШ
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
приведет к выво.цу
hello, world
Упражнение 1-1
pгint~'hello , woгkl\n');
функции.
pгintf{"hello, woгld
');
mainО
{
pгintf('hello , ');
pгintf( "wo гld');
pгintf('\n') ;
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
• \ t - для табуnяции ,
• \Ь - для возврата на одн у позицию,
• \ " - для двойной кавычки,
• \ \ - для самой обратной косой черты.
Упражнение 1-2
с = (5/9)*(f-32).
О - 17.8
20 -6.7
40 4.4
60 15.6
260 126. 7
280 137.8
300 148.9
тип int означает, что все переменные списка целые ; тип float
"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
Таблица 1.1.
char символ - один байт
Iower = О;
upper =300;
step = 20;
fahr = Iower;
завершается.
while (i<j)
i = 2 '" ~
Мы также писали 32 . О
32 , несмотря на то, что так как
вместо
переменная fahr имеет тип float , цел ое 32 автоматически бы
преобразовалось к типу float (в 32 . О ) перед вычитанием. С точки
зрения сти л я разумно писать плавающие константы с явной десятичной
точкой даже то гда, когда они имеют целые з начения; это подчеркивает
их плавающую приро.цу для просматривающеro программу и
fahr = Iower;
проверка
Этот же при мер сообщает чуть бол ьше о том , как работает printf .
функция printf фактически является универсальной функцией
фJрматных преобразований, которая бу,цет полностью описана в л екции
NQ 7. Ее первым аргументом является строка символов, которая должна
быть напечатана, причем каждый знак % указывает, ку,ца должен
подставляться каждый из остальных аргументов /второй, третий, .. ./ и в
какой фJрме он должен печататься. Например, в операторе
20
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
Упражнение 1-3
Б.8. К<'рниган, Д. М . Ричи Я ЗЫ К "JIOграм""ирования С
Упражнение 1-4
22
Б.8. К<'рниган, Д. М . Ричи Я ЗЫ К "JIOграм""ирования С
fahr = о
fahr =fahr + 20
каждая задается одним оператором , так как в этом случае запись бол ее
компактна , чем при использовании оператора while , а операторы
управления циклом сосредотачиваются вместе в одном месте.
Упражнение 1-5
2з
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
"
Б.8. К<'рниган, Д. М. Ричи Язык "JIOграм""ирования С
здесь обсуждаем.
с = gelchar()
pUlchar (с)
25
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
вв ести с им в ол
с = getcharO;
while (с != EOF) {
рше оог (с);
с = ge,ehar();
}
#dеfiлe EOF -)
либо
#dеfiлe EOF О
и EOF .
е = getehar()
27
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
с = getcharO != ЕОР
с = (getchar() ! = ЕО Р)
пс = О;
while (getchar() != ЕО Р)
++nc;
prinrf('%ld\n" , ос);
оператор
++ пс;
28
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
prinrf('%.Ol\n", nc);
функция printf использует спец иф.i кацию %f как для f l oat, так и
для double ; спецификация %. О f подавляет печать несуществующей
дробной части.
Тело оператора ЦИКJJа for здесь пусто, так как вся работа выпол няется в
проверочной и реинициализационной частях. Но граммати ческие
правила языка "С" требуют, чтобы оператор f оr имел тело.
29
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
проверяемых условий.
nI = О;
while «с = getchar()) != EO F)
if (с =='In')
++nI;
printf('%dln", nI);
зо
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
Упражнение 1-6
Упражнение 1-7
#dеfiлe yes 1
#dеfiлe rю О
С трока
nI = пw = nc = О ;
полагает все три переменные равными н уnю. Это не особый случай , а
следствие того обстоятельства , что оператору присваивания
соответствует неЮJторое значение и присваивания проводятся
if (выражение)
о п е рато р-1
е Е е о пер ато р- 2
Упражнение 1-9
Упражнение 1-10
Упражнение 1-11
1.6. Массивы
"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
nwhite =rюthег = О;
for (i = О; i < 10; ++i)
ndigit[i) = О;
while ((е
= getehar()) != EOF)
if(e >= 'о' && е <= '9')
++ndigit[e-'O');
else if(e== " 11 е == '\n' 11 е == '\1')
++nwhite;
else
++пошег;
printf("digits =');
for (i = О; i < 10; ++ i)
printf(" 0/0<1", ndigit[i));
prinrf('\nwhite space = o/od, оtПeг = %d\n",
nwhite, rюthег);
описание
iлt ndigit[lO);
35
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
конструкция
if (условие)
оператор
еЕе if (условие)
оператор
еЕе
з6
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
оператор
еЕе if (условие)
оператор
Упражнение 1-12
1.7. Функции
з7
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
вопросов.
int i, р;
Р = 1;
for (i = l ; i<= п; ++i)
Р = р '" х;
return ( р );
}
Вс е функции имеют одинако в ы й ви д :
имя ( сп и сок а р гуме н тов, есл и о ни и ме ются)
о пи сани е а р гуме н то в , если о ни име ются
{
о пи сани я
о п е р ато ры
int х,п;
Упражнение 1-13
"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
юг (р = 1; п > О ; --п)
р = р *х;
ге 'шп ( р );
}
процессом.
Поскол ьку все так прекрасно дел ится, было бы хороll.Ю И написать
программу соответствующим образом. Давайте сначала напишем
отдельную функцию get l in e , которая бу,цет извлекать следующую
строку из файла ввода; это - обобщение функции getcha r . Мы
попытаемся сделать эту функцию по возможности более гибкой, чтобы
она была полезно й и в других ситуация.х. Как м ини мум getli n e
должна передавать с и гнал о возможном появлении конца файла; более
общий полезный вариант мог бы передавать длину строки и л и нуль,
если встретится конец файла. Нуль не может быть длиной строки, так
как каждая строка содержит по крайней мере один символ; даже строка,
содержащая только символ новой строки, имеет длину 1.
5ize */
linе
mainQ /* find lопgе5t line * /
{
int lеп; /* сurтеп( line leпgth */
int maх; /* maximum leпgth 5ееп 50 far */
сhзг line[MAXLlNE]; /* сшгепt inрut line */
сhзг 5ave[MAXLINE]; /* Ioпgе5t linе, 5aved */
maх = О;
while (Оеп = get1ine(line, MAXLINE)) > О)
if (!еп > тах) {
max = lеп;
сору(linе,5ауе);
}
if (maх > О) /* there wa5 а linе */
ргinrК'%5",5ауе);
}
getline(5,lim) /* get linе into 5,геtшп lепgth */
ehar s[];
irnlim;
{
int с, ~
i = О;
while ((s2[i] = sl [i]) != '\0')
++i;
char s[];
iлt Iim;
'11elloln"
! h !e !I!I !o !\n ! \O !
"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Упражнение 1-14
Упражнение 1-15
Упражнение 1-16
Упражнение 1-17
"
Б.8. К<'рниган, Д. М . Ричи Я ЗЫ К "JIOграм""ирования С
"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
line[i] = с;
++ ~
}
line[i] = '\0'
rerurn(i)
}
с оруО /* specialized version */
{
int~
еме rn char linе[], save[];
i= О;
while «save[i] = line[i]) ! ='\О' )
++ ~
'"
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
Упражнение 1-18
1.11. Резюме
После того как вы овл адеете это й частью 'С", приступайте к чтению
следующих нескольких лекций. Усилия, которые вы при этом затратите,
полностью окупятся, потому что в этих лекциях обсуждаются именно те
стороны 'С", где мощь и выразительность языка начинает становиться
очевидной.
Упражнение 1-19
Упражнение 1-20
Упражнение 1-21
Упражнение 1-22
50
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
Упражнение 1-23
52
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
short inr х;
Iong irn у;
W1Signed int z;
Таблица
2. 1.
DEC PDP-ll HONEYWELL6000 lВM 370 INТERDAТA8/32
in t 16 32 32 32
short 16 36 16 16
l ong 32 36 32 32
float 32 36 32 32
double 64 72 64 64
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
2.3. Константы
1 23. 45 6е-7,
0.12е3
long.
• \n (новая строка) ,
• \ t (табуляция),
• \ О (н ул евой символ),
• \\ (обратная косая черта),
• \ ' (одинарная кавычка) и Т.д.
Хотя они выглядят как два символа, на самом деле являются одним.
Кроме того , можно сгенерировать произвольную посл едовательность
двои чных знаЮJВ размером в байт, если написать
'\ddd'
или
56
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
strlen(S) !*геtшnlепgthоfs* !
char s[];
{
int~
i= О;
while (s[i] != '\0')
++ ~
rеtшn(i);
}
2.4. Описания
int Iower;
int upper;
int step;
char с;
char linе [ 1000 ];
х%у
58
Б.8. К<'рниган, Д. М. Ричи Язык "JIOграм""ирования С
== .=
С тарJ.LП.1НСГВО операции & & выше , чем у I 1, и обе они младше операций
отношения и равенсгва. Поэтому такие выражения , как
(е = getehar()) != '\n'
скобки необходимы .
if( ! iлwогd )
Вместо
БО
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
if( iлwогd == О )
Упражнение 2-1
char 5[);
{
int i, п;
n = О;
for ( i = О; 5[i] >= '0' && 5[i]<='9'; ++ i)
n = 10 >1< n + s[i] - 'О';
return(n);
}
Б.8. К<'рниган, Д. М. Ричи Язык "JIOграм""иJlOВания С
s[i] - 'О'
чисел.
62
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
char с;
с = getcharO;
if( с == EOF)
6з
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
int t char с;
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
i = c;c = i;
х = ~ так и
i = х;
(имя т ип а) в ыр ажение
sqrt((double) п)
65
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Упражнение 2-2
например, в
Щс == '\n' )
++ ~
х = п++ ;
б6
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Х = ++п;
if( с == '\n' )
nl++;
int i, j ;
if(s[i] ! = с) (
sU) = s[i);
j++;
if(c == '\n'){
s(i] = с;
++~
if( с == '\n')
s[i++ ] = с;
i=j = О;
while(s(i]! = '\O') j *find еnd ofs */
i++;
while«s(i++] = tU++]) != '\0') j*copy t*/
Упражнение 2-3
Упражнение 2-4
ба
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
Таблица 2.2.
& Побитовое AND
I Побитовое включающее OR
л побитовое исключающее OR
« сдвиг влево
» СДвиг вправо
с = n &0071
c=xlmask
69
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
единице.
х & - О77
70
Б.8. К<'рниган, Д. М . Ричи Я ЗЫ К "JIOграм""ирования С
Упражнение 2-5
Упражнение 2-6
Упражнение 2-7
Упражнение 2-8
i= i+2
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
i += 2
еl = (еl) оп (е2)
х *= у + 1
то
х =х *(у + l)
не
х=х"'у+ l
Упражнение 2-9
операторы
if(a > Ь)
z = а;
7з
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
else
z = Ь;
el ?E2 : e3
z= (а > Ь) ? а : Ь; j* z = mз х(а, Ь) *!
(п > О) ? f: n
"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
выражения.
Упражнение 2-10
Таблица 2.3.
OPERAТOR ASSOCIAllVIТY
+- LEFT то RIGНТ
« » LEFТ то RIGНТ
== 1= LEFT то RIGНТ
Л LEFТ то RlGНТ
LEFТ то RlGНТ
11 LEFТ то RlGНТ
7: RlGHTТO LEFT
= += -= ЕТс. RlGHTТO LEFT
, (CНAPТER 3) LEFТ то RlGНТ
х= Ю+g() ;
76
Б.8. К<'рниган, Д. М . Ричи Я ЗЫ К "JIOграм""ирования С
a[i] = i++;
77
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Управление потоком
3 Управление потоком
х= О;
i++;
pгint~ ... );
3.2 . IF - ELSE
78
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
if (выражение)
оператор-l
еЕе
оператор-2,
if (выражение)
вместо
if (выражение ! = О)
Например, в
if(n > O)
Ща>Ь)
z= а;
еЕе
z= Ь;
79
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
if (п > О) {
if (a> b)
z = а;
еЕе
z= Ь;
if (п > О)
fo г (i = О; i < п; i++)
if(s[i] > О ) {
pгinrf(".. .');
гe Iuтn( i);
}
еЕе /* wгong */
p гintf("e ггo г - n is zeгo\n' );
if (a > Ь)
z = а;
еЕе
z = Ь;
точкой с запятой.
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
3.3 . ELSE - IF
Конструкция
if (выражение)
оператор
еБе if (выражение)
оператор
еБе if (выражение)
оператор
else
оператор
else
оператор
может быть опущен , или его можно использовать для контроля , чтобы
засечь ''невозможное'' условие.
юw = О;
high = n-l;
while (Iow <= high) {
mid = (low + high) 12;
if (х < v(mid ])
high = mid - 1;
else if (х > v(mid ])
ю w = mid + 1;
else /* fo und match */
return(mid);
}
return(- I );
}
3.4. ПереКЛЮЧi!Гель
nwhite = поtПeг = О;
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
'"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
Упражнение З-1
while (в ы раже н ие )
о пер ато р
оператора.
Опе р ато р
э квивалентен последовательности
вы р ажени е 1;
while (в ы раже н ие 2) {
о п е р ато р
в ыр аже ни е 3;
}
юг (;;) {
Б.8. К<'рниган, Д. М . Ричи Я ЗЫ К "JIOграм""ирования С
Последней операцией языка "С" является запятая ",", которая чаще всего
используется в операторе for . Два выражения , разделенные запятой,
вычисляются слева направо, причем типом и значением результата
Упражнение З-2
3 . б . ЦИКЛ ОО - WНILE
Как уже отмечал ось в л екции 1, циклы while и for обл адают тем
приятным свойством, что в них проверка окончания ОС)'ll.f'ствляется в
начале , а не в конце цикла. Третий оператор цикла языка "С ", do-
whi le , проверяет условие окончания в конце, после каждого прохода
через тело ЦИКJJа ; тело цикла всегда выполняется по крайней мере один
раз. Синтаксис этого оператора имеет вид:
do
оператор while (выражение)
более сложной, чем может показаться сначала. Дел о в том, что простые
методы выделения цифр генерируют их в неправильном порядке. Мы
предпочли получить строку в обратном порядке, а затем обратить ее.
Упражнение 3-3
Упражнение 3-4
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Упражнение З-5
printf('%s\n", line);
}
}
пропускаются.
Упражнение З-6
for( ... )
Ю r ( ... )
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
~ (disaSler)
gO(Q erтoг;
егroг:
[aurк!:
/* foLll1d оле а! ро s itioл i. j */
Программа, И С ПОЛ ЬЗУЮ J..ЦЗя оператор goto , всегда может быть написана
без него , хотя, возможно , за счет повторения некоторых проверок и
в ведения дополнительных пе рем енных. Наприм е р , программа пои ска в
массиве примет в ид:
[aurк! = О;
for (i = О; i < n && !foLll1d; i++)
far U= О; j < m && !faurк!; j++)
faund = v[i]UJ < О;
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
if (fourк1)
/* it was at i-l , j- l */
еЕе
/* rюt foLll1d */
используем ой системы.
"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
i= О;
while(--lim> О && (e=getehar()) != ЕОР && е != '\n')
5[i++ ] = с;
"(е == '\n')
s[i++ ] = е;
s[i] = '\0';
гешrn(О;
}
fo г (i = О ;
5[i] != '\0'; i++) (
fo гU = \ k=O; t[k) ! ='\О' && 50 ) == t[k) ; j ++; k++)
if (t[k) == '\0')
гetuгn(~ ;
)
гe tuгn( -1);
Каждая функция имеет вид имя ( список аргументов, если они имеются)
описания аргументов, есл и он и имеются
dummy О { }
Ге(ШП (выражение)
)hражнение 4-1
'00
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
например , в
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
>О,
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
char line[maxline];
sшn = О;
while (getline(line, maxline) > О)
ргiлtf(' \l%. 2 fIn",swn+=alo ~linе ));
}
описание
return(alO~s));
}
Значение выражения в
Ге(ШП (в ыр ажен и е )
Упражнение 4-2
1 23. 4 5е-6
'"
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
>О,
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
(1- 2)*(4+5)=
записывается в виде
12-45+ * =
el5e if ( о п е рация)
в ын ут ь о п ер ан ды из сге ка
в ып олнить о п е р ацию
>О ,
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
ебе
о ши бка
case '*':
push(popO*pop());
break;
case'-':
ор2 = рорО;
push(poPO-ор2);
break;
case 'f :
ор2 = рорО;
if(op2 != 0.0)
push(poPO/op2);
el5e
ргiлtf("zего divisor popped\n');
break;
case '=':
ргiлtf(' \l%I\n",рush(рорО));
break;
case 'с':
clear();
break;
case toobig:
prinrf('"%.20s ... is too kюg\n",s);
break;
}
}
#define rrnxva! l OO /* rrnxlmumdepth ofva! stack */
>О,
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
push(popQ);
Упражнение 4-3
int sp = О;
ш
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
double va~maxvalJ ;
clear() {... }
int sp;
double va~maxva lJ;
в файле 1:
в фа й ле 2:
cleaI\J {... }
так как описания extern ' в файле l' находятся выше и вне трех
указанных функций, они относятся ко всем ним ; одного набора
описаний достаточно для всего ' файла 2'.
s[i] = е;
if (с == '.') { !* collect fraction *!
if (i < lim)
s[ i] = е;
for(i++;(e=getehar()) >='0' & & e<='9';i++)
if (i < lim)
s[i] = е;
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
ungeleh(e);
s[i] = '\0';
return (пштЬег);
Что же представляют из себя функции' getch ' и ' ung e tc h '? Часто
так бывает, что программа, считывающая входные данные, не может
определить, что она прочла уже достаточно, пока она не прочтет
Упражнение 4-4
Упражнение 4-5
Упражнение 4-6
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
уже встречались.
ge,ehQ {... }
tmge,ehO {... }
regic;(er int х;
regic;(er сМг с;
~с,п)
regic;ter in( С, Л;
{
regic;(er int ~
Язык "С " не является языком с блочной структурой в смысл е PUl или
алгол а; в нем нельзя опи сывать одни функции внутри других.
if (п > { О)
int ~
/* decJare а new i */
for 0= О; i < п; i++)
int х;
ю
{
double х;
int х;
~x)
double х;
{
4.9. Инициализация
>20
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
значения (мусор).
int x = l ;
char sqoote = '\";
Iong day = 60 '" 24; /'" minutes in а day "'/
blnary(x, v, п)
int х, V(], п;
{
int Iow = О;
int high = п- 1;
int mid;
вместо
blnary(x, v, п)
ш
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
int х, V(], п;
{
int Iow, high. mid;
Iow = О;
Шgh = П-l;
nwhite = rюtheг = О;
for (i = О ; i < 10; i++)
ndigil[i] = О;
int nwhite = О;
int nother = О;
int ndigit[lO] = { О, О, О, О, О, О, О, О, О, О };
4.10. Рекурсия
в яз ыке "С " функции могут использоваться рекурсивно; это означает, что
функция может прямо или косвенно обращаться к себе самой.
Традиционным примером является печать числа в виде строки
символов. как мы уже ранее отмечали, циcWы генерируются не в том
порядке: цифры младll.В1х разрядов появляются раньше цифр из cтapll.В1x
разрядов, но печататься они должны в обратном порядке.
char 5(10J;
int ~
if(n < O) {
ршсhaг('-');
n = -п;
i = О;
do {
s[ i++ ] = n % 10 + 'О'; /* get next char */
} while ((п {= 10) > О); {* d~card il *{
while (--i >= О)
ршсhaг(5(iJ);
Альте р натив ой этом у способу яв ляется р екурси вное решение, когда при
каждом вызове функция printd сначала снова об ращается к себе,
чтоб ы ско пировать л идирую щие циcWы , а затем печатает по сл едню ю
ци41:>у.
'"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
Упражнение 4-7
Упражнение 4-8
#include "Шеname"
4.11.2. Макроподстановка
определение вида
#define tes 1
yes - определе нное имя, то в printf{ " yes " ) не бу,цет сделано
никакой подстановки.
",
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
#dеfiлe then
#dеfiлe Ьеgin {
#dеfiлe еnd ;}
и затем написать
if (i > О) шеп
Ьеgin
а = 1;
Ь = 2
еnd
когда строка
х = max(p+q, r+5);
Такая возможность обеспе чив ает " функцию макс и мума", ЮJторая
расLШ1РЯется в последо вател ьный код, а не в обращение к функции. При
правильном обращении с аргументам и таЮJЙ макрос бу,цет работать с
любыми типами данных; здесь нет необ)[)Димости в разл ичных видах
тах для да нных разных типов, как это было бы с функциями.
Упражнение 4-9
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Указатели и массивы
5. Указатели и массивы
рх = &х;
'"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
у = "' рх;
рх = &х;
у = "' рх;
у = х;
указателя
int "' р х;
описаниями. Например ,
>30
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
у = "' рх+ 1
p гintf{'%d\n", "' р х)
в выражениях вида
у = "' рх+ 1
у = ' (р х+ 1)
"' р х = о
"' р х += 1
(' рх)++
ш
Б.8. К<'рниган, Д. М . Ричи Я ЗЫ К "JIOграм""ирования С
он указывает.
ру = рх
что и р х .
swap(a, Ь) ;
swap(x, у) /* wrong */
int Х, у;
{
int {е mp ;
tе ЩJ = х;
х = у;
у = temp;
ш
Б.8. К <'р ниган, Д. М . Ричи Я з ы к "JIOграм""ирования С
= * р х;
tе IТЧJ
* рх = "' р у;
*ру = temp;
}
geunr:
int n, У, array[size);
'"
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
Упражнение 5-1
iлt а[10]
int"'pa
то присваивание
ра = &а[ О]
х = "' ра
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
'(pa+l)
ра = а
>3'
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
int п;
retШ11(п);
}
[(&a(2J)
как и
~a + 2)
или
>3'
Б.8. К<'рниган, Д. М . Ричи Я ЗЫ К "JIOграм""ирования С
a l locbuf .
'"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
описание
Проверки вида
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
отношения, как <, >= И Т.д., работают надлежащим образом. Напр и мер,
p<q
р + п
strlen:
strlen(s) /'" геtшп length of string s "'/
char "'s;
{
char "'р = s;
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
while (* р != '\0')
р ++;
rerurn(p- s);
}
while (* р)
р ++ ;
их, а также прибав л ять к ним переменные типа f loat или double .
"j а т а string"
cha.r *message;
то в результате оператора
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
обычно пишyr
s=t
strcpy(s, () /* сору t (о s */
char s[], t[];
{
int~
i= О;
while « s[i] = t[i]) != '\0')
i++;
'"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
хотя с первого взгляда эта запись может показаться загадочной , она дает
значительное удобство. Этой идиомой сл едует овладеть уже хотя бы
потому. что вы с ней будете часто встречаться в 'С"- программах.
i = О;
while (s[i] == t[i])
if (s[i++ ] == '\0')
return(O);
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
relurn( ,[i]-l[i]);
}
юг ( ,. *s == *t·" s+ + t++)
if (*, == '\0')
relUТn(O);
return(*s-*t);
}
Наприм е р
*++р
*--р
сначала уменьшает р .
Упражнение 5-2
Упражнение 5-3
Упражнение 5-4
'"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
'"
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
представ ить их в виде двух строк двумерного масс и ва, чем пытаться
'"
Б.8. К<'рниган, Д.М. Ричи Язык "JIOграм""ирования С
(0,31,29,31,30,31,30,31 , 3 1,30,31,30,31)
};
>50
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
и л и таким
in' (*dау_taЬ)[lЗ);
• их сортировка
• вывод их в правильном порядке
>52
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
#dеfiлe null О
#define lines 100 /* тах lines to Ье sorted */
nlines = О ;
while ((len = getline(line, mзxlеп)) > О)
if (nlines >= mзxlines)
>53
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
return(-1);
еЕе if «р = alloc(len)) == null)
return (-1);
еЕе {
line[len-l] = '\0'; /* zap newline */
strcpy(p,llne);
llneptr[nllnes++ ] = р ;
return(nllnes);
}
char *llneptr[lines];
int nlines;
{
int i;
>55
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
быстрой сортировки.
Упражнение 5-5
имеются описания
Упражнение 5-6
>58
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
то выходом бу,цет
hello, work:J
равны соответственно " eeho ", " h e110 ," и " wor l d ". Первым
фактическим аргументом является argv (1 ], а последним
argv(arge - 1 ]. Если arge равен 1 , то за именем программы не
следует никакой командной строки аргументов. Все это показано в
eeho :
>59
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
Другой вариант:
Эта версия пока з ывает, что аргумент qюрмата функции printf может
быть выражением, точно так же , как и любой другой. Такое
использование встречается не очень часто , но его все же стоит
запомнить.
>6'
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
if(argc != 2)
prinrl ('\Jsage: find pattem\n');
else
while (gе t1ine(fiлe, mзxlinе) > О)
if (index(line, argv[ l ] >= О )
prinrf('%s", linе);
find -х -п the
Должна выдать
except = 1;
break;
са5е 'п' :
пumbег = 1;
break;
default:
printf("find: illega! орtioп %с\n", *5);
argc = О;
break;
>6'
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
}
if (argc != 1)
pгinrf(''usage: firx:I-х -п pattem\n");
еЕе
while (getline(line, maxliлe) > О) (
linеrю + +;
if«index(line, *argv) >= О) != except) \
if(number)
printf('%Id: ", lineoo);
pгintf('%s", line);
}
}
Упражнение 5-7
add23 4 + *
вычисляет 2*(3+4).
Упражнение 5-8
>63
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Упражнение 5-9
entab m + п
Упражнение 5-10
tail-n
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
sort(v, п, СО пlp , exch) j'" sort stringc; v[Q] ... v{n-l] "'!
сhзг "'v{]; j'" into increasing oгde r "'!
int п;
iлt (*со тр)() , (* ехсЬ)() ;
(
int ga p, i. j;
>6'
Б.8. К<'рниган, Д.М. Ричи Язык "JIOграм""ирования С
(*СОЩJ)(v(j), v(j+gap))
Уl = .'ol(sl);
У2 = .'0I(s2);
if(vl < У2)
relurn( -1);
else if(vl > У2)
relurn(l);
else
relurn (О);
temp = *рх;
*рх = *ру;
*ру = {еmp ;
>6 '
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Упражнение 5-11
Упражнение 5-12
ре гистров сорти руются вместе, так что буква 'а ' прописное и 'а'
строчное оказываются соседними а не разделенными целы м
алфавитом.
Упражнение 5-13
Упражнение 5-14
>6'
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Структуры
6. Структуры
struct date {
int day;
int rтюпш;
>6'
Б.8. К<'рниган, Д. М. Ричи Язык "JIOграм""ирования С
int уеа г;
int yearday;
char nюп_name[4];
};
Точно так же, как в случае любого другого базисного типа, за правой
4игурной скобкой, закрывающей список членов , может следовать
список переменных. оператор
синтаксически аналоrnчен
int x,y,z;
памяти.
struct date d;
>70
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
strucldaled={ 47
" 1776, 186, "J'uJ"},,
Член определенной структуры может быть указан в в ыр ажен ии с
помощью ЮJнструкции ви да
Операция указа ния чл ена структуры" ." связывает имя структуры и имя
чл ена. В качестве примера определим 1 еар (признак ВИСОЮJсности
года) на основе даты, на)[)ДЯщей ся в структуре d ,
if (Slrсmp(d,nюп_name , "aug') == О) .. ,
Или преобра зуем первый символ имени месяца так, чтобы оно
начиналось со стро чной буквы
struct реrsоп {
char nalП'(nalП'size];
char address[adrsize];
Ioпg zipcode; /* почтовый ин декс */
Ioпg ss_пшmег; /* юд соц. Обеспечения */
double salary; /* за рп лата */
struct date birthdate; /* дата ро жден ия */
struct date hiredate; /* дата поступления
на работу */
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
};
то
еmp.Ыгthdаtе.пюпth
описание
pd- >year
(*pd).year
Операции р аботы со структурами" -> " и " ." нарЯAV со () для списка
аргументов и [] для индексов находятся на самом верху иер а рхии
cтapUМHCТBa операций и , следовательно , связываются очень крепко.
Если, например, и меется описание
struct {
int х;
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
int "'у;
} "'р;
то выражение
++ р- > х
6.3. 11ассивыструктур
struct key {
char "'keyword;
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
int kеусоuш;
} keytab [nkeysJ;
strucl key {
char "'keyword;
int keycounr;
};
strucl key keytab [nkeysJ;
struct key {
char "'keyword;
int keycount;
} keytab[] = {
'break", О,
"case", О ,
"char", О,
"continue", О ,
"default", О ,
/* ... "'/
''unsigned'', О ,
"while", О
};
{ 'bгeak", О },
{ "case", О },
",
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
#define maxword 20
#dеfiлe nkеУ' C5izeo~keytab) / 5izeof(5truCl key))
low = О;
high = n-l;
while (Iow <= high) (
mi:I = (Iow+high) / 2;
Щ(соnd = stтcmp(word , tab(mid).keyword)) < О)
high = mi:I- 1;
еЕе if(cond > О)
low = mid + 1;
еЕе
relurn (mi:I);
}
relurn(-1);
}
Выражение
sizeof(objeCl)
'"
Б.8. К <'рниган, Д. М. Р ич и Я ЗЫ К "JIOграм""ирования С
'"
Б.8. К<'рниган, Д. М. Ричи Язык "JIOграм""ирования С
relurn(lelter);
}
Упражнение 6-1
>80
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Упражнение 6-2
Упражнение 6-3
int cond;
strUC! key *Iow = &!аЬ[О] ;
strUC! key *high = &!аЬ[П-l];
stпк:t key *mid;
while (Iow <= high) {
mid = Iow + (high-Iow) / 2;
if ((сооо = strcmp(word, mid->keyword)) < О)
high = mid - 1;
else if(coOO > О)
kJw = mid + l ;
else
re!urn(mid);
re!urn( null);
}
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
То может оказаться, что имя функции тру,цно выдел ить среди текста. В
связи с эт им иногда используется другой стиль записи:
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
#dеfiлe IТ\Зxwогd 20
mainО /* word freguency CO Lll1t */
{
struct tnode *root, *treeO;
сhзг word[maxword];
int t;
root = null;
while «t = getwoгd(word, IТ\Зxwогd)) != EOF)
if (t == letler)
"5
Б.8. К<'рниган, Д.М. Ричи Язык "JIOграм""ирования С
",
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
cha.r *р;
то
'"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
(Struct trюd е *) р
Упражнение б-4
Упражнение б-5
Упражнение б-б
б . б . Поиск в таблице
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
#dеfiлe yes 1
inword = yes;
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
функция strsave про сто копирует стро ку, указа нную в качестве
аргумента, в место хранения, пол ученное в результате обращения к
функции a l loc . Мы уже привел и эту функцию в лещ ии NoS. Так как
обращение к функции alloc и free MOгyr происxqцить в любом
порядке и в связи с проблемой выравнивания , простой вариант
функции alloc из лекц ии N2S нам бол ьше не подходи т; смот рите
лещи и N27 и лекц ии No8 .
Упражнение 6-7
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Упражнение 6-8
6.7. Поля
#dеfiлe keyword 01
#dеfiлe externa] 02
#dеfiлe staoc 04
их выключает, а
struct {
W1Signed is_keyword : 1;
W1Signed is_extern : 1;
W1Signed is_static : 1;
} flags;
дл я включения битов;
'"
Б.8. К<'рниган, Д. М. Ричи Язык "JIOграм""ирования С
flags.is_eX1ern = flags.is_static = О;
для их проверки.
6.8 . Объединения
"5
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
uniоп u_tag {
in! iva~
Поаt fva ~
cha.r *pva~
} uva~
и мя объединения. чле н
или
то есть точно так же, как и в сл учае структур. есл и для отслеживания
",
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
if (utype == iл!)
pгintf{' %d\n", uvaLival);
еЕе if (utype == Воа!)
ргiл!~ '% fIn", uvalfvaQ;
еЕе if (utype == striлg)
pгintf{' %s\n", LNaLpvaI);
еЕе
pгintf{'bad type %d in urype\n", шуре) ;
struc! {
сhзг *natп:';
int flags;
int utype;
tmion {
int iva~
Воа! fva~
сhзг *pya~
}uva~
} syrntab[l15yrn);
syrntab[i].uvalival
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
typedef inllength;
делает имя length синонимом для int . 'ТИ п" l ength может быть
использован в описаниях. переводов типов и Т.д. Точно таким же
образом, как и тип int :
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
treeptr tallocO
{
char *аlЮсО;
return(treeptr) alloc(sizeo~tree node )));
}
200
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
Ввод и вывод
7. Ввод и вывод
# include <s(dlo.h>
20>
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
р го g< inШе
otherprog I prog
202
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
pгo g I а rюtheгрго g
203
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
#include <stdio.h>
бессмысленные результаты.
Упражнение 7-1
20 7
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
208
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
Например, обращение
со строкой на вводе
25 54.32е-1 tlюmpsоп
int i;
209
Б.8. К<'рниган, Д. М. Ричи Язык "JIOграм""ирования С
float х;
char nalП' ( 50 ] ;
scanf{'"%2 d % f %"'d %2s ", &i, &х. natп:');
с вводом
56789012345_72
знак &.
# include <stdio.h>
mainО j'" rudmntary desk cak::u1ator "'!
{
double sшn. у;
sum =O;
while (sc_nf('%lf', &v) !=EOF)
print~'\t%.21\n". sum += v);
2>0
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
scanf{'"%d", п);
вместо
scanf{'"%d", &п) ;
sргintf(na!П', "temp%d", п) ;
Упражнение 7-2
cat Х.С,у.с
ш
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
fp =fopen( name,mode);
ш
Б.8. К<'рниган, Д. М . Ричи Я ЗЫ К "JIOграм""ирования С
e=ge,e(fp )
ро'е(е, ф)
'"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
#include <stdlo.h>
maln(argc, argv) /"'cat: corx::atenate files"'/
int argc;
char *argv[J;
(
fiIe *fp, *fopenO;
if(argc== 1) /"'00 args; со ру standard inрш"' l
fileco py(stdin);
else
while (-- argc > О )
if((fp =fopen(*++argv, Y ))==null) (
printf{"cat:can't о р е п %\n", "'argv);
break;
} else (
file co py(fp );
fclose(fp);
}
ш
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
"irк:lude <stdio.h>
main(argc,argv) /*cat: concatenate files* /
int argc;
char *argv(J ;
{
fiIe *ф, *fopenO;
2>'
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
ш
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
fputs(liлe, [р)
2>'
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
register те *io р ;
{
register in! с;
while (с = *s++)
pUlC(c,iop);
}
Упражнение 7-3
Упражнение 7-4
Упражнение 7-5
О - если нет.
isupper(c) Н е О, есл и "с" буква верхнего регистра ,
О - если нет.
islower(c) Не О , если "с" буква нижнего регистр а,
О - если нет.
isdjgjt(c) Не О , если "с" ци<Wа ,
о - если нет.
isspace(c) Не О, если "с" пробел, табуляция
или новая строка, О - есл и нет.
toupper(c) Пр еоб разует "с" в букву верхнего реги стра .
tolower(c) Преобр азует "с" в букву ни жнего реги ст ра.
tmgetc(c,fp)
220
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
calloc(n, sizeof(object))
char *callocQ;
int *ip;
ip = (iлt*) саlloс(n,sizeоf(iлt));
222
Б.8. К <'рниган, Д. М. Р ич и Я ЗЫ К "JIOграм""ирования С
pгog <infile>outfile
выдача.
22з
Б.8. К<'рниган, Д. М . Ричи Я ЗЫ К "JIOграм""ирования С
Переменная "С " должна быть описана как char, потому что функция
r e ad принимает указатель на символы. Возвраl.LflемыЙ символ должен
быть маскирован числ ом 0377 для гарантии его пол ожител ьности; в
противном случае з наЮJВЫЙ разряд может сделать его значение
от рицательным. ( константа 0377 под~щит ДЛЯ эвм РDР-ll , но не
обязательно для других MaI..lМH).
#dеfiлe null О
#dеfiлe bufsize 512
#define р пюdе 0644/"'гw for оwnе г, Г for gгo up, othe гs"'l
main(aгgc, argv) I"'c p: со ру f1 to f2"'1
int argc;
char *argv[];
{
int f1, f2, л;
char buf[bufsize];
if (argc ! = 3)
e rгo r(' 'usage :c p from {о", null);
if «11 =open(argv[ 1],O))== -1)
е гго г( "с р :са л' t о ре л %5", argv[ l ]);
if « f2 = crea t(argv[2 ] , p lТJ) d e))== -1)
е гго г( "с р : can't create %5", argv[2 ]);
while « n=read(fl, buf,bufsize))>O)
227
Б.8. К<'рниган, Д. М . Ричи Язы к "JIOграм""ирования С
if (write(f2, buf,n) ! = п)
е гro г( "с р : write егroг", null);
exit(O);
}
е гro Г( 5 1 ,52 )
I"' print e rгo г me55age аnd die"'l
сhзг'" 51, 52;
{
pгint~s l ,s2 );
pгint~'\n'J;
exit( l );
}
Упражнение 8-1
229
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
Упражнение 8-2
файла.
230
Б.8. К<'рниган, Д. М. Ричи ЯЗЫК "JIOграм""ирования С
#include <s(dlo.h>
#define prmde 0644 /*r/w for оwnег;г for others*/
fiJe *foреn(name, nюdе) /*ореп file,return fiJe ри*/
regi<;ter char *name, *rmde;
{
regi<;ter in( fd;
regic;ter те *fp;
if(*nюdе !='r'&&*rmde ! = 'w'&&*nюdе ! = 'а' ) {
fprintf(stderr,"illega! nюdе %s opening %s\n",
rmde,name);
exit(l);
юг (ф = _ iob;fp<_iob+_пfilе;fp ++ )
Щ(ф- > _flag & Lread l _ write))==O)
2з2
Б.8. К<'рниган, Д. М. Ричи Язык "JIOграм""ирования С
#include <stdio.h>
_fillbuf(fp) /*allocate and fill input buffer*/
register те *fp;
(
static char smallbuf(nfile);/*for Lll1buffered 1/0*/
char *саПосО;
if((fp-> _flag& _read)==O 11 (ср- > _flag&(EOF I_eIТ)) 1=0
return(EO F);
while(fp- >_ base==null) /*find ЬШfeг space*/
2ЗЗ
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
FILE _iob[nfile] = {
(null,O,_READ,O), /*Sldin*/
(null,O,_ WRIТE,I), /*SldoUl*/
23'
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
Упражнение 8-3
Упражнение 8-4
Упражнение 8-5
236
Б.8. К<'рниган, Д.М. Ричи Язык "JIOграм""ирования С
239
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
'"
Б.8. К<'рниган, Д.М. Ричи Язык "JIOграм""ирования С
выравнив ания все блоки кратны разм еру заголо вка , а сам заго ловок
выровнен н адлежащи м образом. Это дости гаетс я с помощью
объединения, которое содержит желае мую структуру заголо вка и
образец наи более ограничительного по выр ав нив анию типа:
'"
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
значения; этот БОЛbl.LМЙ блок бу,цет затем разделен так, как необ)[)Димо.
Масшгабирующая величина является параметром, который может быть
подобран в соответствии с необходимостью.
'"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
cha.r *а р ;
{
register header * р , *g;
p=(header*)ap-l; /*point {о header*/
for (g=allocp; !(p>g & & p>g- >s. ptr);g=g- >s. ptr)
if (g>=g->s. ptr & & (p>g 11 p<g- >s.ptr))
break; /*а! о ne е nd or other* /
if (p+p->s.size==g- >s. ptr) { /*join to upper nbr*/
p- >s.size += g->s. ptr->s.size;
p- >s. ptr = g- >s. ptr- >s. pu;
} ебе
p- >s. ptr = g- >s. ptr;
if (g+g->s.size== p) { /*join to lower nbr*/
g->s.size+=p- >s.size;
g->s. pu =p->s.рu;
} ебе
g->s. pu =p;
а По с р = g;
}
Упражнение 8-6
Упражнение 8-7
Упражнение 8-8
",
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
9.2.1 . Комментарии
Табл ица 9. 1.
DEC PDP-ll 7 символ ов 2 регистра
HONEYWELL 60006 символ ов 1 регистр
lВM 360/370 7 символ ов 1 регистр
l NТERDAJA 8132 8 символ ов 2 регистра
• int
• e x ter n
• else
• cha r
• r egister
• for
• float
• typede f
• do
• doubl e
• static
• wh i le
• struct
• goto
• sw i tc h
• un i on
• r etur n
'"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
• case
• long
• sizeof
• defau l t
• short
• break
• entry
• unsigned
• continue
• *auto
• if
9.2.5. Константы
размеры.
'"
Б.8. К <'рниган, Д. М. Р ич и Я з ык "JIOграм""ирования С
Таблица 9.2.
новая строка NULF! \п
горизонтальная табуляция нт \t
символ возврата на одну по з ицию BS \Ь
возврат каретки CR \r
переход на новую страницу FF \f
обратная косая черта \ \\
одиночная кавычка \ '
комбинация битов 000 \ddd
250
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
9.2.6. Строки
Таблица 9.3.
25>
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
in t 16 36 32 32
short 16 36 16 16
l ong 32 36 32 32
float 32 36 32 32
doubl e 64 72 б4 64
range -38/+38 -38/+38 -76/+76 -76/+76
{ в ыр ажени е
-- ---- --- н ео б }
252
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
потребностей.
253
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
9.6. Преобразования
255
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
9.7. Выражения
25 7
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
ст р ока
(в ыражени е)
п е р в ичн ое-в ыр аже ни е [ в ыражени е]
п е р в ичн ое-в ыр аже ни е (с пи с о к- в ыр ажений н ео
п е р в ичн ое-l-зн ачени е. Иде н т и4и катор
п е р в ичн ое-в ыр аже ни е -> и ден т иф1 катор
спи сок- в ыраже ний :
в ы р ажение
258
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
259
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
260
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Унарное-выражение:
• * выражение
• & L- з начение
• - выражение
• ! выражение
• - выражение
• ++ L-значение
• - - L-значение
• L- з начение ++
• L- з начение --
• (имя- типа) выражение
• sizeof выражение
• sizeof имя- типа
'6>
Б.8. К <'рниган, Д. М. Р ич и Я з ык "JIOграм""ирования С
262
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
Мультипликативное-выражение:
• выражение * выражение
• выражение / выражение
• выражение % выражение
263
Б.8. К <'рниган, Д. М. Р ич и Я з ык "JIOграм""ирования С
Адцитивное-выражение:
• выражен и е + выражение
• выражен и е - выражение
'"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
Выражение-сдвига:
Выражение-отношения:
265
Б.8. К<'рниган, Д. М . Ричи Я ЗЫ К "JIOграм""ирования С
Операции < (меньше), > (больше), <= (меньше или равно) и >= (больше
или равно) все дают О , есл и указанное отношение л ожно, и 1, если оно
исгинно. Резynьтат имеет тип in t . Выпол няются обычные
арифметические преобразования. Мосут сравн и ваться два указателя;
резynьтат завис ит от относительного расположения указываемых
Выражение-равенсгва:
• выражен и е == выражен и е
• выражен и е != выражен и е
266
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
267
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
Выражение- л оrnческого-и л и:
выражение 11 выражение
Условное-выражение:
выражение? в ыраже ние: выражение
268
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Выражение-присваивания:
• L- з начение = выражение
• L- з начение += выражение
• L- з начение - = выражение
• L- з начение * = выражение
• L- з начение 1= выражение
• L- з начение %= выражение
• L- з начение > >= выражение
• L- з начение « = выражение
• L- з начение & = выражение
• L- з начение л = выражение
• L- з начение I= выражение
269
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
~ a,(t=3,t+ 2 ) ,с)
9.8. Описания
Описание:
с п ецифи като ры-о пи сани я с пи сок- о п исателей
н еоб;
270
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
С пециф1каторы- описания:
Спецификаторы-описания:
специф1катор-типа спецификаторы-описания
необ
специф1катор-класса-памяти с пецификатор-опи сания
необ
С пециф1катор-класса-памяти:
• auto
• static
• e x ter n
• r egister
• typede f
С пециф1катор- типа:
• char
• short
• int
• long
• unsigned
• float
• double
• спецификатор- структуры -и л и-объединения
• определяющее-тип-имя
short iш
272
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
Iong irn
W1Signed int
Iong float
9.8.3 .0ПИСi!Гели
С пи с о к-о пи сателей:
иници ал и зируемый -о пи сатель
иници ал и з ируемый -о пи сатель, с пи со к-опи сателе й
ини циализ ируе мы й -о писатель:
о писател ь-иници ал и затор
н еоб
о пи сатель:
идентиф1като р
( о писатель )
>1< о пи сатель
о писатель О
о писатель [константное- в ы р ажение
н ео б]
27з
Б.8. К<'рниган, Д. М. Ричи Язык "JIOграм""ирования С
t di
*d
на t ".
dO
то содержащийся идентификато р имеет тип функция,
возвращающая t ".
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
d[константное-выражение]
или
d[ ]
С труктура-или-объединение:
• 51RUCT
• UNЮN
Описатель- ст руктур ы :
о пи сатель
: ко нстан т н о е в ыражени е
277
Б.8. К <'р ниган, Д. М. Ричи Я з ык "JIOграм""ирования С
автомати чески.
struct идентификатор
278
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
непереносимоЙ).
struct mode {
char (word[20];
int count;
struct mode "'left;
struct mode "' right;
};
279
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Sp- >count
s.left
9.8.6. Инициализация
Инициализатор:
= выражение
= {список-инициализатора}
= {список-инициализатора,}
с пи со к-инициали зато р а:
выражение
{cnисок- инициализатора }
Например,
'"
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
Поаt у( 4]( З] = {
{ 1, 3,5 },
{2, 4,6 },
{З,S, 7} ,
};
Поаt у( 4]( З] = {
1, 3, 5, 2, 4, 6, 3, 5, 7
};
Поаt у(4]( З] = {
{l ], {2}, {З } , {4 ]
};
и наконец , описание
помощью строки.
282
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Имя типа:
с пециф.iкатор-типа абстрактный-описатель
абстрактный-описатель:
п усто
(абстрактный-описатель)
'" абстрактный описатель
абст рактный-опи сатель О
абстрактный-описатель [константное выражение
неоБJ
(абстрактный описатель)
iлl
int'"
iлl *[3]
iлl (*)[3]
iлl *0
iлl (*)()
283
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
9.8.8 . ТYPEDEF
типы.
Определяющее-тип-имя
идентиф1катор
ЮJнструкции
miles dlstance;
ежеrn klicksp metricp;
complex Z, "'zp;
9.9 . Операторы
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
выполняются последовательно.
выражение;
составной оператор:
{список-описаний список-операторов
необ необ}
список-описаний:
описание
оператор
оператор с пи со к-операторов
285
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
1. IF (выражен и е) оператор
2. IF (выражение) оператор ELSE оператор
9.9.5. Оператор 00
286
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
в ыр ажени е- l ;
в ы ражение - З
Любое выражение или даже все они мосут быть опущены. Если
отсутствует второе выражение, то предложение с while считается
э квивалентным whi l e ( l ) ; другие отсутствующие выражения просто
оп ускаются из приведенноro выше расширения.
287
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
default:
Оператор
bгeak;
Оператор
сопtiпuе;
Ге[ШП;
Ге[ШП в ыражение;
289
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
идентиф1катор:
290
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
о пр еделение -функции :
О писател ь-функции :
о пи сатель (с п исок- п а р а мет р ов
н еоб)
с пи со к п а рамет р о в :
тел о-функции :
с пи со к-о пи саний состав но й -о пе р ато р
'"
Б.8. К <'р ниган, Д. М. Ричи Я з ык "JIOграм""ирования С
int maх(а , Ь , с)
int а, Ь, с ;
(
int Щ
т = (а > Ь) ? а:Ь;
[Nшп((m> с)? т:с);
}
292
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
определение-данных:
описание
293
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
{
auto int d.istance;
'"
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
выделен ию памяти.
295
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
# Ш1d е f идентиф.iкато р
иденти фикатора.
296
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
297
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
9.14.2. Функции
iлt Ю;
g(Q;
g(funcp) iлt(*funcр)();
{
(*funcр )();
298
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
Рассмотрим,например, описание
iлt x[3][5J;
299
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
будет переносимым.
- -
либо тернарной операцией
7:
зm
Б.8. К<'рниган, Д. М. Ричи Я ЗЫ К "JIOграм""ирования С
памяти.
Так как язык "С" является раз вивающимся языком, в старых программах
можно встретить HeКDTopыe уста ревшие КDнструкции. Хотя
болы.LIИН СТВО версий КDмпилятора поддерживает такие анахронизмы,
они в КDHцe КDHЦOB исчезнут, оставив за собой только проблемы
переносимости.
зоз
Б.8. К<'рниган, Д. М. Ричи Я зы к "JIOграм""ирования С
которых является
х= -1
-1 к х.
intx = l ;
использовалось
int х 1;
iлt f (1+2)
9.18.1. Выражения
выражение:
первичное-выражение
* выражение
& выражение
- выражение
! Выр ажен ие
3"'
Б.8. К<'рниган, Д. М. Ричи Язык "JIOграм""ирования С
Л выражение
++ l-значение
-- l-значение
l-значение ++
l-значение --
sizeof выражение
(имя типа) выражение
выражение бинарная-операция выражение
выражение ? Выражение: выражение
l-значение операция-присваивания выражение
выражение , выражение
первичное выражение:
иде нтификатор
константа
строка
(выражение)
первичное-выражение (с писок выражений
необ)
первичное-выражение [выражение]
l-значение . Идентификатор
первичное выражение - > идентификатор
l-значение:
иде нтификатор
первичное-выражение [выражение]
l-значение
. Идентификатор
первичное-выражение -> идентиф1катор
* выражение
(l-значение)
о [] . - >
имеют самый высокий приоритет и группируются слева направо.
Унарные операции
Бинарные операции:
• * / %
• + -
• » «
• < > <= >=
• -- !=
·• -
• &
• &&
• II
• ?:
9.18.2. Описания
Описание:
с п е циqм каторы - о пи сан ия с пи сок-и ници ал и зируемых- о пи сателей
н еоб;
с п е ци qмкатор ы- о пи сан ия :
306
Б.8. К<'рниган, Д. М. Ричи Язык "JIOграм""ирования С
специ4икатор-типа специф1каторы-описания
необ
специ4икатор-класса-памяти с пециф1каторы-опи сан ия
необ
с пециф1катор-класса-памяти:
ашо
static
extem
regi<;ter
typedef
с пециф1катор-типа:
char
soort
int
long
W1Signed
float
double
специф1катор-структуры-или-объединения
оп ределяющее-тип имя -
с пи со к-инициали зи руемы х-опи сателе й:
инициализируемый-описатель
инициализируемый-описатель,
список-инициализируемых-описателей
инициали зируемы й-описатель
описатель-инициализатор
необ
описатель:
идентиф1катор
(опи сател ь)
* описатель
описатель О
описатель (константное выражение
необ ]
с пециф1катор-структуры-или-объединения:
struct список-описателей-структуры
struct иде нтиф1катор {список-описаний-структуры)
struct иде нтиф1катор
307
Б.8. К<'рниган, Д.М. Ричи Язык "JIOграм""ирования С
uniоп {список-описаний-структуры}
uniоп иденти4икатор {список-описаний-структуры}
uniоп иденти4икатор
список-описаний-структуры:
описание-структуры
описание-структуры список-описаний-структуры
описание структуры:
специ4икатор-типа список-описателей-структуры:
список-описателей-структуры
описатель-структуры
описатеЛЬ-СТРУКТУРЫ,список-описателей-структуры
описатель-структуры:
описатель
:константное-выражение
инициализатор:
= выражение
= {список-инициализатора}
= {список-инициализатора}
список инициализатора:
выражение
список-инициализатора,список-инициализатора
{список-инициализатора}
имя-типа:
специ4икатор-типа абстрактный-описатель
абстрактный-описатель:
пусто
{абстрактный-описатель}
* абстрактный-описатель
абстрактный-описатель О
абстрактный-описатель [константное-выражение
необ]
определяющее-тип-имя:
идентиф1катор
9.18.3. Операторы
составной-оператор:
ЗО8
Б.8. К<'рниган, Д. М. Ричи Язык "JIOграм""ирования С
{список-описаний список-операторов
необ необ}
список-описаний:
описание
описание список-описаний
список-операторов:
оператор
оператор список-операторов
оператор:
составной оператор
выражение;
if (выражение) оператор
if(выражение) оператор ебе оператор
while (выражение) оператор
do оператор while (выражение);
foг(выражение-l ;выражение-2 ;выражение-З )
необ необ необ
оператор
return выражение;
goto идентификатор;
иде нтификатор: оператор
Программа:
внешнее-определение
внешнее-определение программа
внешнее-определение:
определение-функции
определение-данных
309
Б.8. К<'рниган, Д.М. Ричи ЯЗЫК "JIOграм""ирования С
определение-функции:
специф1катор-типа описатель-функции тело-функции
необ
описатель-функции:
описатель (список-параметров)
необ
список-параметров:
идетиф1катор
идентиф1катор , список-параметров
тело-функции:
список-описаний-типа оператор-функции
оператор-функции:
{список описаний список-операторов}
необ
определение данных:
9.18.5. Препроцессор
с с и нтакс и сом
enum с пи с о к- п еречислени я
enum идентификатор
Б.8. К<'рниган, Д. М . Ричи Я зы к "JIOграм""ирования С
с пи со к- пе ре чи сле ния :
п е ре ч исл яемо е
п е ре ч исляемое:
идентиф1като р
Таблица 9.4.
Значение Изображение" в тексте
Вертикальная черта
Апостороф \ '
Волнистая черта
Содержание
Титульная страница 2
Выход ные данные 3
Лекция о. Аннотация и введ ение 4
Лекция 1. Учебное введение 12
Лекция 2. Типы , операции и выражения 52
Лекция з. Управление потоком 78
Лекция 4. Функции и структура программ 96
Лекция 5. Указатели и массивы 129
Лекция 6. Структуры 169
Лекция 7. Ввод и вывод 201
Лекция 8. Интерфейс системы ИNIХ 222
Лекция 9. Справочное руководство по я з ыку С 247