воскресенье, 4 декабря 2016 г.

Язык Си

Си — инструмент, острый, как бритва: с его помощью можно создать и элегантную программу, и кровавое месиво
Брайан У. Керниган
C (Си) — язык программирования разработанный в 1969-1973 годах в Bell Labs Кеном Томпсоном и Деннисом Ритчи. Создан как развитие языка B (Би) и был предназначен для ОС UNIX. С тех пор считается самым каноничным языком программирования.
Язык Си — компилируемый. Это значит что программа-компилятор переводит Си-программу в бинарный код, который затем выполняется напрямую процессором. Это дает прирост в скорости выполнения программного кода по сравнению с интерпретацией.

Программа

int main(){return 0;} //самая простая программа на Си, которая возвращает 0 операционной системе после своего запуска. 

Важно заметить, что все строки между фигурными скобками (которые ограничивают блоки операторов) должны заканчиваться точкой с запятой.
Особенность языка, его тогдашняя инновационность, заключалась в том, что код разделялся на функции. И это разделение удобно (в отличие от языка PL/M). И все функции программы будут вызываться из главной функции main, которая в программе должна быть обязательно.
Создать функцию просто: тип имя_функции(аргументы}{тело функции}. Появление вызова функции в программе должно идти после её описания (когда указывается тело функции), или же указать в начале файла все функции, которые у нас будут в программе.
Функция может возвращать значение определенного типа (оператором return) или же ничего не возвращать (тогда на месте типа пишут void и такая функция становится процедурой).

Переменные

Типы данных в Си приближены к процессору.
4 типа целых чисел:
  1. signed short int — короткое целое со знаком (2 байта)
  2. unsigned short int — короткое целое без знака
  3. signed long int или просто int — длинное целое со знаком (4 байта)
  4. unsigned long int — длинное целое без знака
Два типа с плавающей точкой:
  1. float — число с плавающей точкой (4 байта),
  2. double — число с двойной точностью (8 байт).
И несколько специфических типов данных:
  1. enum — перечисления,
  2. struct — структуры,
  3. union — объединение.
Существует символьный тип данных — char (1 байт). Строка в понятии языка, это массив из char'ов.
Типы автоматически не преобразуются один в другой, т. к. это потребовало бы дополнительных вливаний вычислений в код.
Конечно же можно создать массив однотипных данных. В том числе и неопределенного размера. И в отличие от BASIC нумерация элементов массива начинается с 0. Элементы локально-объявленного массива инициализировать нельзя, а глобального — можно.
Работа с переменной начинается с её объявления: int a. Объявление может происходить одновременно с инициализацией: int a=0;
Замечание: размеры в байтах указаны для архитектуры x86 и являются архитектуро-зависимыми.

Константы

\n — новая строка, \t — табуляция, \b — шаг назад, \r — возврат каретки, \\ - косая черта, \' - апостроф, \" - кавычки.

Операторы присваивания

= простое присваивание.
+= -= *= /= %= <<= >>= &= ^= |= хитрые присваивания. Их задача уменьшить количество действий с памятью.
Нельзя не сказать и о операторах ++ и --.

Арифметические операторы

  1. + - сложение
  2. - - вычитание
  3. * - умножение
  4. / - деление нацело
  5. % - остаток от деления нацело
  6. ~ побитовое НЕ
  7. & побитовое И
  8. | побитовое ИЛИ
  9. ^ побитовое исключающее ИЛИ

Операторы отношений

  1. == равенство
  2. != неравенство
  3. < > <= >= различные операторы отношения
Эти операторы возвращают 1 если сравнение истинно, 0 если ложно. Важно, что Си не понимает двойного сравнения (как и все остальные языки).

Логичесике операторы

  1. ! логическое НЕ
  2. && логическое И
  3. || логическое ИЛИ
Хотя есть мнение, что деление на логические и арифметические операторы условно. Об этом читать ниже.

Функции

