Брайан Керниган - Язык программирования Си. Издание 3-е, исправленное
- Название:Язык программирования Си. Издание 3-е, исправленное
- Автор:
- Жанр:
- Издательство:Невский Диалект
- Год:2001
- Город:Санкт-Петербург
- ISBN:0-13-110362-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Брайан Керниган - Язык программирования Си. Издание 3-е, исправленное краткое содержание
Книга широко известных авторов, разработчиков языка Си, переработанная и дополненная с учетом стандарта ANSI для языка Си, 2-е английское издание которой вышло в 1988 году, давно стала классикой для всех изучающих и/или использующих как Си, так и Си++. Русский перевод этой книги впервые был выпущен изд- вом "Финансы и статистика" в 1992 г. и с тех пор пользуется неизменным спросом читателей.
Для настоящего третьего русского издания перевод заново сверен с оригиналом, в него внесены некоторые поправки, учитывающие устоявшиеся за прошедшие годы изменения в терминологии, а так же учтены замечания, размещенные автором на странице http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html.
Для программистов, преподавателей и студентов.
Издание подготовлено при участии издательства "Финансы и статистика"
Язык программирования Си. Издание 3-е, исправленное - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
int lower, upper, step;
char с, line[1000];
Переменные можно распределять по объявлениям произвольным образом, так что указанные выше списки можно записать и в следующем виде:
int lower;
int upper;
int step;
char c;
char line[1000];
Последняя форма записи занимает больше места, тем не менее она лучше, поскольку позволяет добавлять к каждому объявлению комментарий. Кроме того, она более удобна для последующих модификаций.
В своем объявлении переменная может быть инициализирована, как, например:
char esc = '\\';
int i = 0;
int limit = MAXLINE+1;
float eps = 1.0e-5;
Инициализация неавтоматической переменной осуществляется только один раз - перед тем, как программа начнет выполняться, при этом начальное значение должно быть константным выражением. Явно инициализируемая автоматическая переменная получает начальное значение каждый раз при входе в функцию или блок, ее начальным значением может быть любое выражение. Внешние и статические переменные по умолчанию получают нулевые значения. Автоматические переменные, явным образом не инициализированные, содержат неопределенные значения ("мусор").
К любой переменной в объявлении может быть применен квалификатор constдля указания того, что ее значение далее не будет изменяться.
const double е = 2.71828182845905;
const char msg[] = "предупреждение: ";
Применительно к массиву квалификатор constуказывает на то, что ни один из его элементов не будет меняться. Указание constможно также применять к аргументу- массиву, чтобы сообщить, что функция не изменяет этот массив:
int strlen(const char[]);
Реакция на попытку изменить переменную, помеченную квалификатором constзависит от реализации компилятора.
2.5 Арифметические операторы
Бинарными (т. е. с двумя операндами) арифметическими операторами являются +, -, *, /, а также оператор деления по модулю %. Деление целых сопровождается отбрасыванием дробной части, какой бы она ни была. Выражение
x % y
дает остаток от деления x на y и, следовательно, нуль, если x делится на y нацело. Например, год является високосным, если он делится на 4, но не делится на 100. Кроме того, год является високосным, если он делится на 400. Следовательно,
if ((year % 4 == 0 && year % 100 !=0 || year % 400 == 0)
printf("%d високосный год\n", year);
else
printf("%d невисокосный год\n", year);
Оператор %к операндам типов floatи doubleне применяется. В какую сторону (в сторону увеличения или уменьшения числа) будет усечена дробная часть при выполнении /и каким будет знак результата операции %с отрицательными операндами, зависит от машины.
Бинарные операторы +и -имеют одинаковый приоритет, который ниже приоритета операторов *, /и %, который в свою очередь ниже приоритета унарных операторов +и -. Арифметические операции одного приоритетного уровня выполняются слева направо.
В конце этой главы (параграф 2.12) приводится таблица 2.1,в которой представлены приоритеты всех операторов и очередность их выполнения.
2.6 Операторы отношения и логические операторы
Операторами отношения являются
›
›=
‹
‹=
Все они имеют одинаковый приоритет. Сразу за ними идет приоритет операторов сравнения на равенство:
==
!=
Операторы отношения имеют более низкий приоритет, чем арифметические, поэтому выражение вроде i ‹ lim-1 будет выполняться так же, как i ‹ (lim-1), т.е. как мы и ожидаем.
Более интересны логические операторы & &и ||. Выражения, между которыми стоят операторы && или ||, вычисляются слева направо. Вычисление прекращается, как только становится известна истинность или ложность результата. Многие Си-программы опираются на это свойство, как, например, цикл из функции getline, которую мы приводили в главе 1:
for (i = 0; i ‹ lim-1 && (с = getchar()) != EOF && с != '\n'; ++i)
s[i] = c;
Прежде чем читать очередной символ, нужно проверить, есть ли для него место в массиве s, иначе говоря, сначала необходимо проверить соблюдение условия i ‹ lim-1. Если это условие не выполняется, мы не должны продолжать вычисление, в частности читать следующий символ. Так же было бы неправильным сравнивать c и EOF до обращения к getchar; следовательно, и вызов getchar, и присваивание должны выполняться перед указанной проверкой.
Приоритет оператора &&выше, чем таковой оператора ||, однако их приоритеты ниже, чем приоритет операторов отношения и равенства. Из сказанного следует, что выражение вида
i ‹ lim-1 && (с = getchar()) != '\n' && с != EOF
не нуждается в дополнительных скобках. Но, так как приоритет !=выше, чем приоритет присваивания, в
(с = getchar()) != '\n'
скобки необходимы, чтобы сначала выполнить присваивание, а затем сравнение с '\n'.
По определению численным результатом вычисления выражения отношения или логического выражения является 1, если оно истинно, и 0, если оно ложно.
Унарный оператор !преобразует ненулевой операнд в 0, а нуль в 1. Обычно оператор !используют в конструкциях вида
if (!valid)
что эквивалентно
if (valid == 0)
Трудно сказать, какая из форм записи лучше. Конструкция вида !valid хорошо читается ("если не правильно"), но в более сложных выражениях может оказаться, что ее не так-то легко понять.
Упражнение 2.2. Напишите цикл, эквивалентный приведенному выше or-циклу, не пользуясь операторами && и ||.
2.7 Преобразования типов
Если операнды оператора принадлежат к разным типам, то они приводятся к некоторому общему типу. Приведение выполняется в соответствии с небольшим числом правил. Обычно автоматически производятся лишь те преобразования, которые без какой-либо потери информации превращают операнды с меньшим диапазоном значений в операнды с большим диапазоном, как, например, преобразование целого в число с плавающей точкой в выражении вроде f+i. Выражения, не имеющие смысла, например число с плавающей точкой в роли индекса, не допускаются. Выражения, в которых могла бы теряться информация (скажем, при присваивании длинных целых переменным более коротких типов или при присваивании значений с плавающей точкой целым переменным), могут повлечь за собой предупреждение, но они допустимы.
Значения типа char- это просто малые целые, и их можно свободно использовать в арифметических выражениях, что значительно облегчает всевозможные манипуляции с символами. В качестве примера приведем простенькую реализацию функции atoi, преобразующей последовательность цифр в ее числовой эквивалент.
Читать дальшеИнтервал:
Закладка: