Search
Write a publication
Pull to refresh

Comments 52

Боюсь фраза "Habr идеальное место для этого " не совсем верна. Вот пикабу, вконтактик, dtf - да. А на хабре могут очень много накидать в панамку за пространные описания на вольные темы. Тут все таки любят серьезно проработанные статьи или посты.

автору уже накидали в панамку за предыдущий туториал по установке python

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

Я запостил сегодня серьезную пропаботанную статью над которой работал больше месяца - никто не читает. :-(

Не понял, для кого эта статья. Профи и так все это знает. Новичок из такого сумбурного объяснения ничего не поймёт.

Кстати, неужели на Руси перевелись текстовые редакторы, которые правописание проверяют? Нет, например, слова "врятли", есть выражение "вряд ли".

Некоторым "путь в АйТи" со школьного курса русского языка и литературы надо начинать. Класса с пятого примерно.

Только хотел написать, что перед изучением C стоило бы изучить русский язык хотя б на твёрдую 4 :)

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

hello world пишется 1 раз. Дальше уже надо начинать понимать, что это и зачем оно.

Hello world пишется столько раз, сколько надо проверить что система сборки как таковая не объявила забастовку и не сошла с ума. Завидую людям у которых это число раз равно 1.

система сборки как таковая не объявила забастовку и не сошла с ума

С чего бы вдруг такое?

А я знаю? Сидишь себе, никого не трогаешь, тут бац, какой-нибудь find_package(ZLIB REQUIRED) говорит "пошёл нахрен". Или случается The CXX compiler identification is unknown.
Или просто настраиваешь какой-нибудь инструмент в первый раз, типа "хочу кросс-компилированный под ARM Go, использующий вот этот C-код".

И во всех этих случаях начинаешь с самого простого: пусть у меня соберётся программа, которая использует все релевантные технологии самым примитивным образом из возможных - напишет в консоль "привет", нарисует чайник, мигнёт одним светодиодом. В этом смысл Hello, world-программ: доказать, что у целевой системы можно вызвать какое-то поведение перед тем как пытаться вызывать сложное.

И во всех этих случаях начинаешь с самого простого

Начинать имеет смысл 1 раз. Гонять HelloWorld по кругу - зачем?

The CXX compiler identification is unknown

тут никакой HelloWorld не поможет, это чудеса cmake. сжечь build directory.

Это уже продвинутые вещи, которые явно к хеллоу ворлд имеют мало отношения.

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

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

Как по мне, при изучении ассемблера на первых порах надо именно что вручную вызывать и транслятор ассемблера, и компоновщик: чтоб понять реальную последовательность действий и что за что отвечает. И лишь когда поймёшь, как несколько объектников связываются в выполняемую программу (с возможным добавлением библиотечных модулей), тогда можно считать, что более-менее понял, как это происходит (а как в действительности работает -- это уже надо вникать в форматы объектных и выполняемых файлов, тонкости работы компоновщика и др., что явно не для новичка).

понять реальную последовательность действий

Это если вы изучаете устройство билд-системы К самому языку это слабо относится, даже если это ассемблер.

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

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

Когда то давно программу на ассемблере можно было сбилдить в com. Без всех этих секций. Тонкости линковки - это особенности целевой платформы, к самому ассемблеру это слабо относится.

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

Нет. Иначе возможно искажение сознания, когда от чего-то специфического уже будет трудно перейти к базе.

Не, ну, в Скрэтче можно порисовать, можно.

Статья явно переписана с чата гопоты, но соглашусь, по своему опыту обучения сына робототехнике. Путь самурая начинается с Си. И как сетовал и не один препод ВУЗов на соревнованиях: "приходят с питоном, и дать им алгоритмическое программирование на С,С++, Джава увы сложнее на порядок". 13 медалек у сына, в т.ч. третье место по Росси.. проверено опытом.

Кажется в этом случае преподаватель ничего кроме С не знает и знать не хочет.

Нет, проблема не в этом. Тех кого знал тогда - крутые мамонты, много полезного сделавшие в ИТ. Проблема в ином: самурай вошедший в ИТ с визуальщины и питона, не понимает подкапотные проблемы и ему крайне сложно объяснить концепцию указателя в правильном понимании. Они по большей части так и остаются питонистами "по жизни". Если что, я про детишек в возрасте 8-12 лет, которые входят в ИТ через робототехнику, типа "это просто". Там статистика у преподов была очень впечатляющей.

