Обновить

Комментарии 70

Позабавил тэг "разработка игр"

Автор, вот вы когда сами пишете этот хаос из if'ов, у вас ничего не щелкает в голове?

Убрал

Возможно, немного не в тему, но:

А какой фидбек вы ожидаете?

То, что вы попробовали Си - это классно. В любом случае это новый взгляд на программирование и управление ресурсами.

То, что в программе есть что доделать - это тоже очевидно:

scanf("%s", p_choice); -> scanf("%99s", p_choice);

Результат scanf лучше контролировать, т.к. если вы введёте один пробел, то p_choice рискует остаться неизменным;

p_choice на старте лучше обнулить/очистить. Так-то она мусором заполнена, и если это мусор соответствует букве q, то программа сразу же выйдет;

т.к. в программе нет отработки "мусорного" ввода (на запрос ввели "123"), то можно сделать немного полегче-получше: пользователь что-то вводит и в цикле по трём строкам идёт сравнение: какой из вариантов он ввёл? Если ни одному не соответствует, то просим повторить. А если вариант найден, то дальше идёт сравнение чисел. ЧИСЕЛ, КАРЛ! Лучше сравнивать числа: 0 тупит 1, 1 разрезает 2, 2 обёртывает 0.

// окончание игры

if (strcmp("q", p_choice) == 0) {

printf("\nQuitting...\n");

}

можно заменить на просто printf ... - в этом месте p_choice и так равен "q".

Прим.: в нативных языках Си, C++ строковый тип считается "не простым" типом данных (в общем, то это так и есть для всех языков, просто это стараются скрыть в тумане). И поэтому от строк стараются "отойти": если можно переключиться на числа - то лучше работать с числами.

Благодарю за критику. Обязательно приму во внимание Ваши советы.

Там вообще можно сравнение в два условия запихать если нумерацию перевернуть: 0 побеждает 2, а остальные тупо по увеличению значения..

А ведь вы правы. Надо бы мне побольше мыслить числами

В C если тело оператора if состоит из одного оператора, то фигурные скобки можно не писать, на 8 строк меньше.

Логика вашей игры на C и на питоне отличается: в C вы формируете случайный выбор компьютера вне игрового цикла, так что будете угадывать один и тот же вариант.

Плюсанул хотя бы даже за то, что статья написана живым человеком.

Меня уже поставили в известие. Насколько я помню, из-за моего просчета (я не заключил "яблоко рандома" в цикле while) выбор выполняется только один раз, так что выбор тоже будет идти только однажды. Благодарю за комментарий.

Не совсем. Вызов srand() нужно оставить вне цикла, а вот вызов rand() внести вовнутрь.

Откуда вообще вы взяли термин яблоко рандома?

От яблони раздора укатилось

Для людей экономящих фигурные скобки после ифа в аду предусмотрен отдельный котел. Имхо).

Привет из котла

А вот MISRA C:2012 правило 15.6 рекомендует ставить фигурные скобки во всех случаях. Потому что сегодня там одна строка, завтра две. Да и читаемость улучшается

Вы технически правы, но немного не по адресу. Правила MISRA появились из-за критических багов в коде, которые убивали людей. В основном они идут в промышленной разработке, но в мелких хобби-проектах ими можно пренебречь.

Ожидаю фидбека в комментариях!

Напрашиваетесь, сударь, напрашиваетесь...

Вы там, в Питоне своём, как сыр в масле катаясь расслабились до наивности детской. Хотите приложение под Андроид - Kivy, хотите фронтенд - да хоть Anvil.works, и так со всем - Питон и ещё совсем чуть-чуть дают результат. А на С - стоит выйти за вот такую ножницы-бумагу... Андроид приложение - извольте, SDK, NDK, Native Activity и куча подробностей, с которыми можно разобраться, но изложены они с точки зрения Котлина, а то и Джавы. Фронтенд - а Вам какой, на Emscripten или Clang/LLVM? Ну и кусок JavaScript в придачу.,