if(условие) оператор1 else оператор2. Если условие истинно (не ноль), то выполняется оператор1, а если нет (условие 0) — то оператор2. Это позволяет проще записывать сравнения с нулем, например if(x!=0) <=> if(x) и if(x==0) <=> if(!x).
while(уловие) оператор1. Цикл выполняет оператор1 до тех пор, пока условие не ноль. for(оператор1; условие; оператор2). Сначала выполнится оператор1, затем будет выполняться оператор2 до тех пор, пока условие не станет ложным.
break используется для предварительного выхода из цикла.
Строго говоря, на этом встроенные функции языка Си исчерпываются. Да, функции ввода-вывода не являются стандартными.
printf(строка, список переменных). Функция форматированного вывода. Количество аргументов для функции переменно и зависит от того, сколько переменных вы хотите вывести. Вывод строки не вызовет никаких проблем: printf("Hello world!"). Чтобы вывести строку с переносом строки нужно написать на нужной позиции \n (new line), например printf("Kill\nall\nhumans\n"). А чтобы вывести значение переменной нужно приложить немного усилий: printf("%d", a). %d означает, что переменная, подготовленная к выводу, целочисленная. %s — строка, %d — целое число.
scanf(строка, переменные). Функция форматированного ввода, аналогична printf. В конец строки автоматически добавляется нулевой символ (\0).

Указатели

Механизм, который вызывает трепет уважения у понявших, ненависть у не понявших и пренебрежении у тех, кто до этого писал на ассемблере.
Например, нам в функции нам нужно изменить значение переданной переменной.
void set(int x){x=14;}
int main(){
 int a=88;
 set(a);
 printf("%d\n", a); //выведется 88
 return 0;
}

Это происходит и-за того, что в функцию передается копия значения переменной,а не она сама. Чтобы избежать этого, модифицируем программу таким образом:
void set(int *x){ //функция получает адрес переменной типа int
 *x=14; //и записывает по этому адресу 14
}
int main(){
 int a=88; set(&a); //передаем адрес на переменную
 printf("%d\n", a); //выведется 14
 return 0;
}

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

Библиотеки

Библиотеки добавляют множество функций в систему языка. Причислим самые часто используемые:
  1. math.h — математическая библиотека содержит модуль, тригонометрические функции, арк-функции, гиперболический функции, логарифмы, возведение в степень и некоторыми другими.
  2. signals.h — библиотека работы с сигналами в ОС Unix.
  3. stdio.h — библиотека содержащая функции для функций стандартного ввода-вывода. Содержит функции работы с файлами (fopen, fclose, remove, rename), fgetc (получить символ), fgets (получить строку), fputc (записать символ), fputs (записать строку), getchar (получает символ со стандартного устройства ввода), gets (получает строку со стандартного устройства ввода), fprintf, fcanf (уже были обсуждены) и проч.
  4. stdlib.h — стандартная библиотека с функциями:
    1. преобразования типов (XtoY, например atoi — строка в целое число),
    2. генерации псевдослучайных чисел (rand, srand),
    3. выделения памяти (Xalloc, например malloc),
    4. контроль выполнения (exit — завершить программу, abort — экстренно завершить программу),
    5. сортировка (qsort) и проч.
  5. string.h — библиотека работы со строками содержит функции копирования, сравнения, конкатенации (дописывания, сложения строк), поиска символов, лексикографического сравнения, определения длины строки и проч.

Директивы компилятора

Директива компилятора начинается с символа # и означает некоторое действие, которое компилятор обязан выполнить, например #include имя_файла означает включить содержимое указанного файла в текущий. Таким образом функции, объявленные в этом, подключенном файле, становятся «видны» в нашей программе.
Другой важной директивой является #define строка значение. Компилятор ищет строку в файле и заменяет её на значение. Это позволяет легко выполнять требование отсутствия в коде «магических констант»: #define BIG_NUM 256.

Компиляторы

  1. GNU Compiler Collection включает компилятор Си. Знает все диалекты и может компилировать код под огромное количество платформ.
  2. MinGW — Минималистичный GNU для Windows. Содержит библиотеки WinAPI.
  3. MS C — старый компилятор от MS под DOS.
  4. TCC — маленький компилятор Си с возможностью интерпретации (!) Си-программ.

Диалекты

  1. K&RC (Си Крнигана и Ритчи). Опубликован вместе с книгой «Язык программирования Си» в 1978.
  2. ISO C или ANSI C. Стандарт языка разработанный ANSI в 1989. Например, теперь функция main должна возвращать хоть какое-то значение (не быть void).
  3. СC99. (легко догадаться до года - 1999) Некоторые добавления: возможность объявлять локальные переменные в любом месте (как в C++): for(int i=0; …) вместо int i; for(i=0; …), однострочные комментарии (как в C++).
  4. C++11. (2011 год, спасибо Кэп!) Введены современные мэйнстримовые фичи: многопоточность, юникод, и проч.

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

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