Программирование с нуля

859
Программирование с нуля
Программирование с нуля

Эта статья описывает основные конструкции программирования и предназначена для тех, кто хочет разобраться в них. Однако, в силу их большого количества, не все нюансы будут рассмотрены, чтобы не сделать статью слишком монотонной и непонятной.

Мы будем использовать синтаксис, подобный языку Си, но не будем углубляться в детали, связанные с указателями и другими низкоуровневыми особенностями языка. Вместо этого, мы перейдем к синтаксису более высокоуровневых языков программирования, таких как Java, который поможет нам автоматизировать рутинные задачи.

Двоичная система счисления

Двоичная система счисления использует всего два знака — 0 и 1. Например, 00000001 представляет число 1, 00000010 — число 2, а 00000100 — число 4. Если увеличить значение на два раза, достаточно сдвинуть единицу влево. Чтобы получить число 3, нужно использовать 00000011. Таким образом, можно представить любое необходимое число. В данном примере использовалось восьмиразрядное двоичное число, то есть число, состоящее из восьми знаков. Чем больше разрядов, тем большее значение можно закодировать. Например, восьмиразрядное число может хранить значение до 255 (если учитывать 0, то 256), что является максимальным значением для этой разрядности. Увеличение количества разрядов вдвое увеличивает емкость числа вдвое. Например, девятиразрядное число может хранить значение до 512. Однако, в программировании обычно используются числа с разрядностью, кратной степени двойки — 1, 2, 4, 8, 16, 32 и т.д.

Шестнадцатеричная система счисления

Шестнадцатеричная система счисления очень похожа на двоичную, но вместо 0 и 1 в ней используются цифры от 0 до 15: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. Здесь А соответствует числу 10, В — 11, С — 12, D — 13, E — 14, а F — 15.

Знак минус в программировании

В двоичной системе счисления знак минус обычно обозначается единицей в самом старшем разряде числа, если число может быть отрицательным (да, в программировании бывают типы данных со знаком). Например, число -1 записывается как 10000000. Обратите внимание, что это не число -0, так как не существует отрицательного нуля, и отрицательные числа смещаются влево на один разряд. Однако, различные языки программирования могут иметь разные способы представления отрицательных чисел, но для понимания основных принципов достаточно знать данное объяснение.

Буквы и знаки

В программировании, помимо чисел, символы, знаки и эмодзи также представлены в виде чисел. Например, символ ‘A’ может быть представлен числом 65 в ASCII-кодировке, либо другим числом, в зависимости от выбранной кодировки. Существует множество различных кодировок символов, так что выбор конкретной кодировки зависит от конкретной задачи и контекста.

Типы данных

В программировании существуют различные типы данных. Числовые типы данных, например int (от англ. integer), используются для хранения целых чисел, как 233, который был рассмотрен ранее. Также есть тип float, который используется для хранения чисел с плавающей запятой, например 198,76. Для хранения символов используется тип char, а для строк — тип String. Тип bool имеет два возможных значения: true (истина) и false (ложь). Различные языки программирования могут использовать разные подходы для реализации этого типа, но в большинстве случаев ноль интерпретируется как ложь, а любое другое значение как истина. О существовании нестандартных типов данных, таких как числа с фиксированной запятой, здесь не будет упоминаться.

Применение

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

int value;

Объявление примитивного типа является стандартным шагом перед использованием чисел в программировании.

Для объявления переменной нужно указать её тип, а затем имя переменной. После этого необходимо закончить выражение точкой с запятой. Теперь мы можем использовать переменную по её имени.

value = 112;

Здесь мы присваиваем переменной определенное значение. В отличие от математики, в программировании знак «=» означает взять значение справа и присвоить его переменной слева. «=» является оператором присваивания.

Можно объединить объявление переменной и присвоение значения ей в одной строке. Таким образом, переменная будет сразу инициализирована.

int value0 = 113;
char a = ‘a’;
String line = “line”;

В языках программирования буквы обычно выделяются одинарными кавычками, а строки — двойными кавычками. Числа типа int не нуждаются в выделении кавычками или другими символами, так как они сами по себе являются примитивным типом данных.

float b = 3.14f;

В языках программирования существует тип данных для чисел с плавающей запятой одинарной точности, который обычно обозначается как float. Чтобы явно указать, что число должно быть именно этого типа, в конце числа добавляется буква f.

double c = 1.2;

Перед числами с плавающей запятой двойной точности ничего не добавляется.