То, что Вы увидели на ножницах с бумагой - это парадный фасад, а на деле может быть так, что пока Вы, пытаясь получить реально полезный результат, будете учить С, а на это неделя по вечерам уже много, и всю обвязку что и есть задница, можно будет выучить весь Rust и получить тот же результат от Cargo, потом выучить Go и получить результат ещё раз от Go (замечаете - и того проще чем с Растом), а остаток времени провести в душевных метаниях - может быть надо было сразу отдаться, ну или примкнуть к, Flutter?

С Flutter, кстати, возможен пример. На Python вы берёте Flet и ездите на Flutter фрирайдером. На C - сначала Dart, потом Flutter, потом Dart FFI и только потом вопрос "а ради чего?". Если кто-то поклялся Вам хорошо платить за C, ну знает или думает что знает ради чего, это одно дело, а если нет...

Так что от меня фидбек такой - бросайте эту ерунду, вы знакомитесь с С так, как это делали тогда, когда альтернатив не было. Вы питонист? Отлично, напишите модуль на С. Убедитесь, что он и на Андроид, с тем же Kivy например, тоже работает. Напишите что-нибудь на SDL или Qt. И только после этого у Вас появится право решать - понравился С или нет.

Разве C не учат перед C++? В моем видении C — только промежуточная ступень, чтобы получше разобраться в тех же C++/Rust. Хотя, по такой же логике, перед C стоило бы посмотреть на Go/CSharp.

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

Тогда я просто начал бы писать на C++, как на Python. Тогда геморроя было бы в 10 раз больше. Я предпочту сначала понять, как работают системы с минимумом абстракций, чтобы уже потом плавно перетечь в C++.

Ну, писать на C++ как на python у вас всё равно не получилось бы, как не получилось на C. И не стоит ожидать, что C можно плавно "перетечь" в C++. Зная C, можно легко начать писать работающие программы, которые будут компилироваться C++ компилятором. Но для идиоматичного кода придётся учиться заново, местами переучиваясь от привычек из C

Можно знать C и не знать ничего больше, его достаточно для многих применений.

Если очень постараться, то можно и API для бэкенда написать на C.

Я сегодня ради эксперимента взял ИИ (я все еще не умею писать на C, могу только вникать в код) и провел бенчмарк FastAPI-обертки + бэкенда на C против уже существующей этой же обертки на TS. Суть программы была в том, что это была админ-панель (пользователи могли регистрироваться, а админы могли их банить).

Я построил архитектуру так, что Python асинхронно сгребает в батчи (10, 50, 100, 200) запросы и посылает их в C-бэкенд. С количеством обрабатываемых батчей росла и скорость обработки (98× скорости при батче в 200 запросов, и оно шло только вверх по метрике!)

На моем динозавре 2009 года с 6 ГБ ОЗУ оно летало. Я завтра попробую уйти от PostgreSQL и посмотреть в сторону RocksDB, там должно быть еще больше. C++ тоже мне интересен, но я пока не буду его трогать, пусть и знаю несколько прикольных фреймворков для обработки данных

Разве C не учат перед C++?

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

Sic!
Sic!

C и C++ языки очень разные. То, что они местами внешне похожи - следствие того, что на момент создания плюсов поголовно все заинтересованные лица знали C. Далее сходство сохраняли как дань традиции, но сами ответственные лица подчёркивают - это ни в какой степени не являлось целью и делалось строго по возможности.

Изучать C ради лучшего последующего изучения плюсов - ошибка. Чтобы C просто не мешал, его нужно не только основательно изучить, но и к нему привыкнуть, чтобы языки не смешивались один с другим. Если хочется и C и C++, тогда хорошо, если только плюсы - двойная работа в лучшем случае.

Ниже Вы пишете

Тогда я просто начал бы писать на C++, как на Python.

и это очень странно. С одной стороны, как писать как на Пайтон если на плюсах половина кода в одном файле, а другая половина - в другом? С другой стороны, на Пайтон можно писать в любом стиле, в том числе как на плюсах с макросами.

Если языки сами по себе, как хобби или предмет любования логическими, да и алогичными тоже, построениями, не интересуют - никакого смысла в полиглотстве нету. А рассказы типа "я выучил ... и стал лучше ..." - это скорее от нежелания признавать собственные ошибки, чем от искренности.

