Простейшая программа на C

В качестве примера программы на языке C рассмотрим программу, которая вычисляет максимальное значение последовательности отличных от нуля целых чисел. Пользователь должен ввести несколько чисел. Если пользователь вводит ноль, то это означает, что последовательность закончилась. Последовательность должна содержать по крайней мере один элемент. После получения нуля программа распечатывает ответ.

#include <stdio.h>

int main() {
    int current = 0; /* текущий элемент последовательности */
    int maximum = 0; /* максимальное значение на данный момент */

    printf("Введите последовательность чисел и нажмите <Enter>\n");
    printf("0 - символ конца последовательности\n");

    /* Считываем первый элемент последовательности */
    if(scanf("%d", &current) != 1 || current == 0) {
        printf("Не удалось прочитать первый элемент\n");
        return -1;
    }
    maximum = current;

    /* Обрабатываем все остальные элементы */
    while(scanf("%d", &current) == 1 && current != 0) {
        if(current > maximum) {
            maximum = current;
        }
    }

    /* Печатаем ответ */
    printf("Максимальное значение = %d\n", maximum);
    return 0;
}

Если мы выполним эту программу (о том, как нужно компилировать и выполнять программы будет написано ниже), то увидим что-то такое.

Введите последовательность чисел и нажмите <Enter>
0 - символ конца последовательности
1 2 3 -1 2 0
Максимальное значение = 3
Первая, вторая и четвертая строчки – это то, что было напечатано программной. Третья строчка – то, что мы ввели. Наша последовательность содержала пять элементов и символ конца последовательности.

Теперь постараемся понять, как эта программа работает. Пусть нам на вход поступает последовательность a0, a1, ... an. Во-первых, заметим, что для вычисления максимального элемента последовательности нет необходимости заранее знать все ее элементы. Достаточно иметь значение текущего элемента и текущего максимума, то есть максимума из всех предыдущих элементов. Если максимальным значение первых k элементов a1, a2, ..., ak является max, то максимальным значением a1, a2, ..., ak, ak+1 будет максимум двух чисел: max и ak+1. Во-вторых, максимальным значением последовательности из одного элемента является этот элемент.

Рассмотрим код программы. Первую строчку (#include ...) пока оставим без пояснений. Если программа должна что-то печатать или считывать, то эта строчка должна быть. Строчка int main() { объявляет "основную" функцию нашей программы. Каждая программа на языке C должна иметь ровно одну функцию main. Выполнение программы начинается с вызова этой функции.

Как уже было сказано, для вычисления максимума нам понадобится хранить два значения. Для этого вводим две переменные: current и maximum, значениями которых будут текущий элемент последовательности и текущий максимум, соответственно. Для определенности мы присваиваем этим переменным значение 0. Далее идут операторы printf(..., которые печатают поясняющий комментарий для пользователя.

Содержательная часть программы состоит из трех блоков: считывание первого элемента последовательности, обработка всех остальных элементов и печать результата. Первый элемент последовательности мы считываем отдельно, так как его значение обрабатывается особым образом &ndash оно используется для присвоения корректного начального значения переменной maximum. Значение 0, которое мы ранее присвоили этой переменной, не может считаться нормальным кандидатом для начального значения максимума. Если последовательность будет содержать только отрицательные числа, то наша программа, как это будет видно позднее, будет выводить некорректный ответ.

Считывание данных заслуживает отдельного обсуждения. Сейчас же отметим два приема, которые используются в данной программе. Во-первых, для считывания входных данных используются функции типа scanf. Это довольно гибкое средство считывания данных. Простая форма вызова этой функции

int int_value;
double real_value;
int rc; /* return code = код возврата */
rc = scanf("%d", &int_value); /* Прочитать целое число (формат "%d") и записать в int_value */
rc = scanf("%lf", &real_value); /* Прочитать действительное число (формат "%lf") и записать в real_value */
Функция scanf проверяет корректность входных данных и возвращает количество удачно прочитанных значений. Если мы просим прочитать одно число, как в этих примерах, и пользователь вводит корректные данные, то функция возвращает значение 1 (переменная rc получит значение 1). Если же пользователь вводит буквы, или же при считывании произошли какие-либо ошибки, то функция вернет значение отличное от 1. В случае нашей программы это означает, что первый элемент был введен, если результат scanf не равен 1 или scanf вернул 1 и переменная current получила отличное от нуля значение. Оба условия проверяются в одном условном операторе
if(scanf("%d", &current) != 1 || current == 0) {
Язык C гарантирует, что условия проверяются слева направо до тех пор, пока это необходимо. Если scanf вернул не 1, то сравнение scanf(...) != 1 выполнено и проверять условие current == 0 уже нет смысла: значение всего логического выражения является истинным. Если же scanf вернул 1, а это значит, что переменная current получила корректное значение, то необходимо проверить второе условие current == 0.
Каким образом можно считывать данные из файла, а не с клавиатуры, как в рассматриваемом случае, объясняется здесь.

Обработка всех остальных элементов. Перед началом цикла while мы прочитали один элемент последовательности и maximum содержит максимальное значение из всех ранее прочитанных элементов. Цикл выполняется до тех пор, пока удается прочитать очередной элемент последовательности и этот элемент отличен от нуля (используется аналогичный прием с одновременной проверкой двух условий). На каждой итерации цикла мы, в случае необходимости, обновляем текущий максимум. Заметим, что выполняется инвариант цикла: перед началом итерации цикла переменная maximum содержит максимальное значение из всех предыдущих элементов последовательности.

Печать результата. Для печати используются функции типа printf, которые являются гибким средством вывода данных. Простая форма

/* продолжение примера про scanf */
printf("Вы ввели: int_value = %d, real_value = %f\n", int_value, real_value);
Первым аргументом при вызове функции printf является строка формата. Это собственно та строчка, которая будет непечатана. Строка формата может содержать несколько шаблонных позиций (placeholder), которые отмечаются символом % (процент) за которым следует символ, обозначающий тип выводимого значения. Если в строке формата встречается %d, то в этом месте будет напечатано целочисленное значение. Последовательность %f печатает действительное число. В вызове printf После строки формата должно быть указано нужное количество значений (по числу символов %).

Подготовка и запуск программы

Для запуска программы нужно сделать следующее:
  1. в текстовом редакторе создать файл, который будет содержать исходный текст программы;
  2. откомпилировать программу (преобразовать из текста на языке C в машинный код);
  3. запустить выполняемый файл.
В среде Linux этим действия могут соответствовать такие команды:
  1. vim my_first_program.c
  2. gcc -o prog my_first_program.c
  3. ./prog
Более подробно об основных командах можно прочитать здесь и здесь (PDF).