Поздравляем с прохождением пятой недели CS50! Вы закончили, вероятно, самый непростой блок гарвардского курса по основам программирования. Дальше будет несколько легче, но не менее интересно. Вы подучили язык Си, а, точнее, получили первый навык программирования. Если вам интересно продолжить учиться программированию на JavaRush (или вы уже начали проходить наш курс), держите небольшую шпаргалку. В ней — основные различия Java и Си.

Тип языка

C — функционально-ориентированный

Java — объектно-ориентированный

Это значит, что в C основным блоком программ является функция. В переводе на Java функция — это метод. В то время как в Java основной строительный элемент — это класс.

Сфера использования и популярность

С — cистемное программирование

Java — промышленное программирование

Соответственно, поскольку промышленное программирование носит массовый характер, «джависту» найти работу гораздо проще, чем «сишнику».

Hello world
C
#include
int main(void) {
   printf("Hello\n");
   return 0;
}
Java 
public class HelloWorld {
   public static void main(String[] args) { 
       System.out.println("Hello");
   }
}

Java — интерпретируемый (ну, почти), C — компилируемый

Компилятор берет созданный программистом код и переводит его в нечто понятное машине, нулики и единички. Именно это и происходит в тот момент, когда код C откомпилирован. В то же время Java сначала трансформирует код в то, что мы называем байткодом. Байткод исполняется на виртуальной машине Java (JVM, Java Virtual Machine).

Переносимость кода

По причине интерпретируемости и наличия виртуальной машины, код Java лучше переносится в другие среды, то есть он более портативный. Практически для любой платформы есть своя Java-машина, на которой вы можете запустить ваш код. Слоган Java «Написано один раз, работает везде». Это не совсем так, но довольно близко к правде.

Наличие препроцессора

Препроцессор — программа, которая принимает данные на входе, анализирует их и затем выдает данные, предназначенные для входа другой программы (в случае C — компилятора).

Вы уже прошли 5 неделю CS50, так что запись в начале программы: #include вам знакома.

Здесь мы имеем дело с директивой (или командной строкой) препроцессора C. Эта строка в исходном коде, имеющая формат #ключевое_слово параметры. В нашем случае директива с ключевым словом include означает подключение к программе того, что указано в параметрах. То есть, стандартной библиотеки ввода/вывода stdio.h.

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

Поэтому в более современном языке Java включение файлов заменяют пакеты (ключевое слово package). В Java не предусмотрено разделение библиотек по двум файлам (отдельно для API и имплементации), так что компилятор считывает нужную информацию непосредственно из файлов класса, а команда import сообщает компилятору, что есть такая функция и её пакет такой-то.

С — более низкоуровневый язык, чем Java

Под «низкоуровневостью» и «высокоуровневостью» тут понимаются уровни абстракции. Можно сказать, Си ближе к тому, как понимает код компьютер, но для программиста в нем очень много деталей, которые сокрыты от тех, кто кодит на языках более высокого уровня. Для большинства задач уровень абстракции Java позволяет, не вдаваясь в излишние детали, написать приложение за адекватное время, в то время как C хорош для того, что поближе к «железу» — драйверы и операционные системы.

С — указатели, Java — ссылки

В Java все классы являются ссылочными типами, точно так же, как массивы и строки. Они указывают на созданные в куче объекты, тем самым они похожи на указатели в Cи. Однако в Java нет прямой работы с памятью, в то время как в Си если вы знаете адрес переменной, то можете перейти по этому адресу и получить, а то и изменить данные, которые там хранятся. Это может быть очень полезно, но также и опасно. Указатели являются печально известным источником ошибок. Поэтому в Java классических указателей нет: их устранение упрощает язык и делает программы более надежными и безопасными.

Сборщик «мусора»: только в Java

Виртуальная машина Java выполняет сборку мусора, то есть тех объектов, которые уже не используются, но ещё занимают память. Благодаря сборщику мусора или Garbage Collector’у Java-программисты не должны явно управлять памятью, используемую всеми объектами и массивами. Эта функция устраняет множество ошибок и утечку памяти, с которой зачастую сталкиваются программисты, работающие на C, C++ и других языках.