Например, заинтересовала тема функционального программирования (спецом подальше от C). Тогда можно прочитать про функциональное программирование и подумать как это будет на своём Пайтоне. Где именно прочитать, я не знаю, однако. Если Вы тоже не знаете, ну не удалось выяснить, то берёте книгу по функциональному языку, скажем по Лисп, и читаете по диагонали. Далее то же самое - уложить идеи на Пайтон. Ключевое слово - по диагонали, то есть никак не выучить.

Применительно к C или плюсам - посмотрите на Ассемблер и, если не в курсе то обязательно, на архитектуру машины, особенно на систему прерываний.

А что учить легче — C или плюсы? Не по отделению "по какому языку материалов больше", а скорее по именно усвоению материала

На мой скромный взгляд, чистый Си учить намного легче. Вот совсем (и намного) легче. На C++ одни пляски с шаблонами чего стоят!

НО: если рассматривать условно "большие" проекты, то более понятный, чистый, корректный код будет скорее всего на C++ (конечно, если вы на нём умеете). Просто потому, что стандартных средств для типовых задач - их намного больше. И контроль типов лучше. Повторюсь: это всё работает, если вы умеете "в плюсы". Если вы будете на C++ писать как на чистом Си (многие так и делают и это работает) - тогда преимуществ не будет.

Получается, что на C++ в сложности обучения идет кривая до небес, а после этого плато?

Попробую дать другую аналогию (скорость + дистанция) (также: сравнение с Питоном сделано для контраста, не нужно сильно придираться):

== Задаём скорость:

Питон - это как передвижение по просёлочной дороге (утоптано, умято, вполне ровно);

Си - это передвижение по перепаханному полю (вроде не проваливаемся по пояс, но если побежим, то можно и ноги повредить);

C++ - это передвижение по утрамбованному полю (двигаемся медленно, но возможность повредить ноги снижается).

== Включаем дистанцию:

Начинающий разработчик - ну что там говорить - это быстро везде, особенно с ИванИванычем;

Продвинутый разработчик:

на Си - добраться до деревни в 5 км на север;

на Питоне - это обойти 10 полян на севере на расстоянии 10 км;

на C++ - это побывать во всех полянах на севере на расстоянии 10 км.

---

А теперь переходим к исходному вопросу: что легче? По-моему, легче прийти в одну известную недалёкую точку, хоть и по перепаханному полю.

Очевидно, у Вас возможны другие приоритеты. Банально, разный темперамент может повлиять: кто-то не готов "медленно, в одном направлении, а деревни всё ещё не видно".

---

Прим.: по-моему, кривая обучаемости здесь несколько неинформативна, т.к. объём навыков (ордината графика) сильно разная - количество полян отличается очень-очень. Соответственно и сравнивать крутизну некорректно.

Прим.Прим.: В C++ нет как таковой сложности обучения до небес (например, если что-то не знаете - то вообще босса не замочить ничего сделать нельзя): если что-то слишком сложно, то вы такими средствами не пользуетесь (или используете готовые библиотеки) - и всё ок.

Так красиво расписано все... В поэты бы Вам.

Прим.Прим.: В C++ нет как таковой сложности обучения до небес (например, если что-то не знаете - то вообще босса не замочить ничего сделать нельзя): если что-то слишком сложно, то вы такими средствами не пользуетесь (или используете готовые библиотеки) - и всё ок.

Босс: ты же знаешь С++, у нас на новой платформе проект не собирается, что то с бустом, поправь...

Нет, потом следующая кривая до небес. Первая была еще пологой =)

Сам язык С максимально простой, но при этом и за программиста он ничего не делает. Поэтому за всеми подводными камнями нужно следить самостоятельно.
С++ может взять на себя рутину, но надо знать что написать.