Операторы

В программировании существует множество операторов, позволяющих выполнять арифметические и другие операции с переменными. Среди них наиболее распространены операторы сложения (+), вычитания (-), умножения (*), деления (/) и остатка от деления (%). Оператор ; (точка с запятой) используется для завершения выражений.

После записи выражения, например сложения, получается значение.

int a = 127;
int b = -12;
a + b;

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

Повторим еще раз: оператор присваивания берет значение с правой стороны и присваивает его переменной на левой стороне. Он обозначается знаком «=». Важно отметить, что оператор присваивания не имеет ничего общего с математическим знаком равенства.

int c = 12;
int d = 14;
int e = c + d;

В языке программирования существуют логические операторы, такие как < (меньше), > (больше), <= (меньше либо равно), == (равно), && (логическое И), || (логическое ИЛИ) и другие.

Эти операторы позволяют сравнивать значения или выражения, указанные слева и справа, и выдают логическое значение типа bool — true или false, которое также может быть присвоено.

int f = 1;
int g = 4;
bool isTrue = g > f;

Логический оператор && (И) сравнивает два значения типа bool. Если значение слева и значение справа оба равны true, то оператор && вернет true. В противном случае, он вернет false.

Оператор || (ИЛИ) возвращает значение true, если хотя бы одно из значений истинно (true). Если оба значения ложны (false), то оператор || вернет значение false.

Комментарии

Комментарии в программировании используются, чтобы не забыть описать, что было реализовано в коде или чтобы информировать пользователей о том, как использовать программу. Комментарии можно рассматривать как заметки в коде.

Однострочные комментарии начинаются с символов // и продолжаются до конца строки.

//Комментарий.
int maxCount;

Вторая строка уже не комментарий.

Кроме однострочных комментариев, в языке программирования существуют также многострочные комментарии и другие типы комментариев, которые не будут рассмотрены в данном контексте.

Оператор ветвления if

if(a < 154) {
a = a + 1;
}

Если значение переменной «a» меньше 154, то условие является истинным и выполнится код внутри фигурных скобок, который называется блоком кода. После этого программа продолжит свое выполнение.

Блок кода предназначен для того, чтобы явно указать программе, какой код должен быть выполнен внутри определенного оператора и только в том случае, если условие оператора выполняется.

Оператор ветвления if можно расширить.

if(isTrue && isFalse){
    b = b – 1;
    } else {
    b = b + 1
}

Если условие оператора является истинным, то выполнится первый блок кода, а в случае, если условие не выполняется, то будет выполнен второй блок кода, который находится после оператора else.

Оператор ветвления switch

switch(value){
    case 0:
        a = a + 1;
        break;
    case 1:
    a = a + b;
    break;
    case 6:
    b = b – a;
    b = b – 1;
    break;
    default:
    b = b + 1;
    break;
}

Данный оператор выполняет сравнение значения, указанного в круглых скобках, со значениями, указанными после оператора case. В случае, если значения совпадают, выполняется соответствующее выражение или выражения, после чего выполнение продолжается до оператора break. После этого программа выходит из цикла и продолжает свое выполнение дальше.

Если ни одно значение не совпадает с заданным в круглых скобках, то будет выполнено выражение, указанное после оператора default. Однако оператор default необязательный и может быть опущен.

switch(value){
    case 0:
    a = a + 1;
        break;
    case 1:
    a = a + b;
    break;
}

Цикл for

Циклы предназначены для многократного выполнения блока кода, пока определенное условие не прекратит их выполнение.

for(int i = 32; i >=0; i = i – 1){
    a = b + c + d;
}

Цикл while

while(i > 3){
    i = i – 2;
}

While цикл выполняется по крайней мере один раз, так как проверка условия происходит после выполнения блока кода цикла. Если условие истинно, то цикл выполняется снова и снова, пока условие станет ложным.

do{
    i = i – 2;
} while(false);

Область видимости

int a = 4;
{ 
    int b = 0;
    b = a + b;
}

Область видимости переменных определяется фигурными скобками. Переменные, объявленные внутри фигурных скобок, не видны во внешней области, но внешняя область видна внутри фигурных скобок. Таким образом, переменные, объявленные во внешней области, могут использоваться внутри фигурных скобок, но переменные, объявленные внутри фигурных скобок, не могут быть использованы во внешней области.

Ключевые слова

