---
# System prepended metadata

title: 01 лекция Полная версия

---


# 01 лекция Полная версия
## За жизнь
Сначала будет много про Си, тк Си++ - исходно расширение языка си
Изначально был как предпроцессор, который превращал это в си код, который потом компилировался, это был не отдельный язык, а надстройка над си. Потом он даже разошелся с си, некоторые вещи работают по другому. Но в общем С++ можно считать надмножеством языка си, многое, что работает в си, работает и в ++.


Идея - языка C/C++. Почему важно - сильно влияет на проиходящие, стиль и т.д. Си относиться к одним из самых старых яп которые живы, старше си только фортран. Фортран создавался как язык для научных вычеслений. В Фортран легко работать с матрицами и т.д. А на си удобнее работать с системными функциями. Фортран часто используется в вычеслительных серверах. На нём написано много ПО, по этому яп до сих пор жив. Языки бывают разные. Паскаль создавался для обучения. 

:::info

-Для чего создавался си?
:::spoiler Ответ
-Системными программистами для себя.
Программистам приходилась писать всё на ассеблере каждый раз на новую железку, чтобы так не делать - придумали си. Но достаточно низкоуровневый, для быстрых операций.
:::

> Си устроен синтаксически очень кратко. В паскале/java Integer начинает бесить пока я это пишу.

**Язык Си очень доверяет программисту**
есть очень много разных примеров

:::warning
-чем функция отличается от процедуры?
:::spoiler Ответ
-функция возвращает что-то, а процедура нет
:::

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

Наверное слышал, что на си легко выстрелить себе в ногу. Си не будет держать тебя за ручку, он подумает, что ты умней, ты знаешь, что делаешь. Это и хорошо и плохо. Плохо - из-за неколифицированности, требуется выше калификация. (на Java нужна калификация ниже, си и особенно си++ требуется калификация больше, чтобы не натворить глупостей) С другой стороны, то, что вам язык больше доверяет - позволяет вам больше сделать. На всяких высокур языках надо изголиться или вообще нельзя, а цена проверок - скорость, на java программы переодически откровенно лагают. Чем более высокоуровневый язык, тем больше абстракций и больше стоимость абстракций, а чем более низкоуровневый - тем больше извращений при написании, но и больше процент вычеслительной мощьности. (мин количество абстракций)

Если вас интересует в первую очередь скорость разработки и возможность использования низкокалифицированного персонала - С/C++ плохой вариант
Если вас интересует в первую очередь скорость работы, и вы готовы потратить больше времени на отладку, чтобы сьэкономить на железке - С/C++ вероятно хорошая идея

Java - C/C++ с отрезанными указателями
C# - java От майкрософт 


## Компиляторы
Ещё важная особенность си, в отличие от rust, в си есть спецификация, почему rust считается пока не дошел до серьезного состояния - нет спецификации, пока нигде не описанно, как точно он должен работать, как оно должно выполняться - компилятор один (как работает - так и должно) (это не очень хорошо - потому что есть багги)


У C/C++ есть великое множество компиляторов, его для подмножества си можно написать за 3 дня, но у такого компилятора написанного студентом есть огромная огромная раница с крупными.

:::danger

-Чем (крупный) компилятор отличается от просто компиляторов?
:::spoiler Ответ
1) это оптимизирующй компилятор (это очень сложно) (генерация машшиного кода, которая будет быстрая и компактная)
2) выдают очень хорошие ошибки/warnin'ги (не поймете, пока сами не напишите)
:::

Когда вы пишите компилятор и там простая ошибка - ; ломается это не в том месте, а где-то далеко и вообще не очевидным образом, и догадаться про ; - не тривиально. То, что выдаются хорошие и точечные ошибки - это огромная огромная работа

Крупные компиляторы C/C++ (3,5 независимых реализаций):
1) Clang(LLVM)
2) GCC (Gnu Compiler Coliction)
3) Microsoft (Visual Studio)
4) (3.5) Intel (парсер - clang) (исходно (генерация кода) - своя реализация)

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

## За жизнь и за стандарт
**Стандарт - та часть языка, которая работает везде!**

Суперфичи - то, что работает с конкретным компилятором (не стандартная), больше всего проблем с GCC, например:
```#include <bits/stdc++. h>``` (подключить все стандартные библиотеки(хедеры))
> Все настолько плохо, что однажды когда пытался скомпилировать программу clang он выдал ошибку:
> This feature is gcc will never be supported

(раньше VS грешила этим.)
Поддержка стандартов тоже очень плавает - VS откровенно не хотели поддерживать новые стандарты именно C.

Идея C/C++ - быть более менее переносимым. 
**С точки зрения пероносимости - Си гораздо круче java!** 
(если на каком-то железе есть java, то с ооогромной вероятность есть компилятор си) В отличие от Java очень хорошо держит обратную совместимоть (Java и мобильная java - разные вещи).

