1.1. Hачинаем. Единственный способ освоить новый язык
программирования - писать на нем программы. Первая програм-
ма, которая должна быть написана, - одна для всех языков:
напечатать слова : HELLO, WORLD.
Это - самый существенный барьер; чтобы преодолеть его,
вы должны суметь завести где-то текст программы, успешно его
скомпилировать, загрузить, прогнать и найти, где оказалась
ваша выдача. Если вы научились справляться с этими техничес-
кими деталями, все остальное сравнительно просто.
· 12 -
Программа печати “HELLO, WORLD” на языке “C” имеет вид:
MAIN ()
{
PRINTF(“HELLO, WORLD\N”);
}
Как пропустить эту программу - зависит от используемой
вами системы. В частности, на операционной системе “UNIX” вы
должны завести исходную программу в файле, имя которого
оканчивается на “.C” , например, HELLO.C , и затем скомпили-
ровать ее по команде
CC HELLO.C
Если вы не допустили какой-либо небрежности , такой как
пропуск символа или неправильное написание, компиляция прой-
дет без сообщений и будет создан исполняемый файл с именем
а.OUT . Прогон его по команде
A.OUT
приведет к выводу
HELLO, WORLD
На других системах эти правила будут иными; проконсуль-тируйтесь с местным авторитетом.
Упражнение 1-1.
Пропустите эту программу на вашей системе. Попробуйте
не включать различные части программы и посмотрите какие со-
общения об ошибках вы при этом получите.
Теперь некоторые пояснения к самой программе. Любая
“C”-программа, каков бы ни был ее размер, состоит из одной
или более “функций”, указывающих фактические операции
компьютера, которые должны быть выполнены. Функции в языке
“C” подобны функциям и подпрограммам фортрана и процедурам
PL/1, паскаля и т.д. В нашем примере такой функцией является
MAIN. Обычно вы можете давать функциям любые имена по вашему
усмотрению, но MAIN - это особое имя; выполнение вашей прог-
раммы начинается сначала с функции MAIN. Это означает, что
каждая программа должна в каком-то месте содержать функцию с
именем MAIN. Для выполнения определенных действий функция
MAIN обычно обращается к другим функциям, часть из которых
находится в той же самой программе, а часть - в библиотеках,
содержащих ранее написанные функции.
· 13 -
Одним способом обмена данными между функциями является
передача посредством аргументов. Круглые скобки, следующие
за именем функции, заключают в себе список аргументов; здесь
маIN - функция без аргументов, что указывается как (). Опе-
раторы, составляющие функцию, заключаются в фигурные скобки
{ и }, которые аналогичны DO-END в PL/1 или BEGIN-END в ал-
голе, паскале и т.д. Обращение к функции осуществляется ука-
занием ее имени, за которым следует заключенный в круглые
скобки список аргументов. здесь нет никаких операторов CALL,
как в фортране или PL/1. Круглые скобки должны присутство-
вать и в том случае, когда функция не имеет аргументов.
Строка
PRINTF(“HELLO, WORLD\N”);
является обращением к функции, которое вызывает функцию
с именем PRINTF и аргуметом “HELLO, WORLD\N”. Функция PRINTF
является библиотечной функцией, которая выдает выходные дан-
ные на терминал (если только не указано какое-то другое мес-
то назначения). В данном случае печатается строка символов,
являющаяся аргументом функции.
Последовательность из любого количества символов, зак-
люченных в удвоенные кавычки “...”, называется 'символьной
строкой' или 'строчной константой'. Пока мы будем использо-
вать символьные строки только в качестве аргументов для
PRINTF и других функций.
Последовательность \N в приведенной строке является
обозначением на языке “C” для 'символа новой строки', кото-
рый служит указанием для перехода на терминале к левому краю
следующей строки. Если вы не включите \N (полезный экспери-
мент), то обнаружите, что ваша выдача не закончится перехо-
дом терминала на новую строку. Использование последователь-
ности \N - единственный способ введения символа новой строки
в аргумент функции PRINTF; если вы попробуете что-нибудь
вроде
PRINTF(“HELLO, WORLD
“);
то “C”-компилятор будет печатать злорадные диагностические
сообщения о недостающих кавычках.
Функция PRINTF не обеспечивает автоматического перехода
на новую строку, так что многократное обращение к ней можно
использовать для поэтапной сборки выходной строки. Наша пер-
вая программа, печатающая идентичную выдачу, с точно таким
же успехом могла бы быть написана в виде
MAIN()
{
PRINTF(“HELLO, “);
PRINTF(“WORLD”);
PRINTF(“\N”);
}
· 14 -
Подчеркнем, что \N представляет только один символ. Ус-
ловные 'последовательности', подобные \N , дают общий и до-
пускающий расширение механизм для представления трудных для
печати или невидимых символов. Среди прочих символов в языке
“C” предусмотрены следующие: \т - для табуляции, \B - для
возврата на одну позицию, \” - для двойной кавычки и \\ для
самой обратной косой черты.
Упражнение 1-2.
Проведите эксперименты для того, чтобы узнать что прои-
зойдет, если в строке, являющейся аргументом функции PRINTF
будет содержаться \X, где X - некоторый символ, не входящий
в вышеприведенный список.
1.2. Переменные и арифметика.
Следующая программа печатает приведенную ниже таблицу
температур по Фаренгейту и их эквивалентов по стоградусной
шкале Цельсия, используя для перевода формулу
C = (5/9)*(F-32).
0 -17.8
20 -6.7
40 4.4
60 15.6
... ...
260 126.7
280 137.8
300 140.9
Теперь сама программа:
/* PRINT FAHRENHEIT-CELSIUS TABLE
FOR F = 0, 20, ..., 300 */
MAIN()
{
INT LOWER, UPPER, STEP;
FLOAT FAHR, CELSIUS;
LOWER = 0; /* LOWER LIMIT OF TEMPERATURE
TABLE */
UPPER =300; /* UPPER LIMIT */
STEP = 20; /* STEP SIZE */
FAHR = LOWER;
WHILE (FAHR <= UPPER) {
CELSIUS = (5.0/9.0) * (FAHR -32.0);
PRINTF(“%4.0F %6.1F\N”, FAHR, CELSIUS);
FAHR = FAHR + STEP;
}
}
· 15 -
Первые две строки
/* PRINT FAHRENHEIT-CELSIUS TABLE
FOR F = 0, 20, ..., 300 */
являются комментарием, который в данном случае кратко пояс-
няет, что делает программа. Любые символы между /* и */ иг-
норируются компилятором; можно свободно пользоваться коммен-
тариями для облегчения понимания программы. Комментарии мо-
гут появляться в любом месте, где возможен пробел или пере-
ход на новую строку.
В языке “C” все переменные должны быть описаны до их ис-
пользования, обычно это делается в начале функции до первого
выполняемого оператора. Если вы забудете вставить описание,
то получите диагностическое сообщение от компилятора. Описа-
ние состоит из типа и списка переменных, имеющих этот тип,
как в
INT LOWER, UPPER, STEP;
FLOAT FAHR, CELSIUS;
Тип INT означает, что все переменные списка целые; тип
FLOAT предназначен для чисел с плавающей точкой, т.е. для
чисел, которые могут иметь дробную часть. Точность как INT ,
TAK и FLOAT зависит от конкретной машины, на которой вы ра-
ботаете. На PDP-11, например, тип INT соответствует 16-бито-
вому числу со знаком, т.е. числу, лежащему между -32768 и
+32767. Число типа FLOAT - это 32-битовое число, имеющее
около семи значащих цифр и лежащее в диапазоне от 10е-38 до
10е+38. В главе 2 приводится список размеров для других ма-
шин.
В языке “C” предусмотрено несколько других основных ти-
пов данных, кроме INT и FLOAT:
CHAR символ - один байт
SHORT короткое целое
LONG длинное целое
DOUBLE плавающее с двойной точностью
Размеры этих объектов тоже машинно-независимы; детали
приведены в главе 2. Имеются также массивы, структуры и об-
ъединения этих основных типов, указатели на них и функ-
ции,которые их возвращают; со всеми ними мы встретимся в
свое время.
Фактически вычисления в программе перевода температур
начинаются с операторов присваивания
LOWER = 0;
UPPER =300;
STEP = 20;
FAHR =LOWER;
которые придают переменным их начальные значения. каждый от-
дельный оператор заканчивается точкой с запятой.
Каждая строка таблицы вычисляется одинаковым образом,
так что мы используем цикл, повторяющийся один раз на стро-
ку. В этом назначение оператора WHILE:
WHILE (FAHR <= UPPER) {
....
}
· 16 -
проверяется условие в круглых скобках. Если оно истинно
(FAHR меньше или равно UPPER), то выполняется тело цикла
(все операторы, заключенные в фигурные скобки { и } ). Затем
вновь проверяется это условие и, если оно истинно, опять вы-
полняется тело цикла. Если же условие не выполняется ( FAHR
превосходит UPPER ), цикл заканчивается и происходит переход
к выполнению оператора, следующего за оператором цикла. Так
как в настоящей программе нет никаких последующих операто-
ров, то выполнение программы завершается.
Тело оператора WHILE может состоять из одного или более
операторов, заключенных в фигурные скобки, как в программе
перевода температур, или из одного оператора без скобок,
как, например, в
WHILE (I < J)
I = 2 * I;
В обоих случаях операторы, управляемые оператором WHILE,
сдвинуты на одну табуляцию, чтобы вы могли с первого взгляда
видеть, какие операторы находятся внутри цикла. Такой сдвиг
подчеркивает логическую структуру программы. Хотя в языке
“C” допускается совершенно произвольное расположение опера-
торов в строке, подходящий сдвиг и использование пробелов
значительно облегчают чтение программ. Мы рекомендуем писать
только один оператор на строке и (обычно) оставлять пробелы
вокруг операторов. Расположение фигурных скобок менее сущес-
твенно; мы выбрали один из нескольких популярных стилей. Вы-
берите подходящий для вас стиль и затем используйте его пос-
ледовательно.
Основная часть работы выполняется в теле цикла. Темпера-
тура по Цельсию вычисляется и присваивается переменной
CELAIUS оператором
CELSIUS = (5.0/9.0) * (FAHR-32.0);
причина использования выражения 5.0/9.0 вместо выглядящего
проще 5/9 заключается в том, что в языке “C”, как и во мно-
гих других языках, при делении целых происходит усечение,
состоящее в отбрасывании дробной части результата. Таким об-
разом, результат операции 5/9 равен нулю, и, конечно, в этом
случае все температуры оказались бы равными нулю. Десятичная
точка в константе указывает, что она имеет тип с плавающей
точкой, так что, как мы и хотели, 5.0/9.0 равно 0.5555... .
Мы также писали 32.0 вместо 32 , несмотря на то, что так
как переменная FAHR имеет тип FLOAT , целое 32 автоматически
бы преобразовалось к типу FLOAT ( в 32.0) перед вычитанием.
С точки зрения стиля разумно писать плавающие константы с
явной десятичной точкой даже тогда, когда они имеют целые
значения; это подчеркивает их плавающую природу для просмат-
ривающего программу и обеспечивает то, что компилятор будет
смотреть на вещи так же, как и Вы.
· 17 -
Подробные правила о том, в каком случае целые преобразу-
ются к типу с плаваюшей точкой, приведены в главе 2. Сейчас
же отметим, что присваивание
FAHR = LOWER;
проверка
WHILE (FAHR <= UPPER)
работают, как ожидается, - перед выполнением операций целые
преобразуются в плавающую форму.
Этот же пример сообщает чуть больше о том, как работает
PRINTF. Функция PRINTF фактически является универсальной
функцией форматных преобразований, которая будет полностью
описана в главе 7. Ее первым аргументом является строка сим-
волов, которая должна быть напечатана, причем каждый знак %
указывает, куда должен подставляться каждый из остальных ар-
гументов /второй, третий, .../ и в какой форме он должен пе-
чататься. Например, в операторе
PRINTF(“%4.0F %6.1F\N”, FAHR, CELSIUS);
спецификация преобразования %4.0F говорит, что число с пла-
вающей точкой должно быть напечатано в поле шириной по край-
ней мере в четыре символа без цифр после десятичной точки.
спецификация %6.1F описывает другое число, которое должно
занимать по крайней мере шесть позиций с одной цифрой после
десятичной точки, аналогично спецификациям F6.1 в фортране
или F(6,1) в PL/1. Различные части спецификации могут быть
опущены: спецификация %6F говорит, что число будет шириной
по крайней мере в шесть символов; спецификация %2 требует
двух позиций после десятичной точки, но ширина при этом не
ограничивается; спецификация %F говорит только о том, что
нужно напечатать число с плавающей точкой. Функция PRINTF
также распознает следующие спецификации: %D - для десятично-
го целого, %о - для восьмеричного числа, %х - для шестнадца-
тиричного, %с - для символа, %S - для символьной строки и %%
· для самого символа %.
Каждая конструкция с символом % в первом аргументе функ-
ции PRINTF сочетается с соответствующим вторым, третьим, и
т.д. Аргументами; они должны согласовываться по числу и ти-
пу; в противном случае вы получите бессмысленные результаты.
Между прочим, функция PRINTF не является частью языка
“C”; в самом языке “C” не определены операции ввода-вывода.
Нет ничего таинственного и в функции PRINTF ; это - просто
полезная функция, являющаяся частью стандартной библиотеки
подпрограмм, которая обычно доступна “C”-программам. Чтобы
сосредоточиться на самом языке, мы не будем подробно оста-
навливаться на операциях ввода-вывода до главы 7. В частнос-
ти, мы до тех пор отложим форматный ввод. Если вам надо
ввести числа - прочитайте описание функции SCANF в главе 7,
раздел 7.4. Функция SCANF во многом сходна с PRINTF , но она
считывает входные данные, а не печатает выходные.
· 18 -
Упражнение 1-3.
Преобразуйте программу перевода температур таким обра-
зом, чтобы она печатала заголовок к таблице.
Упражнение 1-4.
Напишите программы печати соответствующей таблицы пере-
хода от градусов цельсия к градусам фаренгейта.
... основаниям. При этом философская абстракция языка оказывается неразрывно связана с основными темами и движениями философии в целом. Более конкретно, на ранние стадии традиционно рассматриваемого в рамках АФ анализа обыденного языка глубокое влияние оказала философия Дж. Э. Мура, особенно его учение о здравом смысле, согласно которому такие понятия, как «человек», «мир», «я», «внешний мир», « ...
... и других странах СНГ, а также облегчение доступа к русской и мировой культуре и науке. Таким образом, судя по данным наших исследований, востребованность русского языка осталась в республике достаточно высокой. Многие представители современной молдавской молодежи продолжают, как их отцы и деды, тянуться к русской культуре, научным и техническим достижениям России. Русский язык остается языком ...
... рисуночное словесно-слоговое письмо). Памятники среднеэламского периода (14—12 вв. до н.э.) выполнены аккадской клинописью. Памятники новоэламского периода относятся к 8—6 вв. до н.э. Был официальным языком в персидском государстве Ахеменидов в 6—4 вв. предполагается, что он, подвергшись влиянию древнеперсидского, сохранился до раннего средневековья. 7. Бурушаски язык Язык бурушаски ( ...
... /диалект), скифский, согдийский, среднеперсидский, таджикский, таджриши (язык/диалект), талышский, татский, хорезмийский, хотаносакский, шугнано-рушанская группа языков, ягнобский, язгулямский и др. Они относятся к индоиранской ветви индоевропейских языков. Области распространения: Иран, Афганистан, Таджикистан, некоторые районы Ирака, Турции, Пакистана, Индии, Грузии, Российской Федерации. Общее ...
0 комментариев