Ключевые слова — это зарезервированные слова в языках программирования, которые имеют специальное значение и используются для определенных целей, например, для создания циклов, условных операторов, объявления функций и т.д. Они не могут использоваться для именования переменных, методов или других элементов программы. Ключевые слова различаются в каждом языке программирования, и, например, слово while является ключевым словом во многих языках для создания циклов.

Массивы

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

int[] items = new int[7];

В языках программирования, для объявления массива, сначала указывается тип элементов, затем ставятся квадратные скобки, указывающие на объявление массива, после чего указывается имя массива. Далее, после знака присвоения, указывается выражение инициализации, которое создаёт массив. Одним из способов создания массива является использование оператора new, который выделяет память для массива и возвращает ссылку на созданный объект.

Обращение к элементам массива начинается с индекса 0, так что если мы создали массив с семью элементами, то последний элемент будет иметь индекс 6. Важно помнить об этом при работе с массивами.

Обращение к элементу массива и присвоение его переменной выглядит так

int a = items[0];

Вход в программу

Мы уже рассмотрели основные моменты, чтобы иметь хоть какое-то представление о языке программирования, поэтому давайте перейдем к написанию простой программы.

В языке программирования началом программы является метод main. Как и любой другой метод, он представляет собой блок кода, но с уникальным именем. Метод main может быть вызван из другой части программы по имени, однако он не может быть вызван сам по себе, поскольку он является входной точкой программы. Метод main срабатывает только при запуске программы.

int addAndMultiplyByTwo(int a, int b){
    return (a + b) * 2;
}

Вот простейший метод, который мы сейчас рассмотрим. В круглых скобках указываются входные параметры, которые можно представить как переменные, уже объявленные в блоке кода, но которым мы можем присвоить значения извне. Внутри фигурных скобок первым оператором, который мы видим, может быть return. Он берет значение справа от себя, которое получается из выражения, и передает его в вызывающий код. Тип возвращаемого значения должен быть таким же, как указанный перед именем метода, например int.

int g = 6;
int z = addAndMultiplyByTwo(7, g);
class HelloWorld {
    public static void main(String args []) {
        System.out.println("Hello World");
    }
}

Данный пример начинается с создания класса HelloWorld, который можно рассматривать как файл с кодом программы. Затем объявляется метод main. Из названия метода можно понять, что это основной метод программы, который будет запущен при ее выполнении. Ключевое слово public означает, что метод является открытым и доступен для вызова не только внутри класса, но и из других частей программы. Ключевое слово static указывает на то, что метод принадлежит классу, а не объекту этого класса. Также мы можем увидеть ключевое слово void, которое говорит о том, что метод не возвращает значение. В круглых скобках указывается аргумент args[], который представляет собой массив строк и служит для передачи параметров методу. В данном случае массив пустой, так как мы не используем никаких параметров для запуска программы.

В этом примере мы видим создание класса HelloWorld, который содержит метод main. Ключевое слово public говорит о том, что метод доступен из любого места программы. Ключевое слово static указывает, что метод не требует создания экземпляра класса для вызова. Тип возвращаемого значения метода main — void, что означает, что метод не возвращает никакого значения. В круглых скобках после имени метода указываются параметры, передаваемые в метод. В данном случае параметр args[] является массивом строк.

Затем мы видим вызов метода println, который выводит строку «Hello World» в консоль и переводит курсор на новую строку. Перечисление через точку System.out указывает на объект класса PrintStream, который выводит информацию в консоль. Все перечисления через точку в данном случае просто указывают путь к методу println, чтобы компилятор знал, где искать его. После выполнения метода println программа завершается.

Компиляция и выполнение

Для того чтобы запустить простую программу на Java, необходимо выполнить несколько шагов. Во-первых, необходимо скачать и установить JDK (Java Development Kit). Затем нужно добавить путь к папке «bin» JDK в переменные среды операционной системы (в переменную Path). Это необходимо, чтобы операционная система могла найти программы JDK для компиляции и запуска.

После этого можно написать текст программы на Java и сохранить его в текстовом файле с именем, совпадающим с именем класса (в данном случае «HelloWorld.java»). Далее необходимо открыть командную строку, перейти в папку с файлом программы и выполнить команду «javac HelloWorld.java», чтобы скомпилировать программу и создать файл «HelloWorld.class».

После успешной компиляции программы можно запустить её командой «java HelloWorld». При этом на экране появится сообщение «Hello World».

Импорт

Для использования классов и методов из стандартной библиотеки в Java используется ключевое слово import.

