Мыслим на Си
Мыслим на Си

Полная версия

Мыслим на Си

Настройки чтения
Размер шрифта
Высота строк
Поля
На страницу:
2 из 2

Давайте убедимся, что компилятор работает.

Шаг 1: Создайте файл

Откройте любой текстовый редактор:

Linux: nano, gedit, vim

Windows (WSL): nano (в терминале WSL)

macOS: TextEdit, nano, vim

Онлайн: встроенный редактор Replit или OnlineGDB

Создайте файл test.c:

bashnano test.c

Шаг 2: Напишите код

c#include int main() { printf("Компилятор работает!\n"); printf("Я готов учить Си.\n"); return 0; }

Сохраните:

В nano: Ctrl + O (сохранить), Enter, Ctrl + X (выход)

В vim: нажмите Esc, введите :wq, Enter

В графических редакторах: Ctrl + S или Cmd + S

Шаг 3: Скомпилируйте

bashgcc test.c -o test

Что это значит?

gcc – запуск компилятора

test.c – ваш исходный файл

–o test – опция "output" (выход): назвать программу test

Если всё правильно, ничего не выведется – это хорошо! Компилятор молчит, если нет ошибок.

Если есть ошибки – компилятор скажет:

texttest.c:3:5: error: expected ';' before 'return'

Читайте сообщения. Они говорят, где ошибка (строка 3, символ 5) и что не так (пропущена точка с запятой).

Шаг 4: Запустите

bash./test

Выведет:

textКомпилятор работает! Я готов учить Си.

Поздравляю! Вы только что написали, скомпилировали и запустили программу на Си.

Часть 8: Философия экспериментов – ломайте без страха

Папа сказал мне когда-то: "Ты можешь сломать этот компьютер. Можешь удалить всю систему. Это нормально. Так учатся".

Самое важное в изучении Си – не бояться ошибок.

Segmentation fault? Хорошо. Вы узнали, что обратиться к памяти, которой нет, нельзя.

Программа зависла? Отлично. Вы узнали, что бесконечный цикл – это плохо.

Компилятор ругается? Прекрасно. Вы узнали правила синтаксиса.

Каждая ошибка – урок. Каждый краш – опыт.

Если вы используете Live USB:

При перезагрузке всё вернётся к началу. Можно экспериментировать, удалять системные файлы, выполнять rm -rf / (не делайте это на установленной системе!). Ничего страшного не случится – перезагрузились, и система снова чистая.

Если вы используете WSL или установленный Linux:

Худшее, что может случиться – вы сломаете свой домашний каталог. Системные файлы защищены (нужен sudo). А домашний каталог – это просто ваши файлы. Удалили программу? Переустановите. Сломали настройки? Удалите конфигурационные файлы.

Если вы используете онлайн-компилятор:

Сломать вообще ничего нельзя – это просто сервер где-то в интернете. Пишите что угодно, экспериментируйте сколько хотите.

Заключение части

Теперь у вас есть:

Компилятор GCC – переводчик с Си на язык машины

Текстовый редактор – где писать код

Терминал – где компилировать и запускать программы

Среда для экспериментов – Linux, WSL, Live USB или онлайн-компилятор

Вы проверили, что всё работает. Написали первую программу. Скомпилировали. Запустили.

Вы готовы учить Си.

В следующей части мы разберём программу "Hello, World" построчно – что означает каждый символ, каждое слово, каждая скобка. Вы поймёте, как устроена программа изнутри.

Но прежде – практика. Измените программу test.c. Пусть она выводит ваше имя, возраст, любимое число. Пять разных строк. Скомпилируйте снова. Запустите.

Привыкайте к циклу: написал → скомпилировал → запустил → изменил → повторил. Это и есть программирование.

Компьютер ждёт ваших команд.

Зара

Глава 2. Переменные и типы данных – Как я вышла на Reddit

Пролог: Первый пост на английском

Мне было почти одиннадцать лет. Пять лет я изучала Си, пять лет писала код, компилировала, ломала, чинила. Я понимала указатели лучше, чем английскую грамматику. Я знала, как работает память, но не знала времён глаголов.

Но у меня была идея. Мысль, которая не давала мне спать: можно ли написать программу, которая думает?

Я хотела обсудить это с кем-то. Папа был занят. Тётя Люда не понимала программирования. Соседская Настя давно уехала учиться в другой город. Мне нужны были люди, которые пишут код. Программисты. Инженеры.