Как пример, поездка в ВУЗ на тренировку. Препод ведет занятие должников и заодно работает с нашими детишками по Ардуино. Вышел, кто-то позвал. Две кучки: слева наши, справа студенты (просто присутствовал, запомнилось). Два студента, сдающих зачет:

-"Слышь, у меня чего-то этот датчик ничего не показывает.." Второй подходит, что-то говорит вслух.. С нашей стороны (5-и клашки! Но С/С++ умеют уже в каком-то виде)

-"Так там надо в прерывании, обработать вот эту ногу .. (подходит к студенту) - ну да, вот тут у тебя пропущена обработка.. надо вот так.." В этот момент заходит препод обратно:

-"Так, может я тут и не нужен, может ты сам у него зачет примешь" :)

У меня, например, другой опыт. Я начинал с Visual Basic: формочки, простые игрушки, никаких указателей. Потом был Javascript. Концепцию указателей понял почти сразу, как прочёл первый учебник по Си, сложности определённые были, но это всегда так, когда что-то новое осваиваешь. Не могу сказать, что стал крутым знатоком си, но что-то умею. При этом не уверен, что было бы также весело начинать с голого си, а не с формочек и простого бейсика, потому что изначально решил программированием заниматься, чтобы игры делать. Пока на чистом си дойдёшь хотя бы до отрисовки текстуры, уже желание может отпасть.

Блин, в кого ни ткнешь, у всех сыновья медалисты всероссийские, такое ощущение что первых мест десятки тысяч :) Нет, я рад что ребята талантливые, но просто как то забавно это :)

информации вроде много, но она уж слишком сильно не структурирована и не систематизирована

Что нужно понимать про сам язык. Сам язык был разработан Денисом Ритчи в 1972 году

Фундаментально! Эта информация просто необходима для новичков, да

Раньше книжки читали, когда ещё интернета толком не было и как-то проблем с информацией по Си тоже не возникало :)

Тот же Ричи вместе с Керниганом по своему языку и книгу написали 😉

Лет 5 назад на Хабре была модная тема "я недопонял Functional Programming и сейчас вам объясню на примере говна и палок КАК ОНО НА САМОМ ДЕЛЕ".
Сейчас эта тенденция добралась до С/С++.

> И здесь мы сталкиваемся с первой значимой путаницей между определениями и их интерпретацией. Дело в том что на самом деле язык программирования C является языком высокого уровня, а не низкого как многие его считают.
> Почему же так? На самом деле потому что любой язык программирования является автоматически языком высокого уровня, так как сильно абстрагирует нас от вещей которые происходит на самом деле под капотом.

На самом деле надо пользоваться устоявшимися терминами. И если в мире языков программирования С/С++ называют низкоуровневым - то это соглашение.

А в качестве "общего развития" можно посмотреть на иерархию абстракций (в любом приличном институте дают).
Низкоуровневые языки дают возможность взаимодействовать с ОС.
Более высокоуровневые - начинают содержать библиотеки сложных алгоритмов или DSL-ориентированные имплементации отдельных задач уровня приложения.

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

embedded-программисты вышли из чата. Пример типичного кода:

PORTC |= (1 << DDC5);

В плане языка программирования это вполне себе высокоуровневый код, никак не привязанный к системе команд и устанавливающий один битик в переменной PORTC. Что данная переменная -- это имя регистра, отображённого на память, ничего принципиально не меняет. (Ну или макрос, разворачивающийся в обращение к памяти по явно заданному адресу -- это уж как определено.) Он является низкоуровневым в силу решаемой задачи -- дёрганья ноги GPIO, -- а не в силу используемого языка программирования.

А вот если б язык был действительно низкого уровня, то пришлось бы писать машинные команды, необходимые для выполнения того же самого, и набор этих команд зависел бы от архитектуры. Скажем, на PDP-11 это можно выполнить одной командой, а на ARM потребуется три.

Думается, Вы, как и многие другие, смешиваете "уровень" языка программирования и "уровень" задач, которые на нём решают. Дрыганье ногами GPIO -- задача низкоуровневая, но решена она может быть и на языке низкого уровня (ассемблере), и языках высокого уровня. Можно, конечно, сказать, что С -- язык более низкого уровня, чем Пыхтон, и с этим я соглашусь, -- но это не делает С языком низкого уровня, подобным ассемблеру: он не привязан к архитектуре, и написанный на нём код сам по себе переносим между различными архитектурами (а вот ассемблерный приходится переписывать полностью).