import java.util.Random;

Импортирование классов из стандартной библиотеки осуществляется с помощью ключевого слова import, за которым следует название пакета и класса. Например, для использования класса Random из пакета java.util необходимо написать import java.util.Random;.

Пакет java.util содержит множество полезных классов и интерфейсов, в том числе класс Random, который используется для генерации случайных чисел. В названии пакета используется принятая в Java структура пакетов, где название пакета представляет собой доменное имя организации, обратно записанное и дополненное названием пакета. Например, пакет java.util содержит классы и интерфейсы, связанные с утилитами и инструментами общего назначения.

Важно отметить, что при импортировании класса необходимо указывать его полное название, включая название пакета. Если класс находится в другом пакете, его название должно быть дополнено пакетом, например, import com.example.MyClass;.

Классы и объекты. Статические и динамические реализации

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

class MyClass {
    public static void main(String [] args){
    
        AnotherClass object0 = new AnotherClass();
    
        System.out.println(object0.a);
        System.out.println(object0.addition(8, 10));
    }
}
public class AnotherClass{
    int a  = 9;
    
    int addition(int b, int c){
        return b + c;
    }
}

Давайте рассмотрим эти классы подробнее. Начнём с класса AnotherClass. Перед его именем мы видим ключевое слово public, которое указывает, что класс является публичным и может быть использован другими классами. В этом классе мы создаем переменную a со значением 9 и метод addition. Класс AnotherClass можно рассматривать как новый тип данных.

В классе MyClass мы создаем объект object0 типа AnotherClass. Это похоже на создание обычной переменной, и для этого мы используем ключевое слово new, как при создании массива. Оператор new сообщает языку программирования, что нужно создать копию этого класса в оперативной памяти. Мы можем создавать множество копий и забить ими всю память. Далее мы передаём переменную a этого объекта в метод println. Мы вызываем динамический метод addition в качестве параметра метода println. Метод addition возвращает результат, а метод println выводит его.

Динамический метод отличается от статического тем, что его можно вызвать только из объекта, загруженного в память. Для начала нужно создать объект. Статический метод можно вызывать напрямую из класса, используя имя класса, за которым следует точка, а затем метод. Однако у статических методов есть ограничения. Внутри их тела невозможно обращаться к динамическим переменным объекта класса, в котором они находятся. Поскольку статический метод не загружается в оперативную память, в нём нельзя использовать переменные объекта, загруженные в неё. Чтобы создать статический метод, перед его именем нужно написать ключевое слово static.

Конструкторы

class MyClass2 {
    public static void main(String [] args){
    
        AnotherClass2 object0 = new AnotherClass2();
        AnotherClass2 object1 = new AnotherClass2(6);
    
        System.out.println(object0.a);
        System.out.println(object0.a);
    }
}
public class AnotherClass2{
    public AnotherClass2(){
        a = 7;
    }

    public AnotherClass2(int x){
        a = x;
    }

    int a;
}

В данных классах большая часть кода совпадает с предыдущими, за исключением того, что мы создаём два объекта класса AnotherClass2 — object0 и object1, и делаем это по-разному.

Рассмотрим класс AnotherClass2. Здесь появляется новый механизм — конструктор. Класс может иметь несколько конструкторов, начинающихся с ключевого слова public и за которыми следует имя класса. В скобках указываются параметры, а в теле конструктора описывается инициализация объекта класса. Конструкторы похожи на методы.

Перейдём к разбору конструкторов в классе MyClass2. При создании объектов класса AnotherClass2 в этом классе мы можем указать параметры в круглых скобках. Язык программирования выберет подходящий конструктор на основе переданных параметров и проинициализирует объект соответствующим образом. Таким образом, мы можем создавать объекты, отвечающие нашим нуждам.

Подводя итог

Мы рассмотрели основы программирования на Java, но это только вершина айсберга. Одной из важных тем, которую мы не касались, является наследование. Оно позволяет создавать новые классы, которые наследуют свойства и методы родительского класса, но при этом могут быть расширены или изменены.

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

Если вы решили заняться программированием, то вам неизбежно придется продолжать обучение и изучение новых технологий и методик. Документации и спецификаций очень много, но вместе с тем это важный ресурс для обучения и совершенствования своих навыков программирования. Также полезно принимать участие в сообществах программистов и учиться на опыте других людей. Важно понимать, что программирование – это постоянный процесс самообучения и развития.