Я зашла на Reddit. Раздел r/programming. Тысячи людей, которые обсуждают алгоритмы, языки, архитектуру. Но все говорили по-английски.

На Reddit не принято хвастаться возрастом или учёными званиями. Здесь важен только код. Только идеи. Это меня устраивало – никто не узнает, что мне нет и одиннадцати.

Я села за клавиатуру. Открыла текстовый редактор. Мне нужно было написать пост. Объявление. Манифест. Но как?

Я знала несколько фраз из учебника английского: Hello. My name is… I am twelve years old. The cat is on the table . Грамматику я не понимала. Артикли казались бессмысленными. Времена глаголов – хаосом.

Но я знала Си. Я знала его синтаксис, его логику, его ритм.

И тогда я подумала: "А что если написать пост как код?"

Я набрала:

c// PhoeNIX: Hello, world.

// Goal: write program that think.

// Status: learning, experimenting.

// Question: who have ideas? Let's discuss.

// Return: knowledge++;

Грамматически это было ужасно. Write program that think вместо правильного write a program that thinks . Who have ideas вместо who has ideas . Но структура была правильной. Комментарии. Цель. Статус. Вопрос. Возврат.

Я нажала Submit .

Сердце билось так громко, что я слышала его в ушах.

Часть 1: Как я чиркнула спичкой

Через пять минут пришёл первый ответ:

Nice try, kid. But "thinking" is not a data type. You need to define what "think" means in computational terms.

Потом второй:

Are you talking about neural networks? Expert systems? Symbolic AI?

Третий:

This is stupid. Computers don't think. They execute instructions.

Четвёртый возразил третьему:

@user3 That's reductive. Turing test exists for a reason. If it behaves like thinking, maybe it IS thinking.

И началось.

Как я потом говорила: "Я чиркнула спичкой, а чему гореть – уже было". Мои оппоненты спорили друг с другом. Высказывали идеи одна безумнее другой. Дискутировали о философии сознания, о тесте Тьюринга, о китайской комнате Сёрла, о нейронных сетях и символьных системах.

А я сидела с английским словарём и переводила слова. Одно за другим. Neural – нейронный. Network – сеть. Symbolic – символьный. Execute – выполнять. Instruction – инструкция.

Часть 2: Программа для изучения языка

Но переводить каждое слово вручную было медленно. И тогда я подумала: "Я же программист. Почему бы не написать программу?"

Я скопировала все комментарии из треда в текстовый файл comments.txt. Открыла редактор. Написала простую программу на Си:

c#include

#include

#include

#define MAX_WORDS 10000

#define MAX_WORD_LEN 50

typedef struct {

char word[MAX_WORD_LEN];

int count;

} WordFreq;

WordFreq words[MAX_WORDS];

int word_count = 0;

void to_lowercase(char *str) {

for (int i = 0; str[i]; i++) {

str[i] = tolower(str[i]);

}

}

int find_word(char *word) {

for (int i = 0; i < word_count; i++) {

if (strcmp(words[i].word, word) == 0) {

return i;

}

}

return -1;

}

void add_word(char *word) {

int index = find_word(word);

if (index != -1) {

words[index].count++;

} else {

strcpy(words[word_count].word, word);

words[word_count].count = 1;

word_count++;

}

}

int main() {

FILE *file = fopen("comments.txt", "r");

char word[MAX_WORD_LEN];

while (fscanf(file, "%s", word) != EOF) {

to_lowercase(word);

// Убираем знаки препинания

int len = strlen(word);

while (len > 0 && !isalpha(word[len-1])) {

word[–len] = '\0';

}

if (len > 0) {

add_word(word);

}

}

fclose(file);

// Сортируем по частоте (простой пузырёк)

for (int i = 0; i < word_count – 1; i++) {

for (int j = 0; j < word_count – i – 1; j++) {

if (words[j].count < words[j+1].count) {

WordFreq temp = words[j];

words[j] = words[j+1];

words[j+1] = temp;

}

}

}

// Выводим топ-50

printf("Top 50 most frequent words:\n");

for (int i = 0; i < 50 && i < word_count; i++) {

printf("%3d. %-20s (%d times)\n", i+1, words[i].word, words[i].count);

}

return 0;

}

Эта программа:

Читает файл comments.txt

Разбивает текст на слова

Подсчитывает, сколько раз каждое слово встречается

