diff --git a/_config.yml b/_config.yml index 2f09945..2d8e7c6 100644 --- a/_config.yml +++ b/_config.yml @@ -44,14 +44,14 @@ comments: issue_term: # < url | pathname | title | ...> # Giscus options › https://giscus.app giscus: - repo: # / - repo_id: - category: - category_id: + repo: spybull/spybull.github.io + repo_id: R_kgDOK2L1hA + category: General + category_id: DIC_kwDOK2L1hM4Cbk8a mapping: # optional, default to 'pathname' input_position: # optional, default to 'bottom' lang: # optional, default to the value of `site.lang` - reactions_enabled: # optional, default to the value of `1` + reactions_enabled: 1 # Self-hosted static assets, optional › https://github.com/cotes2020/chirpy-static-assets assets: diff --git a/_posts/2023-12-07-struct of program on c lang.md b/_posts/2023-12-07-struct of program on c lang.md new file mode 100644 index 0000000..ce4e8d4 --- /dev/null +++ b/_posts/2023-12-07-struct of program on c lang.md @@ -0,0 +1,231 @@ +--- +title: Структура программы на языке Си +date: 2023-12-07 00:00:00 +0300 +categories: [Programming, С] +tags: [c] +pin: false +author: spybull +--- + +## Структура программы на языке Си + + +### Основная точка входа программы + +В языке Си, код начинает свое выполнение с главной функции, которая называется **main**. +Ее **определение** может выглядеть следующим образом: + +``` +int main(void) { /* ... */ } +int main(int argc, char *argv[]) { /* ... */ } +``` + +Дополнительно про [main_function](https://en.cppreference.com/w/c/language/main_function) + + +### Основной синтаксис программы +Фигурные скобки '{}' обозначают начало и конец блока, где располагается какой-то код и в большинстве случаев они обязательны. +Они нужны для того чтобы логически отделить принадлежность группы каких-то инстуркций от других блоков. + +Вернемся к программе из вводного урока [hello.c]({% post_url 2023-12-06-introduction to c %}#первая-программа): + +``` +#include + +int main() { + printf("hello, world\n"); + return 0; +} +``` + +При запуске, выполнение программы начнется с функции **main**. Все инструкции внутри фигурных скобок, +начиная с '{' и заканчивая '}' - будут выполнятся последовательно друг за другом: + +1) `printf("hello, world\n");` +2) `return 0;` + +Каждая **инструкция** в языке Cи **ДОЛЖНА** заканчивается ";". +Это настолько важно, что если пропустить ее, компилятор вам об этом сообщит: +``` +root@fedora-develop:~/C# gcc semi_error.c -o semi_error +semi_error.c: In function ‘main’: +semi_error.c:4:27: error: expected ‘;’ before ‘return’ + 4 | printf("hello, world") + | ^ + | ; + 5 | return 0; + | ~~~~~~ +``` + +Сообщит также и о неоткрытой в начале '{' фигурной скобке: +``` +semi_error.c: In function ‘main’: +semi_error.c:4:5: error: expected declaration specifiers before ‘printf’ + 4 | printf("hello, world"); + | ^~~~~~ +semi_error.c:5:5: error: expected declaration specifiers before ‘return’ + 5 | return 0; + | ^~~~~~ +semi_error.c:6:1: error: expected declaration specifiers before ‘}’ token + 6 | } + | ^ +semi_error.c:7: error: expected ‘{’ at end of input +``` + +Так и о не закрытой в конце: +``` +root@fedora-develop:~/C# gcc semi_error.c -o semi_error +semi_error.c: In function ‘main’: +semi_error.c:5:5: error: expected declaration or statement at end of input + 5 | return 0; + | ^~~~~~ +``` + +## Разница между инструкцией и ключевым словом + +В языке Си есть такое понятие как **минимальная единица синтаксиса программы**, ту которую компилятор может распознать и называется это - [**лексема**](https://ru.wikipedia.org/wiki/%D0%9B%D0%B5%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B0%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7). Лексемы языка Си включают различные элементы, такие как ключевые слова, операторы, идентификаторы, литералы и так далее. + +### Ключевые слова +Ключевые слова - это слова, которые зарезервированы в языке и используются компилятором +для распознания каких-то определенных действий. + +Например: `int`, `char`, `if`, `return`, `for` + +### Операторы +К операторам относятся арифметические операции, операции сравнения: + +Например: `+`, `-`, `*`, `/`, `==`, `>`, `<` + +### Идентификаторы +Это имена, которые мы задаем самостоятельно например для имен переменных или функций. +Имена поддаются определеным правилам и могут выглядеть следующим образом: + +- myFunction +- my_var +- var1 + +### Литералы +Литерал - это строка, число или символ, которое можно описать в программе следующим образом: + +- 123 +- "hello world" +- 'fuck' +- 3.14 + +[WIKI](https://ru.wikipedia.org/wiki/%D0%9B%D0%B8%D1%82%D0%B5%D1%80%D0%B0%D0%BB_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)) + +### Разделительные символы +```; () {} ,``` + + +### Комментарии +Комментарии больше относятся к синтаксической конструкции и в языке Си есть два вида комментариев: + +Многострочные: +`/* Это комментарий */` +Однострочные: +`// Это комментарий` + +Однострочные комментарии появились начиная со стандарта **C99**. Ранее в языке были только многострочные комментарии, хотя в С++, многострочные комментарии появились в стандарте **С++98**. +Комментарии никак не обрабатываются компилятором и предназначены для программистов + + +## Последовательная обработка программы + +``` +#include + +int main() { + printf("hello, world\n"); + return 0; +} +``` + +`#include` - ключевое слово для [препроцессора]({% post_url 2023-12-06-introduction to c %}#препроцессинг). [Source file inclusion](https://en.cppreference.com/w/cpp/preprocessor/include) + +`` - это просто файл с объявлениями функций. Данный файл можно легко найти в Linux: +``` +root@fedora-develop:~/C# find / -name 'stdio.h' 2> /dev/null +/usr/include/c++/13/tr1/stdio.h +/usr/include/bits/stdio.h +/usr/include/stdio.h +``` + +Узнать где препроцессор будет искать эти заголовочные файлы можно следующим образом: +``` +root@fedora-develop:~/C# gcc -E -Wp,-v - +#include <...> search starts here: + /usr/lib/gcc/x86_64-redhat-linux/13/include + /usr/local/include + /usr/include +``` + +Поведение препроцессора для ключевого слова `#include` выглядит так: + +1) Обработка `#include`: + - Когда препроцессор встречает директиву `#include`, он ищет указанный файл заголовка. + +2) Поиск заголовочных файлов: + - Если указанный файл заголовка заключен в угловые скобки (`#include `), препроцессор + обычно ищет файл в стандартных системных директориях для заголовочных файлов. + + - Если файл заголовка указан в двойных кавычках (`#include "file.h"`), препроцессор + сначала ищет файл в текущем каталоге, а затем включает поиск в стандартных системных директориях. + +3) Абсолютные и относительные пути: + - Если указан абсолютный или относительный путь к файлу, препроцессор использует этот путь для поиска. + + +`int main() {` + +`int` - это ключевое слово. В данном контексте (контексте функции) - оно обозначает возвращаемый тип, +при том целочисленный, пока просто помним, что это одно из ключевых слов, типы данных будут разбираться, когда дойдем до переменных. + +`main` - это [идентификатор](#идентификаторы) но так как это [основная точка входа программы](#основная-точка-входа-программы) +этот идентификатор можно назвать **зарезервированным идентификатором**. + +'()' и '{}' - это [Разделительные символы](#разделительные-символы) + +`printf("hello, world\n");` - функция, которая является частью [стандартной библиотеки GNU C Library](https://www.gnu.org/software/libc/) + +Функция [printf()](https://man7.org/linux/man-pages/man3/printf.3.html) - выводит информацию на стандартный поток вывода **stdout**. +В качестве аргументов, в данном случае, она принимает строку и специальный символ '**\n**', называемый [escape-последовательностью](https://en.wikipedia.org/wiki/Escape_sequences_in_C) + +Например '**\n**' - переводит вывод данных на левый край новой строки. + +`return 0;` - эта инструкция возвращает значение из функции **main**, в данном примере она вернет свое значение в операционную систему. +В этом можно легко убедиться и продемонстрировать скомпилировав и запустив тестовую программу [hello.c]({% post_url 2023-12-06-introduction to c %}#первая-программа): + +``` +root@fedora-develop:~/C# gcc main.c -o main +root@fedora-develop:~/C# ./main; echo $? +Hello world +0 +``` + +**'0'** в контексте завершения работы программы означает ее **успешное завершение**. +Мы можем также вернуть любое другое значение: + +``` +#include +int main(int argc, char* argv[]) { + printf("Hello world\n"); + return 100; +} +``` + +Проверяем: +``` +root@fedora-develop:~/C# gcc main.c -o main +root@fedora-develop:~/C# ./main; echo $? +Hello world +100 +``` +Ненулевые значения могут использоваться для указания на различные виды ошибок или проблемы в программе. + + +## Литература +- [K&R ANSI C](https://kremlin.cc/k&r.pdf) +- [Ахо, Сети, Ульман. Компиляторы. Принципы, технологии, инструменты.2ed.2008.pdf](https://github.com/lehaSVV2009/Compiler/blob/master/books/%D0%90%D1%85%D0%BE%2C%20%D0%A1%D0%B5%D1%82%D0%B8%2C%20%D0%A3%D0%BB%D1%8C%D0%BC%D0%B0%D0%BD.%20%D0%9A%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%82%D0%BE%D1%80%D1%8B.%20%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF%D1%8B%2C%20%D1%82%D0%B5%D1%85%D0%BD%D0%BE%D0%BB%D0%BE%D0%B3%D0%B8%D0%B8%2C%20%D0%B8%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B.2ed.2008.pdf) +- [Про потоки streams](https://www.gnu.org/software/libc/manual/html_node/I_002fO-on-Streams.html) +- [Lex и YACC в примерах](https://rus-linux.net/lib.php?name=/MyLDP/algol/lex-yacc-howto.html) diff --git a/assets/img/favicons/android-chrome-192x192.png b/assets/img/favicons/android-chrome-192x192.png new file mode 100644 index 0000000..7ce9c5e Binary files /dev/null and b/assets/img/favicons/android-chrome-192x192.png differ diff --git a/assets/img/favicons/android-chrome-512x512.png b/assets/img/favicons/android-chrome-512x512.png new file mode 100644 index 0000000..12f2cc6 Binary files /dev/null and b/assets/img/favicons/android-chrome-512x512.png differ diff --git a/assets/img/favicons/apple-touch-icon.png b/assets/img/favicons/apple-touch-icon.png new file mode 100644 index 0000000..d018118 Binary files /dev/null and b/assets/img/favicons/apple-touch-icon.png differ diff --git a/assets/img/favicons/favicon-16x16.png b/assets/img/favicons/favicon-16x16.png new file mode 100644 index 0000000..fdfffc8 Binary files /dev/null and b/assets/img/favicons/favicon-16x16.png differ diff --git a/assets/img/favicons/favicon-32x32.png b/assets/img/favicons/favicon-32x32.png new file mode 100644 index 0000000..28ff629 Binary files /dev/null and b/assets/img/favicons/favicon-32x32.png differ diff --git a/assets/img/favicons/favicon.ico b/assets/img/favicons/favicon.ico new file mode 100644 index 0000000..ed5dca7 Binary files /dev/null and b/assets/img/favicons/favicon.ico differ diff --git a/assets/img/favicons/mstile-150x150.png b/assets/img/favicons/mstile-150x150.png new file mode 100644 index 0000000..a265fe1 Binary files /dev/null and b/assets/img/favicons/mstile-150x150.png differ