Язык ещё более низкого уровня - это машинные коды непосредственно с переключателями или HEX-редактором и справочником команд. (Панелька для микросхемы - условная)

Вообще-то, язык низкого уровня -- только ассемблер.

Довольно глупое определение (хотя я не могу запретить вам быть тупоконечником).

Смотрите, положим на минуту, что ассемблер( = мнемоника над ISA) единственный вариант языка низкого уровня, то зачем нам два термина "ассемблер" и "низкоуровневый ЯП". Достаточно одного.
Но оба термина существуют - значит оба нужны и полезны.

Помимо чистого ассемблера, т.е. языка-"обёртки" над набором команд конкретной архитектуры, были широко распространены макроассемблеры, дающие возможность определять макрокоманды для автоматического формирования часто используемых последовательностей команд и данных. Так что по своим возможностям разные трансляторы ассемблера для одной и той же архитектуры могут отличаться очень сильно -- и очень сильно может различаться и сам язык, ведь мнемоники машинных команд -- это лишь его часть, и ассемблер отнюдь не "= мнемоника над ISA", как Вы утверждаете.

Ну а термины "язык высокого уровня" и "язык низкого уровня" появились очень давно -- вместе с Фортраном и Коболом, и как раз для того, чтобы отличать их от языков ассемблера по единственно принципиальной между ними разнице -- привязке к конкретной системе команд или отсутствию такой привязки.

Ну а термины "язык высокого уровня" и "язык низкого уровня" появились очень давно -- вместе с Фортраном и Коболом

Я в курсе.
Более того в институте я учил определение "ЯНУ" примерно как вы сказали.

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

========================
Разумеется о значении терминов не спорят, а договариваются (поэтому я не могу запретить вам быть тупоконечником, вы мне остроконечником - но для меня это не столь принципиально).
Но сегодня более содержательный термин - ЯНУ то, что позволяет управлять ресурсами аппаратуры напрямую, желательно без сайд-эффектов (как минимум в критических к этому секциях).

Дык в том-то и дело, что только ассемблер позволяет управлять любыми программно доступными регистрами; традиционным образом компилируемые языки, вроде сей и паскаля -- только регистрами, отображёнными на память, а это далеко не все регистры. (И, кстати говоря, интерпретируемые языки и языки, выполняемые на виртуальных машинах тоже, в принципе, могут это делать через специальные функции, а классические Бейсики на 8-разрядных машинках часто имели такую возможность "из коробки" -- что ещё больше размывает границу, придумывают же всякие микропыхтоны).

Ну а в современном С++ ещё и другая проблема: компилятор оптимизирует настолько агрессивно, что зачастую нарушает порядок выполнения операций, и приходится принимать специальные меры (ставить барьеры и т.п.), чтобы он это не творил. Ассемблер же транслирует команды именно в том порядке, в каком их написал программист.

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

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

Тогда надо терминологию менять, а не переиначивать старое на новый лад -- иначе вообще бред и неразбериха получается. Собственно, это везде нас и окружает -- и как раз из-за того, что с терминологией обращаются слишком вольно и никак её не стандартизируют (а если стандартизируют, то как раз не то, что требовалось: скажем, придумали "кибибайты" с "мебибайтами", хотя килобайты и мегабайты никакой путаницы не вызывали -- в отличие от, например, что считать RISC-процессором и что -- микроядерной ОС; ну и с уровнями языков тоже).

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

Простите (ну вот реально не воспримите за наезд), - а зачем вы про "2*2 = 4" портянки пишите. Я же всё про техническую часть написал до вас.

==============
Из интересных затронутых тем - действительно в сегодняшнем употреблении: "ЯВУ != ~ЯНУ". Т.к. ЯВУ - про удобство наворачивания абстракций, а ЯНУ - про возможности работать с ресурсами аппаратуры напрямую.

Ну а про термины - могу только повторить: сегодняшнее словоупотребление, учитывая современный контекст (оставить ассемблер единственным синонимом ЯНУ - было бы странно) в отношении ЯНУ мне вполне устраивает.

Биться за термины ради терминов в этом месте - считаю если честно малопродуктивным.

Там ошибок тонна...

Переписать от ИИ тоже нужна внимательность уровня "разраб-мидл" хотя-бы.. :)