Сортирует по частоте

Выводит топ-50 самых частых слов

Результат выглядел так:

textTop 50 most frequent words:

1. the (347 times)

2. is (201 times)

3. a (156 times)

4. to (134 times)

5. think (89 times)

6. program (76 times)

7. computer (71 times)

8. neural (54 times)

9. network (52 times)

10. data (48 times)

Я взяла этот список. Убрала служебные слова (the , is , a , to – они бесполезны для понимания смысла). Осталось около 200 ключевых слов.

Я начала переводить и запоминать самые часто используемые. Think – думать. Program – программа. Computer – компьютер. Neural network – нейронная сеть. Data – данные.

Часть 3: Переменные – это слова

Я заметила закономерность. В английском, как и в Си, есть типы слов.

Существительные – это переменные типа int или char*. Они хранят объекты: program , computer , network .

Глаголы – это функции. Они выполняют действия: think , execute , process .

Прилагательные – это константы или модификаторы. Они описывают свойства: neural , symbolic , computational .

Я начала строить предложения как код:

c// Английское предложение:

// "The program thinks using neural networks"

// Как я это понимала:

const char* subject = "program"; // Подлежащее

const char* verb = "thinks"; // Глагол

const char* method = "neural networks"; // Метод

printf("The %s %s using %s\n", subject, verb, method);

Это работало! Через месяц я бойко дискутировала короткими фразами:

Consciousness ≠ computation?Neural networks = pattern matching?

Thinking = information processing?

Люди отвечали. Спорили. Объясняли. И с каждым днём мой словарный запас рос.

Часть 4: Переменные в Си – коробки для данных

Вернёмся к Си. Что такое переменная?

Переменная – это имя для куска памяти. Компьютер выделяет место в оперативной памяти и говорит: "Вот адрес 0x7ffd1234. Теперь этот адрес называется age".proza+1

Простейшая программа с переменной:

c#include

int main() {

int age; // Объявляем переменную

age = 11; // Присваиваем значение

printf("Мне почти %d лет\n", age);

return 0;

}

Что происходит в памяти?

Компилятор видит int age; и резервирует 4 байта памяти

Эти 4 байта получают имя age

Команда age = 11; записывает число 11 в эти байты: 00 00 00 0B (в шестнадцатеричном)

printf читает эти байты и выводит их как число

Часть 5: Типы данных – грамматика Си

В Си нельзя просто сказать "создай переменную". Нужно указать тип – какие данные она будет хранить.

Это как части речи в языке. Нельзя сказать "слово". Нужно: "существительное", "глагол", "прилагательное".

int – целые числа

cint age = 11;

int temperature = -5;

int population = 1000000;

int хранит целые числа (обычно от -2,147,483,648 до 2,147,483,647). Занимает 4 байта.

char – символы

cchar letter = 'P'; // Первая буква PhoeNIX

char digit = '7';

char newline = '\n';

char хранит один символ. Занимает 1 байт.proza+1

Но секрет: char – это на самом деле маленькое целое число. Символ 'P' – это число 80 (код ASCII). 'h' – 104. 'o' – 111.

cchar letter = 'P';

printf("%c\n", letter); // Выведет: P

printf("%d\n", letter); // Выведет: 80

float – дробные числа

cfloat pi = 3.14159;

float temperature = -5.5;

float хранит числа с плавающей точкой. Занимает 4 байта. Точность – около 6-7 десятичных знаков.

double – дробные числа двойной точности

cdouble precise_pi = 3.141592653589793;

double – это float с двойной точностью. Занимает 8 байт. Точность – около 15-16 знаков.

Таблица типов

ТипРазмерДиапазонСпецификаторchar1 байт-128 до 127%c или %dint4 байта±2 млрд%dfloat4 байта±3.4×10³⁸%fdouble8 байт±1.7×10³⁰⁸%lf

Часть 6: Структуры – группы переменных

В моей программе для подсчёта слов я использовал структуру:

ctypedef struct {

char word[MAX_WORD_LEN];

int count;

} WordFreq;

Структура – это способ объединить несколько переменных в одну. Как коробка с отделениями: в одном отделении – слово (char word), в другом – счётчик (int count).

Создаём переменную типа структуры:

cWordFreq w;

strcpy(w.word, "think");

w.count = 89;

printf("Слово '%s' встречается %d раз\n", w.word, w.count);

// Слово 'think' встречается 89 раз

