пятница, 2 января 2015 г.

Массивы и циклы на примере камеры хранения



Недавно пришлось объяснять товарищу основы программирования на языке Java. Как-то тяжело зашла тема про массивы, циклы и итерации. Поэтому я придумал довольно абстрактный пример который помогает понять вышеописанные темы.

Постановка задачи: Допустим мы оперируем некой камерой хранения, из 10 ячеек. Задача состоит в том что бы контролировать состояние каждой ячейки. Освобождать ячейку или же занимать ее. Выводить отчет о занятых и свободных ячейках.

Итак давайте проанализируем, задачу, нам нужна структура данных для хранения 10 значений. Использовать отдельную переменную для каждой ячейки, крайне неудобно так как перебирать все десять переменных для поиска определенной ячейки, не вариант. Для таких целей в программировании существует массив.

Массив (или массив данных) – это набор однотипных элементов, к которым можно обратиться по их порядковому номеру (индексу). Простыми словами, массив содержит в себе какое-то количество переменных одного типа, и у каждой переменной есть свой порядковый номер (индекс) по которому мы можем достучаться к каждой переменной. 
Итак какой же тип данных будет хранить наш массив? Мы должны хранить информацию о том занята ячейка или нет. Для этого идеально походит boolean. Который может содержать в себе либо true либо false (истинна либо ложь). Если ячейка занята - это true, если нет false.

boolean [] checkingRoom = new boolean[10];

Если мы выведем на экран значение всех ячеек, то увидим что все они будут равны false . Это значение по умолчанию для типа boolean. Например если мы просто создадим переменную этого типа, и не укажем явно значение, то у переменной также будет значение false. Для всех примитивов (простых типов данных) в Java есть значения по умолчанию. Более подробно о примитивах и значениях по умолчанию здесь. Как же нам вывести значения всех элементов на экран ? Проблема в том что у нас не одна переменная, а массив содержащий в себе сразу 10 переменных. И нам надо пройтись по всем этим переменным и вывести их значения. Для этого и существует цикл, что бы можно было выполнить какую-то операцию, какое-то количество раз. В нашем случае нужно выводить элементы массива, наши ячеечки, пока они не закончатся. Самая распространенная версия цикла - цикл for. Для нашего примера это выглядит так:
for (int cellNum = 0; cellNum < checkingRoom.length; cellNum++) {
   System.out.println("cell value: " + checkingRoom[cellNum]);
 } 
Давайте рассмотрим по частям что идет после ключевого слова for:
  • int cellNum = 0 - создаем новую переменную, которая будет хранить порядковый номер элемента в массиве. В нашем случае номера будут идти от 0 до 9. Стоит запомнить что в Java принято что нумерация элементов массива начинается с нуля.
  • cellNum < checkingRoom.length - наш цикл не может повторяться вечно, мы должны указать некоторое условие, пока это условие истинно тело цикла (код в {}) будет выполняться. И после каждого выполнения  кода в скобках, условие в цикле for будет снова проверено. И в случае если результат будет отрицательный цикл прекратит свою работу. Переменная length которая доступна для любого массива содержит кол-во элементов в нем. В нашем случае мы закончим цикл когда порядковый номер элемента массива станет больше чем кол-во элементов в массиве то есть мы отобразили значение последней ячейки нашего хранилища, и можем спокойно выйти из цикла.
  • cellNum++ - собственно шаг, c которым мы будем двигаться по массиву. Порядковый номер элемента будет увеличен на единицу после каждого выполнения тела цикла {}. В нашем случае мы пройдем все элементы массива (все ячеечки) по порядку.
  • { } - тело цикла, то что будет выполняться пока условие цикла истинно.  
Также стоит помнить что, первых два компонента цикла for должны быть разделены ;. условия цикла должны быть в круглых скобках (). Этого требует синтаксис цикла for. Есть более простая форма цикла for она называется for each. В ней мы просто указываем переменную по типу массива и через точку с запятой сам массив. Переменная будет содержать по очереди каждый элемент массива. Выглядит это так:
for (boolean cell : checkingRoom) {
  System.out.println("cell value: " + cell);
}
Итак запустив этот код вы увидите что все ячейки в хранилище пустые. И содержат значение false. К нам пришел первый клиент и хочет положить свои вещи в первую свободную ячейку. Нам не составит труда, пройтись по всем ячейкам нашей камеры хранения. И с помощью оператора if найти ячейку со значением false и изменить ее значение на true. Но как нам выйти из цикла после того как мы изменим значение ячейки ?. Для это есть оператор break. Который немедленно выбросит нас из цикла.
for (int cellNum = 0; cellNum < checkingRoom.length; cellNum++) {
    if (checkingRoom[cellNum] == false) {
        checkingRoom[cellNum] = true;
        System.out.println("cell with number " + cellNum +" has been filled. Now Cell value is: "+checkingRoom[cellNum]);
        break;
    }
 }
Запустив нашу программу, мы увидим что первая свободная ячейка под номером ноль была заполнена, после чего мы благополучно вышли из цикла и завершили выполнение:

Output
>>> cell with number 0 has been filled. Now Cell value is: true
   
Вы  можете модифицировать этот код, расширив возможности камеры хранения.
Допустим добавить возможность бронировать ячейку не занимая ее. Ниже полный листинг приложения камера хранения:
public class Main {
    public static void main(String[] args) {
        boolean[] checkingRoom = new boolean[10];
        System.out.println("checkingRoom report version 1: ");
        for (int cellNum = 0; cellNum < checkingRoom.length; cellNum++) {
            System.out.println("cell value: " + checkingRoom[cellNum]);
        }
        System.out.println("checkingRoom report version 2: ");
        for (boolean cell : checkingRoom) {
            System.out.println("cell value: " + cell);
        }

        for (int cellNum = 0; cellNum < checkingRoom.length; cellNum++) {
            if (checkingRoom[cellNum] == false) {
                checkingRoom[cellNum] = true;
                System.out.println("Cell with number " + cellNum + " has been filled. Now Cell value is: " + checkingRoom[cellNum]);
                break;
            }
        }
    }
} 
Думаю статья будет интересна тем, кто делает первые шаги в программирование. Она дает поверхностное представление о массивах данных, цикле for и операторе break который помогает выйти из цикла.     

Комментариев нет:

Отправить комментарий