798 Приложение А
10. Пробельные символы — это символы пробела, табуляции и новой строки. В языке С пробельные символы служат для отделения конструкций друг от друга; в scanf() пробелы используются для разделения последовательных элементов ввода.
11. Символ z в % z является модификатором, а не спецификатором, поэтому он требует указания спецификатора для модификации. Вы могли бы использовать %zd для вывода результата по основанию 10 или другого спецификатора для вывода в системе счисления с другим основанием, например, %zx для шестнадцатеричной формы.
12. Были бы выполнены подстановки. К сожалению, препроцессор не в состоянии различать, какие фигурные скобки должны быть заменены круглыми, а какие нет. Таким образом, программа
#define ( {
#define ) } int main(void)
(
printf("Привет, Великан!\n");
)
превратилась бы в
int maintvoid}
{
printf{"Привет, Великан!\n"};
}
Ответы на вопросы для самоконтроля из главы 5
1. а. 30.
б. 21 (а не 3). Выражение (12 + 6)/(2*3) в результате дало бы 3.
в. х = 1, у = 1 (целочисленное деление).
г. х = 3 (целочисленное деление) и у = 9.
2. а. 6 (сводится к 3 + 3.3).
б. 52.
в. 0 (сводится к О * 22.0).
г. 13 (сводится к 66.0 / 5, или 13.2, а затем присваивается переменной типа int).
3. а. 37.5 (сводится к 7.5 * 5.0)
б. 1.5 (сводится к 30.0 / 20.0)
в. 35 (сводится к 7 * 5)
г. 37 (сводится к 150 / 4)
д. 37.5 (сводится к 7.5 * 5)
е. 35.0 (сводится к 7 * 5.0)
4. Строка 0: необходимо включить .
Строка 3: должна заканчиваться точкой с запятой, а не запятой.
Ответы на вопросы для самоконтроля 799
Строка 6: оператор while образует бесконечный цикл, поскольку значение i остается равным 1 и всегда меньше 30. Вероятно, намерения были записать
while(i++ < 30).
Строки 6-8: судя по отступам, строки 7 и 8 должны были образовывать блок, однако отсутствие фигурных скобок означает, что цикл while включает в себя только строку 7. Необходимо добавить фигурные скобки.
Строка 7: поскольку и 1, и i — целые числа, результат деления будет равен 1 при i = 1 и 0 при всех более высоких значениях. Использование выражения n = 1. 0/1; привело бы к преобразованию i в тип с плавающей запятой перед выполнением операции деления, и общий результат оказался бы ненулевым. Строка 8: в управляющем операторе опущен символ новой строки (\n). Это приводит к тому, что числа выводятся в одной строке, когда такое возможно.
Строка 10: должна содержать return 0;
Вот скорректированная версия:

5. Основная проблема кроется во взаимодействии оператора проверки условия (является ли значение sec больше 0) и оператором scanf(), который получает значение переменной sec. В частности, при первом выполнении проверки условия программа не имеет ни малейшей возможности получить значение для sec, и сравнение будет выполняться со случайным значением, которое оказалось в используемой ячейке памяти; оно может быть больше 0, а может и не быть. Одно (хотя и не очень изящное) решение предусматривает инициализацию sec, скажем, 1, чтобы проверка условия проходила в первый раз. Это вскрывает вторую проблему. Когда вы, в конце концов, вводите 0, чтобы остановить программу, значение sec проверяется только после завершения цикла, и происходит вывод результатов для 0 секунд. В действительности в программе требуется оператор scanf(), который бы выполнялся перед проверкой условия оператора while. Этого можно добиться, изменив центральную часть программы следующим образом:

800 Приложение А
Сначала выполняется оператор scanf(), находящийся снаружи цикла, а затем оператор scanf() в конце цикла (следовательно, прямо перед началом новой итерации цикла). Это распространенный метод решения проблем подобного рода, и именно поэтому он был применен в листинге 5.9.
6. Вывод программы имеет следующий вид:
%s! С is cool!
! С is cool!
11
11
12
11
Давайте посмотрим, что происходит. Первый оператор printf() эквивалентен следующему оператору:
printf("%s! С is cool!\n","%s ! C is cool!\n");
Второй оператор вывода сначала увеличивает значение num до 11, а затем выводит значение. Третий оператор вывода выводит значение num, которое равно 11, после чего увеличивает его до 12. Четвертый оператор выводит текущее значение n, которое по-прежнему равно 12, а затем уменьшает n до 11. Заключительный оператор вывода выводит текущее значение переменной num, которое равно 11.
Читать дальше