Сам язык был разработан Денисом Ритчи в 1972 году, а затем популяризирован благодаря книге в соавторстве с Брайаном Керниганом (второй к самому языку никакого отношения не имеет в том числе и по его собственному признанию он лишь в соавторстве с Ритчи выпустили книгу

Керниган из скромности заявлял о своей непричастности к разработке языка Си. Он, а также другие сотрудники Bell Labs внесли огромный вклад в язык, точно так же как и С++ не разрабатывался Страуструпом в одиночку (Эндрю Кёниг, Стен Липман, Барбара Му и еще с десяток другой разных людей).
Помимо Кернигана к разработке языка в значительной степени причастен Кен Томпсон, а также Дюг Макилрой, Роб Пайк, Питер Нельсон и др., по сути все кто разрабатывал UNIX в первых его версиях.

У самурая нет цели, только путь (с)

Чем вам книги не угодили? Вы в принципе исключили их из рассмотрения. Дейтелы, Прата? Макграт на худой конец ( лучше сразу первые главы Дейтелов, там тоже самое) ? На статьях в Интернете далеко не уедешь.

Есть нюансы вроде двойных и тройных указателей (знание которых проверяется в тестах), но их уместно изучать тогда, когда появятся соответствующие задачи. Мне указатели впервые встретились в asm при работе со строками, я быстро наловчился их использовать. Практика на реальных алгоритмах здесь полезнее сухой теории.

p. s. про указатели есть отдельная книжка Риза (Understanding and using C Pointers), где, скорее всего, всё разжёвано до мелочей (пока не читал)

На Степике есть прекрасный бесплатный курс по C/C++ для начинающих от Сергея Балакирева. Параллельно с ним решать «Изучаем программирование на C” Гриффитсов. И читаем «Архитектура компьютера» от Таненбаума и для начала вполне хватит. Если начинающий совсем начинающий можно до Таненбаума прочесть «Код» Петцольда.

Что такое язык программирования использующий процедурный стиль создания программ?
На самом деле здесь у людей также много заблуждений и неправильной интерпретации определений.

Функциональный стиль программирования и функциональный язык программирования, это не синонимы. В функциональном стиле можно писать и на процедурном языке (на том же С). Просто у вас не будет нет никаких гарантий и все ограничится соглашением между разработчиками. Тогда как функциональный ЯП сам следит за выполнением ограничений на чистые функции и разработчик не сможет случайно или намеренно использовать внутри них глобальное состояние.

Что нужно понимать про сам язык. Сам язык был разработан Денисом Ритчи в 1972 году, а затем популяризирован благодаря книге в соавторстве с Брайаном Керниганом (второй к самому языку никакого отношения не имеет в том числе и по его собственному признанию он лишь в соавторстве с Ритчи выпустили книгу которая лишь придала еще больший импульс C как языку программирования)

Да уж, всё самое важное от языке Си. ;-)

Почему бы не написать о том, что именно побудило Ричи, Томпсона и Кернигана разработать свой (новый) язык программирования ? Чем не устраивал тот же FORTRAN, PL/1 или COBOL ? Или, скажем, почему не писать на МАКРО ассемблере (в то время системщики так и делали) ?

Очень хороший и всесторонний тест для языка общего назначения - это self-hosted language, то есть который может скомпилировать сам себя. Там и работа с деревьями, текстом, числами , оптимизация. Конечно скриптовые делать такими бессмысленно, если это не библейский LISP, а вот новые компилирующие вполне могут поставить для себя такую задачу, включая общий анализ проекта и устранение сборки всего при изменении буквы в /*abc*/ . С и С++ сильны как раз этим, что обросли всевозможными приёмами и костылями проектного уровня а не конкретной программы, включая гиты, докеры, мейкеры, кодогенераторы-матлабы. В этом их уникальная гибкость.

Женщина - она не мужчина, она женщина..
C - не функциональный, C - он процедурный..

заставляет задуматься.. Как минимум, там ли я, где хочу находиться... не правда ли?

Смотрите Константина Владимирова на ютубе - год лекций по C и несколько лет лекций по C++

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

В универе на первом курсе учили С. Да было больно, трудно, но интересно. После получения зачета и экзамена мы были похожи на ту широкоплечию собаку с мемной картинки. Ещё трудновато даввлось ооп на с++, так как это новый уровень абстракции, но и его побороли. В целом после этого каких либо проблем с другими языками не возникало, ну разве что ФП тоже удивило. Поэтому да, лучше начинать с С, так как он хорошо демонстрирует как работают программы на самом деле, да и в целом он никуда не делся.

Sign up to leave a comment.

Articles