Точка . означает "обратиться к полю структуры".

Массив структур – это таблица:

cWordFreq words[10000]; // Массив из 10000 структур

words[0].word = "think";

words[0].count = 89;

words[1].word = "program";

words[1].count = 76;

Так я хранил словарь частотности.

Часть 7: Инициализация – создание и заполнение

Вы можете объявить переменную и присвоить ей значение в одной строке:

cint age = 11;

char initial = 'Z';

float pi = 3.14159;

Это инициализация. Безопаснее, чем в два шага.

Почему? Потому что неинициализированная переменная содержит мусор:proza+1

cint x; // Не инициализировали!

printf("%d\n", x); // Может вывести 0, может 184759392, может -5

В Unix-философии: "Будь явным, не неявным". Если создаёшь переменную – сразу скажи, что в ней должно быть.

Часть 8: Константы – переменные, которые не меняются

cconst int MAX_WORDS = 10000;

const float PI = 3.14159;

MAX_WORDS = 5000; // ОШИБКА! Компилятор не позволит

Или через препроцессор:

c#define MAX_WORDS 10000

#define MAX_WORD_LEN 50

#define – текстовая замена до компиляции. Препроцессор просто заменяет MAX_WORDS на 10000 везде в коде.

Часть 9: Метафора – память это файл

В Unix всё – файл. Клавиатура – файл (/dev/input). Экран – файл (/dev/fb0). Память – тоже файл (/dev/mem).

Переменная – это имя файла в памяти. Тип – это формат файла. Значение – это содержимое.

cint age = 11;

Это как создать файл /memory/age размером 4 байта с содержимым 00 00 00 0B.

cage = 12;

Это как открыть файл, стереть содержимое и записать новое: 00 00 00 0C.

В Linux вы можете увидеть память процесса:

bashcat /proc/self/maps

Всё прозрачно. Всё доступно. Это Unix.

Часть 10: Философия обучения через код

Когда я учила английский через частотный анализ, я не учила грамматику. Я учила паттерны.

Neural networks process data – паттерн: прилагательное + существительное + глагол + существительное.The program thinks – паттерн: артикль + существительное + глагол.

Компьютер помог мне увидеть структуру. Как компилятор видит структуру кода.

Через месяц я писала:

Neural network = weighted graph. Thinking = pattern recognition. Consciousness = emergent property?

Короткие фразы. Без артиклей. Без сложных времён. Но понятные. Логичные. Правильные.

Один пользователь написал:

@PhoeNIX Your English is improving fast. How old are you, by the way?

Я ответила:

Age = irrelevant. Ideas = relevant.

Он засмеялся (написал lol ) и больше не спрашивал.

На Reddit важен только код. Только идеи. Возраст не имеет значения.

Заключение главы

Теперь вы знаете:

Что такое переменные и типы данных

Как объявлять и инициализировать переменные

Что такое структуры и массивы

Как память работает как файловая система

Что код может помочь учить человеческий языкotvet.mail

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

Практическое задание:

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

Потом возьмите любой текст на английском (статью, форум, книгу), пропустите через программу и начните учить самые частые слова.otvet.mail

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

P.S. от PhoeNIX:

Кто-то сказал мне на Reddit: You think in code, not in language.

Я ответила: Code IS language. Universal language.

И это правда.

Переменные – это слова. Типы – грамматика. Программы – предложения.

Если вы понимаете это, вы можете говорить с кем угодно. На любом языке.

Потому что логика универсальна.

Зара

Часть 11: Код говорит громче слов

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

@PhoeNIX Here's my attempt at a simple pattern matcher. Thoughts?

cint match_pattern(char *text, char *pattern) {

int i, j;

for (i = 0; text[i] != '\0'; i++) {

for (j = 0; pattern[j] != '\0' && text[i+j] == pattern[j]; j++);

Конец ознакомительного фрагмента.

Текст предоставлен ООО «Литрес».

Прочитайте эту книгу целиком, купив полную легальную версию на Литрес.

Безопасно оплатить книгу можно банковской картой Visa, MasterCard, Maestro, со счета мобильного телефона, с платежного терминала, в салоне МТС или Связной, через PayPal, WebMoney, Яндекс.Деньги, QIWI Кошелек, бонусными картами или другим удобным Вам способом.

Конец ознакомительного фрагмента
Купить и скачать всю книгу
На страницу:
2 из 2