void lower(char *str) {
	for (int i = 0; str[i]; i++) {
		str[i] = tolower(str[i]);
}

А теперь используем:

...
char just_char_array[] = {'e', 'n', 'd', 'l', 'e', 's', 's', ' ', 'F', 'u', 'n'};
lower(just_char_array);
...

Наслаждаемся UB.

Напомню две вещи:

  • Этот код я написал на второй день своего изучения C, причем не обошлось без интенсивного поиска информации по абстрактной логике, не говоря уже о багах и сегфолтах;

  • Код функции предназначен для строк, а не для массивов со строками

Я ценю и уважаю Ваш профессионализм, но надо же вникать в контекст ситуации.

Я же по этому поводу:

Ожидаю фидбека в комментариях!

Ничего страшного, научитесь еще.

  • Код функции предназначен для строк, а не для массивов со строками

И про этот "маленький" нюанс узнаете в процессе.

Прозвучало как страшное предзнаменование. Спасибо за предупреждение.

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

Это и вправду так. scanf() дался мне очень легко, да и строки вида printf("Значение: %d", num) я полюбил даже больше питоновского форматирования строк. Я сам в предвкушении будущей работы с ними.

С "дружелюбным" scanf() Вас тоже ждёт сюрприз. Если Вы свою текущую программу на си будете вызывать на беке с передачей туда пользовательского ввода, то дадите remote code execuition.

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

scanf("%99s", &p_choice) //ограничивает до 99 символов

Начните с Столярова, иначе сищность головного мозга не избежна

В его программе все char* заканчиваются нулями (из-за инициализации списком, надо же, сделали такое в C), поэтому UB не будет.

Поправка: scanf формирует null-terminated последовательность char, поэтому в случае p_choice UB тоже не будет.

Хорошо было бы предложить решение, которое бы позволило в данном случае избежать UB. Вопрос только в том, существует ли оно.

Просто решение — разумеется существует, выделите буфер подлиннее, скопируйте туда аргумент, добавьте в конец \0 и работайте с этой безопасной копией. Но так никто не делает, конечно.

Я просто не понял, что @Serpentine предлагает сделать, чтобы избежать UB непосредственно в функции lower. Какой бы тип не был выбран для строки(указатель, указатель+длина), всё равно пользователь функции сможет передать испорченные данные.

Последовательность char just_char_array[] должна обязательно заканчиваться нулем '\0', иначе это некорректная строка C.

А это не строка. Это массив, вообще-то. Сами-то посмотрите, что у вас объявлено - массив char.

Все верно, массив char содержит NUL-terminated строку C, т.е. последовательность символов, которая заканчивается символом NUL (\0).

Ваше утверждение было бы верно, если бы там был строковый литерал, но его там нет.

char arr1[] = "abc";         ///< вот тут есть null в конце
char arr2[] = {'a', 'b', 'c'}; ///< а вот тут нет

Омг, ну ты бы ещё на ассемблере пытался это написать - да ещё и изучая язык по ходу.

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

Ассемблер пока отложим — кто знает, что будет через месяц

В 2026 так на питоне тоже писать не нужно. Объявите пару enum’ов и вперед:

    match (player_move, computer_move):
        # Draw cases
        case (Move.ROCK, Move.ROCK) | (Move.SCISSORS, Move.SCISSORS) | (Move.PAPER, Move.PAPER):
            return GameResult.DRAW
        
        # Player wins
        case (Move.ROCK, Move.SCISSORS) | (Move.SCISSORS, Move.PAPER) | (Move.PAPER, Move.ROCK):
            return GameResult.WIN
        
        # Computer wins
        case (Move.ROCK, Move.PAPER) | (Move.SCISSORS, Move.ROCK) | (Move.PAPER, Move.SCISSORS):
            return GameResult.LOSE
        
        case _:
            return GameResult.INVALID_INPUT

Можно полный код такой версии?

Что-то типа такого:

import random
from enum import Enum


class Move(Enum):
    ROCK = "rock"
    SCISSORS = "scissors"
    PAPER = "paper"


class GameResult(Enum):
    WIN = "win"
    LOSE = "lose"
    DRAW = "draw"
    INVALID_INPUT = "invalid input"


def determine_winner(player_move: Move, computer_move: Move) -> GameResult:
    """
    Determine the winner using Python 3.10+ pattern matching.
    
    Args:
        player_move: The player's move
        computer_move: The computer's move
    
    Returns:
        GameResult indicating who won
    """
    match (player_move, computer_move):
        # Draw cases
        case (Move.ROCK, Move.ROCK) | (Move.SCISSORS, Move.SCISSORS) | (Move.PAPER, Move.PAPER):
            return GameResult.DRAW
        
        # Player wins
        case (Move.ROCK, Move.SCISSORS) | (Move.SCISSORS, Move.PAPER) | (Move.PAPER, Move.ROCK):
            return GameResult.WIN
        
        # Computer wins
        case (Move.ROCK, Move.PAPER) | (Move.SCISSORS, Move.ROCK) | (Move.PAPER, Move.SCISSORS):
            return GameResult.LOSE
            
        case _:
            return GameResult.INVALID_INPUT


def play_game(player_input: str) -> tuple[GameResult, Move, Move]:
    """
    Play a single round of Rock-Scissors-Paper.
    
    Args:
        player_input: The player's move as a string ("rock", "scissors", or "paper")
    
    Returns:
        A tuple of (result, player_move, computer_move)
    """
    # Parse player input
    match player_input.lower():
        case "rock":
            player_move = Move.ROCK
        case "scissors":
            player_move = Move.SCISSORS
        case "paper":
            player_move = Move.PAPER
        case _:
            raise ValueError(f"Invalid move: {player_input}. Use 'rock', 'scissors', or 'paper'.")
    
    # Computer makes a random move
    computer_move = random.choice(list(Move))
    
    # Determine the winner
    result = determine_winner(player_move, computer_move)
    
    return result, player_move, computer_move


def display_result(result: GameResult, player_move: Move, computer_move: Move) -> None:
    """Display the game result in a user-friendly format."""
    print(f"\nYou played: {player_move.value}")
    print(f"Computer played: {computer_move.value}")
    
    match result:
        case GameResult.WIN:
            print("🎉 You win!")
        case GameResult.LOSE:
            print("😢 You lose!")
        case GameResult.DRAW:
            print("🤝 It's a draw!")
        case GameResult.INVALID_INPUT:
            print("✗ Invalid input")


def main():
    """Main game loop."""
    print("Welcome to Rock-Scissors-Paper!")
    print("Type 'quit' to exit.\n")
    
    while True:
        user_input = input("Enter your move (rock/scissors/paper): ").strip()
        
        if user_input.lower() == "quit":
            print("Thanks for playing!")
            break
        
        try:
            result, player_move, computer_move = play_game(user_input)
            display_result(result, player_move, computer_move)
        except ValueError as e:
            print(f"Error: {e}")


if __name__ == "__main__":
    main()

Гораздо больше 25 строк будет, однако

Недавно я задумался: Python — не единственный инструмент, которым я хочу оперировать в своих инструментах. Python, понятно, легко освоить и он применяется везде, но язык-то не идеальный!

«Неверная» постановка вопроса! Питон – язык идеальный, но, только для своего класса задач. Это – подготовка и обработка данных. Всё! Для работы с графикой, видео, звуком, ГУИ (графическим интерфейсом пользователя), потоками и много чем еще, выгодней использовать С++ с фреймворками.

Я лично предпочитаю WTL, библиотеку кода, занимающую, в исходниках, менее полутора мегабайт! На базе чего написал свою обучающую систему «Леколь» (см. https://lecole.free.nf/ и мои статьи, здесь).

У меня есть, также, неопубликованная программа для работы с медиа-файлами: «МедиаТекст».

Для загрузки любимых видосиком, написал графическую обёртку «MiniDL» для известной консольной утилиты «yt-dlp.exe» ( https://habr.com/ru/articles/955838/ )

Короче говоря, C++ / WTL – рулит! А вот данные для обучающей программы и видео, с двуязычными субтитрами делал на Питоне. Для подобных задач – ему цены нет!

Но, если надо скачать, допустим, онлайн-словарь, для изучения иностранного языка, то для борьбы с капчей, лучше использовать не Питон (там «дорогое» решение), а расширения для старой версии «Хрома», поддерживающую вторую, а не третью версия манифеста. Ибо, последняя – более ограничительная для подобных целей.

Короче, для разных задач – свое ПО!

А «чистый» Си, это, скорее, для нижнеуровневого и консольного программирования. Например, чтобы реализовать собственные видеоплейер в оконной программе, я взял опенсорсный «FFplay.c», переделал его в классы С++ и спокойно подключил к своему проекту. Кстати, ничего путного, на эту тему, на Гитхабе, я так и не нашел.

Так что, не делайте концептуальных ошибок и будет вас счастье!

А вы C++ с нуля учили?

А вы C++ с нуля учили?

Я все языки учил по принципу: Берешь простой прототип, компилируешь. Либо запускаешь на исполнение, если скрипт. Потом, экспериментируешь с кодом, пока не врубишься, что к чему. Книги по языку и документацию, особо, не читал. Из-за чего много времени приходилось сидеть в Интернете, в поисках подходящего прототипа. Сейчас, благо, есть ИИ-сервисы, которые в части поиска нужной информации представляют собой «Интернет-2.0».

Вообще-то, кормил меня язык «1С77». Проще учетной платформы не существует. Единственный минус – программистов «конфигурастов» никто за программистов не считал. Параллельно, я начал, на работе, осваивать ассемблер и декомпиляцию бинарного кода (см. мой сайт https://erfaren.narod.ru/ ). Этого оказалось мало, поэтому перешел на освоение С++. Сначала с MFC, потом с WTL. Последний прижился, пользуюсь им до сих пор. Затем был Питон и т.п. Для них в Visual Studio С++ существуют мастера, которые генерят различные прототипы кода. С их разбора я и начинал освоение языка. Плюс очень много помогал, в свое время, сайт codeproject.com (сейчас он в упадке). Не говоря уже о Гитхабе.

Мужик, ты задолбал с саморекламой

Мужик, ты задолбал с саморекламой

Мужик, ты не одинок в своих чувствах! Меня тоже достают пустые статьи, где много общих слов и ни одного конкретного примера. Я, конечно, повторяюсь, но по делу. Реплики делаю по существу, а не ради рекламы (смысла в которой нет никакого!). Реагируйте на них тоже по существу – будет предметный разговор. Но, обычно, авторы простых статей, сгенерированных ИИ-ями, хотят только, чтобы их хвалили, какие они молодцы, что научились промпты писать, либо никак не реагировали. Однако, критики боятся – в Интернет не ходить! Здесь все-таки технический форум, а не просто тусовка школьников. Что подразумевает некий уровень в текстах. Удивляет, что многим просто нечего сказать в ответ. Зачем тогда вообще ходить на технический форум? Есть другие площадки, попроще.

В крайнем случае, если нечего сказать по делу, можете переходить на личности, типа: «Сударь! Мне не нравится, что вы говорите, как вы говорите и, вообще, вы сами» (можно в переводе на рабоче-крестьянский язык, я не обижусь), либо, втихоря, минусовать. В итоге, и «волки целы и овцы сыты!». Вы получаете сатисфакцию за то, что демонстрируете свое «фе», кому-то, вроде меня, кто примелькался у вас на глазах, а я внушаю вам простую мысль, что на техническом форуме надо больше писать по сути дела, а не переходить на эмоции, без особой нужды.

Зачем сравнивать строки? Можно изначально присвоить номер для введённого слова и пробросить через switch...

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

Наконец то хоть кто-то осмелился подобное написать. Это очень забавно со стороны выглядит.

Респект автору!

Было приятно получить подобный комментарий, спасибо! Кстати, определите, пожалуйста, "осмелился".

Я всегда рад когда люди пробуют C. Это замечательный инструмент обучения, который позволяет приблизиться к железу.

Но самое главное преимущество языка C именно для обучения - это возможность выстрелить себе в ногу в каждой строчке. Это позволяет ещё лучше понять железо, а потом писать более эффективный и разумный код на языках, предоставляющих инструменты защиты от утечки памяти. Ведь на самом деле утечку памяти можно прекрасно устроить и на Rust. И та база, которую вам даст боль от C, пригодится вам везде.

Поздно учить С, если учился начиная с Питона.

Будет теперь такой код, как в статью писать.

Надо память ресетить =)

А вот я считаю, что встряска мне бы не повредила

Никогда не поздно, поверьте

Поддеживаю автора в желании изучить C. Язык являается лучшим средством разрбраться в том, как работает компьютер и что делают программы, написанные на языках высокого уровня.

По Моему мнению, любой программист, вне зависимости от используемого ЯП, платформы и фреймворков, должен "уметь в C", иначе компьюер и программы будут касатся непонятным чёрным ящиком, имхо.

Всегда пугало привидение типа.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации