Язык Си в примерах/Максимум: различия между версиями

Содержимое удалено Содержимое добавлено
Уточнения и дополнения; →‎Решение: разбит на подразделы.
Уточнения; упомянута ferror (); →‎Условия корректности ввода: выделен раздел.
Строка 1:
{{{{Book template}}/Содержание}}
 
; {{Якорь2 |Дано}}: непустая последовательность разделенных ''пробельными символами'' [[w:Целое число |целых чисел]] (в «текстовом» десятичном представлении) на [[w:Стандартные потоки#Стандартный ввод |стандартном вводе]] программы. Последовательность конечна, но ее длина заранее неизвестна.
; Найти: предельные значения последовательности (минимум, максимум) и основные статистики (среднее, среднеквадратичное отклонение.)
; Указания: воспользуйтесь циклом «пока» (<code >while</code>) для чтения последовательности и функциями <code >pow</code>, <code >sqrt</code> для вычисления среднеквадратичного отклонения.
Строка 36:
}
assert (r == EOF);
assert (! ferror (stdin));
 
printf (("Range: [%d, %d]\n"
Строка 56 ⟶ 57 :
{{Якорь |pow}}
{{Якорь |sqrt}}
''[[w:Среднеквадратическое отклонение |Среднеквадратичное отклонение'']] вычислено как корень из [[w:Дисперсия |дисперсии]], которая, в свою очередь, вычислена по правилу «среднее квадратов минус квадрат среднего» — <source lang="c" enclose="none" >sum_sq / n - pow (sum / n, 2)</source> — тривиально следующему из ее определения. Значение используемой нами здесь функции <code >pow</code> — первый аргумент, возведенный в степень, заданную вторым аргументом; значение <code >sqrt</code> — квадратный корень единственного аргумента. Эти функции является частью ''стандартной библиотеки'' и ''объявлены'' в ''заголовке'' <code >math.h</code>.<ref name="pow" /><ref name="sqrt" />
 
=== Чтение и предобработканакопление ===
 
Чтение последовательности выполнено в два этапа. Вначале, считанный первым элемент используется для инициализации ''предельных значений'' (<var >min</var>, <var >max</var>) и ''сумм'' (<var >sum</var>, <var >sum_sq</var>).
 
Затем, каждый очередной элемент (все так же считываемый функцией <code >scanf</code><ref name="fscanf" />) подвергается следующей обработке:
# сравнивается с текущими значениями переменных <var >min</var>, <var >max</var>; переменныеесли обновляютсяэлемент лежит вне этих пределов — один из них изменяется соответственно;
# значение ''суммы'' (<var >sum</var>) увеличивается на величину текущего элемента; значение ''суммы квадратов'' (<var >sum_sq</var>) — на величину квадрата;
# кроме того, успешное чтение элемента приводит к ''инкременту'' (увеличению на 1) хранящей количество считанных элементов переменной <var >n</var>.
Строка 69 ⟶ 70 :
Каждый вызов <source lang="c" enclose="none" >scanf ("%d", &cur)</source> считывает целое число в десятичной записи (<code >%d</code>) в переменную <code >cur</code>. <em >Предшествующие</em> числу ''пробельные символы'' (пробел, табуляция, [[w:Перевод строки |перевод строки]]) при этом игнорируются, а значит могут быть использованы — в любых сочетаниях — для ''разделения'' элементов последовательности.
 
=== Условия корректности ввода ===
После завершения чтения последовательности, мы ''требуем'' (используя [[../Учимся складывать#assert |уже известную]] нам макроподстановку <code >assert</code><ref name="assert" />) равенства последнего возвращенного функцией <code >scanf</code> значения константе (макроопределению) <code >EOF</code> — что соответствует достижению ''конца файла'' для нашего входного потока (''стандартного ввода''.) Иными словами, мы требует, чтобы чтение последовательности <em >не было прервано</em> наличием во входном потоке каких-либо «нечисловых» данных.
 
После завершения чтения последовательности, мы ''требуем'' (используя [[../Учимся складывать#assert |уже известную]] нам макроподстановку <code >assert</code><ref name="assert" />) равенстваистинности последнегоследующих возвращенногодвух функциейусловий, <codeсмысл >scanf</code>которых значениясводится константек (макроопределению) <code >EOF</code> —тому, что соответствует достижению ''конца файла'' для нашего входного потока (''стандартного ввода''.) Иными словами, мы требует, чтобы чтение последовательности <em >не было прервано</em> наличиемни появлением во входном потоке каких-либо «нечисловых» данных, ни ошибкой ввода-вывода.
# Мы проверяем равенство последнего возвращенного функцией <code >scanf</code> значения константе (макроопределению) <code >EOF</code> (''конец файла''; англ. {{lang |en|end of file}}), что соответствует или ''исчерпанию'' нашего входного потока (''стандартного ввода''), или возникновению ошибки ввода-вывода. Другое возможное на данном этапе значение — ноль — укажет на наличие во входном потоке данных, которые не были опознаны функцией <code >scanf</code> как [[#Дано |требуемое условием]] целое число в десятичной записи (<code >%d</code>).
# Если предыдущее требование выполняется (иными словами — останов произошел <em >не</em> из-за «нечислового» ввода), мы также явно требуем ''ложности'' значения функции ''признака ошибки'' <code >ferror</code> для стандартного ввода (<code >stdin</code>.)<ref name="ferror" />
 
=== Цикл «пока» ===
Строка 101 ⟶ 106 :
<!-- Пожалуйста поддерживайте алфавитный порядок для name. Спасибо. -->
<ref name="assert" >{{Cite web | title = 7.2.1.1 The assert macro | url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=204 | work = WG14 N1570 Committee Draft | publisher = ISO/IEC | datepublished = 2011-04-12 | lang = en | accessdate = 2012-11-19}}</ref>
<ref name="ferror" >{{Cite web | title = 7.21.10.3 The ferror function | url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=357 | work = WG14 N1570 Committee Draft | publisher = ISO/IEC | datepublished = 2011-04-12 | lang = en | accessdate = 2012-11-19}}</ref>
<ref name="fprintf" >{{Cite web | title = 7.21.6.1 The fprintf function | url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=327 | work = WG14 N1570 Committee Draft | publisher = ISO/IEC | datepublished = 2011-04-12 | lang = en | accessdate = 2012-11-19}}</ref>
<ref name="fscanf" >{{Cite web | title = 7.21.6.2 The fscanf function | url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=335 | work = WG14 N1570 Committee Draft | publisher = ISO/IEC | datepublished = 2011-04-12 | lang = en | accessdate = 2012-11-19}}</ref>