Си очень хорошо держит обратную совместимость. 
Был случай, когда пытался собрать программу на java, если слишком старая версия - этих фукнций нет, если слишком новая - эти функции задипликэйтили, то есть их уже нет. Нужно было двоичным посиком искать нужную версию java. Да и десктоп версия и мобильная версия java - совершенно разные вещи.

СИ довольно консервативен, В ++ все время выходят бешенные новые стандарты, где добавлены куча новых фичей, где 2 следующих стандартов их пытаются пофиксить, потом дипликэйтят, а в следующем вводят новую вариацию на тему того же самого.

В C за всё время развития задиплекэйтили только одну единственную функцию - ```gets()```, потому что она читает в буфер неопределенные размеры, и легко получить ```buffer overflow``` (в 11 стандарте).
    
Исходно в Си не было bool (из-за бесполезности), в C++ было сразу, в си добавили в виде ```_Bool```, тк кто-то мог использовать ```bool``` в качестве имени переменной, а слова начинающиеся с _ зарезервированны под будущие версии языка. (```#include <stdbool.h>``` - будет ```bool```)
(std - сокр. от standart)

:::danger

-Чем документация отличается от спецификации?
:::spoiler Ответ
**Документация - описание разной степени подробности\
Спецификация - требование, как оно должно работать**
:::



Стандарт описан очень обтекаемо, тк железо работало по разному. Стандарт был рассчитан на то, чтобы эффективно компилировать программы, чтобы после компиляции программа наиболее эффективно работала на разном железе. Если железо работает по разному, а стандарт четкий - железо которое работает не так должно в этом месте городить кучу костылей, чтобы получить то поведение, которое требует стандарт. Многие части стандарта си которые [Undefined Behavior](https://ru.wikipedia.org/wiki/%D0%9D%D0%B5%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D1%91%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D0%BE%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5)  или [Implementation-defined behavior](https://habr.com/ru/post/450910/) Они не потому, что не могли норм написать стандарт, а потому что железо работало в этом месте по разному. Но эти вещи в большинсте устарели. (первый международный стандарт си выпустили в 90, придумали в 72) 

Современное железо гораздо более унифицированно, в отличие от времени когда писался первый стандарт си, например: представление целого числа - дополнение до 2х (почти везде) (в стандарте си 23 скорее всего это признают)

:::warning
-Что представляет из себя компилятор?
:::spoiler Ответ
-Компиляция - перевод с одного Яп на другой (обычно на машинный код)
:::

> Про чистый си можно порекомендовать книжку Керниган Ричи - язык программирования СИ, от создателя языка, есть переводы на русский, но есть и плохие переводы.
> Если посмотреть старые старые издания этой книжки - там весь код написан заглавными, тк в те далекие времени в компьютерах не было маленьких букв. Не разделяли на маленькие и большие. (сейчас не прокатит, **си - регистрозависиммый язык**)

## Hello world
Программа на си состоит из функций, и весь код распредлен между функциями, они равноправны, и не бывает вложенных функций (а в gcc бывает), едиственная выделенная функция - main, с неё начинается программа и ей заканчивается программа 

### Функции
функция - `тип-возвр-значения   имя   (аргументы)`
С точки зрения Кернигана и Ричи, пустое место в типе возвр значения яснее всего указывает на то, что функция возвращает int. 

`void` - специальный тип, который можно поставить в то место где тип требуется, но никакого типа по факту нет

`main` может принимать аргументы

переменную типа `void` не создать

процедура - это `void` функция

```с
#include <stdio.h> //Подключение заголовочного файла стандартной библиотеки ввода-вывода

int main(void)    // Пустые строки на C++ эквивал. void
                  // На си НЕ эквивалент
{
    printf("Hello!\n");
    return 0;    // Стандарт разрешает не писать, только в main
}
```
> f(void) и в С, и в С++ означает, что функция не имеет параметров, а f() в С++ означает то же самое, а в некоторых стандартах С — что функция имеет неизвестное число параметров
> это относится к тем временам, когда типы аргументов объявлялись не в прототипе функции, а в реализации, т.е.
```с
f(a, b)
int a;
double b;
{
}
```

`int main(void)` - заголовок функции
`{ }` - тело фунции (или чего либо другого)
Если функция описана возвр что-то кроме `void` - она должна заканчиваться строчкой `retun somthing;` причем `somthing` должно быть того же типа, что и мы обещали в обьявлении функции. 

:::warning
-А куда мы этот 0 (в примере) возвращаем?
:::spoiler Ответ
-Программу запускает операц система, и по завершению процесса - у процесса есть код завершения.
:::

Программисты согласились что если она возвращает 0 - программа заканчивает успешно, если нет, какую-то цифру - означ ошибку.

`return` можно писать в функции `void`

```с
void f(int a)
{
    if(a == 0)
    {
        return;
    }
    
}
```