Если вы задумались о том, чтобы освоить первый в своей жизни язык программирования, то вам придётся поломать голову над тем, а что же выбрать из многообразия существующих языков. В мире веб-разработки царит JavaScript, во многих ВУЗах и школах предлагают изучать Python. Если поспрашивать на форумах, то вам вывалят кучу вариантов, включая Haskell, Scala и Erlang. Богатство выбора хорошо почти в любом деле, и обилие языков программирования свидетельствует о том, что это направление научно-прикладной деятельности продолжает развиваться. Одному человеку уже не под силу изучить все существующие языки, поэтому приходится решать какой же язык лучше всего начать осваивать. Зачастую изучают то, что принято в конкретной компании или сегменте рынка. Но если вы только собираетесь сделать первые шаги на ниве программирования, то можно порекомендовать начать с одного из языков семейства С. Это будет наиболее дальновидным выбором, который поможет вам в карьере. Возможно, вы не станете ежедневно писать на этом языке, или не будете изучать его очень глубоко. Но если вы хотите, чтобы к вам относились как к серьёзному разработчику, то вам обязательно нужно владеть одним из языков семейства С.
Что за «семейство С»?
Ответ на этот вопрос зависит от того, кого вы спрашиваете. Разработчики любят только одну вещь больше, чем споры о происхождении и взаимном влиянии языков программирования, — спор о том, какой язык лучше. Но вне зависимости от этого существует общепринятое мнение, что к семейству С относятся сам С, С++, C#, Objective-C и Java.
В качестве очень грубого определения можно сказать, что язык относится к семейству С, если в нём для выделения функциональных блоков используются фигурные скобки {}. Многие языки этого семейства (но не все) являются строго типизированными. Большинство из самых популярных языков являются объектно-ориентированными (С++, С#, Java)однако это не касается самого C. Немало распространённых языков, не относящихся к семейству С, испытало на себе его влияние: Python, Perl, PHP, Ruby и т.д. Однако оценки степени и важности этого влияния сильно различаются. Например, в JavaScript используется синтаксис по типу С, но если копнуть глубже, то эти языки сильно отличаются друг от друга.
Если вы освоите один из языков семейства С, то это даст вам понимание фундаментальных основ программирования: переменных, значений, типов, присваивания, выражений, функций, параметров, возвращаемых значений, потока команд и т.д. Это базовые концепции, которые должен знать любой программист, и, изучив язык семейства С, вы будете на одной волне с большинством других разработчиков, а это важно для многих работодателей.
Латынь не мертва, она просто отдыхает
На всякий случай уточним, что не нужно изучать все языки данного семейства, достаточно ограничиться каким-то одним. Конкретный выбор зависит от сложившихся условий в вашей компании. Ну или от того, чем именно в сфере разработки вы планируете заниматься в будущем. Если вы работаете с продуктами Microsoft, то есть смысл выбрать C#. Если разрабатываете приложения под Android, изучайте Java. Если создаёте встроенные системы или что-то подобное, то наиболее полезным вариантом будет старый добрый С. Если вы работаете в какой-то другой сфере, то возьмитесь за С++.
Языки семейства С обладают очень удобным свойством: если вы изучили один из них, то остальные «идут» гораздо легче. Сегодня никто не говорит на латыни, но её всё ещё полезно изучать, поскольку она облегчает освоение итальянского, испанского и французского языков. Освоив один из С-языков вы не станете экспертом в остальных языках семейства, но кривая обучаемости станет менее пологой. Можно с уверенностью утверждать, что если вы знаете C#, то вряд ли испытаете затруднения с чтением листинга на Java. Конечно, чтобы начать на нём писать, вам придётся изучить синтаксис Java, но это займёт дни, — в крайнем случае, недели, — а не месяцы. Разумеется, чтобы виртуозно программировать на каком-либо языке, придётся потратить на изучение и практику куда больше времени.
Многие разработчики в глубине души мечтают стать «программистами-полиглотами» (или уже считают себя таковыми). Хотя этот термин зачастую означает «я знаю ещё кое-что помимо одного из языков семейства С». Тем не менее, С-язык является своеобразным фундаментом, на который можно опереться при изучении других языков. С-языки формируют характерное «правильное» программистское мышление. И если вы освоите один из этих языков, то сможете легко перейти к изучению, например, функционального языка. Переключение на язык с иной парадигмой подразумевает смену образа мышления программиста. У многих это вызывает затруднение, но зато даёт полезный опыт. Это вовсе не означает, что изучение языка семейства С вызовет в будущем проблемы с освоением иных языков. Хороший разработчик должен уметь мыслить в рамках разных парадигм, как функционального программирования, так и императивного. Вам в любом случае придётся потратить время на усваивание основ, поэтому лучше начать с одного из наиболее распространённых языков.
Ваша личная подушка безопасности
Всё вышесказанное проистекает из предположения, что вы хотите изучить программирование ради того, чтобы потом этим зарабатывать. Но не всеми движет подобная мотивация. Если вы хотите научиться программировать ради удовольствия, то выбирайте вообще любой язык, какой душе угодно.
Если же вы действительно хотите сделать программирование своей профессией, то лучше заранее ознакомьтесь со списком языков, наиболее востребованных работодателями. В рейтинге TIOBE первые четыре языка относятся к семейству С, а почти все остальные из Топ 10 испытали на себе влияние С. Вам больше по душе рейтинг PYPL? В его Топ 10 половина языков также относится к семейству С. Можно ставить под сомнение релевантность любого рейтинга, но если собрать их все вместе, то можно достаточно точно оценить востребованность на рынке специалистов в тех или иных языках. Конечно, встречаются работодатели, которые не настаивают на том, чтобы вы знали именно тот язык, который им нужен, но любой бизнесмен заинтересован в том, чтобы новые сотрудники как можно быстрее могли приступить к выполнению своих обязанностей. В данном случае — чтобы кривая обучаемости была как можно круче. А знание языка семейства С, как было сказано выше, в этом очень помогает.
Даже если вы сам себе работодатель, умение писать на С-языке может оказаться очень полезным, если вам вдруг придётся искать работу. Возможно, вы обожаете Haskell и потратили годы, совершенствуясь в этом языке, но в жизни всякое бывает, и владение одним из С-языков с большей вероятностью поможет вам трудоустроиться. В противном случае вам придётся много объяснять на собеседованиях, почему вы никогда не изучали С++ или Java.
Программируя хорошие привычки
Скорее всего, вам придётся выбирать язык для изучения исходя из того, какие проблемы вы хотите решить. Или вам предложат тот или иной вариант в компании, где вы работаете. Не менее важным критерием может быть и «актуальность» того или иного языка. Несомненно, круто быть одним из первых освоивших новый язык программирования, о котором говорят на каждом
Если вы изучите один из С-языков, то вряд ли вас кто-то за это наградит, но однажды этот опыт и знания могут оказать вам неоценимую поддержку.
Комментарии (105)
leschenko
12.08.2015 10:27+20На мой взгляд, начинать обучение программированию следует с алгоритмизации. А тут чем проще язык, тем лучше. И C не подходит для этой цели. Это очень мощный язык и для новичка теряется фокус.
Salabar
12.08.2015 10:59+3Куда уж проще Си-то? Наследование, интерфейсы, компараторы, что? То ли дело стандартная либа Си. Около сотни функций из которых постоянно дай бог десяток нужно. Даже не представляю, что представляет собой 99% библиотеки C# и как этим пользоваться.
leschenko
12.08.2015 11:07+12Сам синтаксис не прост. Ой как не прост. Это отвлекает от сути. Вместо того, что бы вникать в основы программирования, приходится вникать в язык C. Т.е. начиная с C, вы изучаете именно C, а не программирование как таковое. В этом проблема.
potan
12.08.2015 12:18+1Ага. Давайте учить Haskell, Scheme или хотя бы Forth. Минималистичный синтаксис, ни какого наследования!
haskel
12.08.2015 13:24-7не, начинать надо с языка, исходники которого легко читать с гитхаба и смотреть как на нем вообще пишут, не углубляясь в магию. А Си — это магия указателей и макросы, язык грязных хаков. Чтобы легко читать на си придется развить внутренний препроцессор и резолвер указателей.
averkin
12.08.2015 21:06+5То, что С — язык грязных хаков…
Простите, но вы сейчас напердели в душу, я думаю, трети населения хабра.haskel
14.08.2015 02:39ой, да ладно вам дуться. Вот на гитхабе ребята более самокритичны относительно хаков https://github.com/search?q=ugly+hack&ref=reposearch&type=Code&utf8=%E2%9C%93
asm0dey
12.08.2015 17:51Это почему в хаскеле наследования нет?
potan
12.08.2015 19:45Потому что подтипы сильно усложняют проверку и автоматический вывод типов. И компилятору, и программисту.
asm0dey
12.08.2015 23:03Ну я так рассуждаю — если полиморфизм есть и типы есть — значит есть наследование. Оно может не совсем C-like, но есть.
0xd34df00d
13.08.2015 14:57Наследование тайпклассов там есть.
А это ваше новомодное ООП — тайпклассы для бедных.potan
13.08.2015 18:40Тайпкласся не совсем наследуются. Там можно описать ограничение, что тип данного класса обязан реализовать и другой класс. А так как классы могут связывать несколько типов, и наследование уже не будет графом.
0xd34df00d
14.08.2015 14:47А что такое наследование для ООП тогда? Если класс B (публично) наследуется от A, не значит ли это ровно то же, что B является A, то есть, обязан реализовать всё, соответствующее A?
Про «не будет графом» не понял, если честно.potan
14.08.2015 16:25Для ООП если кто-то реализует B, то он автоматически реализует A. Хотя согласен, что общего много. Из-за этого вывод типов иногда не справляется.
Бывают классы вроде
class Vecspace v f where mul :: f -> v -> v
Для них зависимости объяснить наследованием будет сложнее.
denis_g
12.08.2015 14:46+2А что там сложного?
#include <stdio.h> int main() { int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int sum = 0; int i; for (i = 0; i < 10; i++) { sum += arr[i]; } printf("Your sum is: %d\n", sum); return 0; }
А биты, байты, размерность переменных, переполнение, sizeof, символьные последовательности, ука.затели — это из разряда must know в любом случае.p53
12.08.2015 15:56+3биты, байты, размерность переменных, переполнение, sizeof, символьные последовательности, ука.затели — это из разряда must know
Вы могли бы пояснить, почему это must know? Во многих современных языках биты, байты, указатели – это всё под капотом и позволяет сосредотачиваться на главном – на самом программировании. Условно говоря, чтобы быть хорошим водителем автомобиля с автоматом (не пилотом болида, прошу заметить), мне не важно, как устроен двигатель, кроме самых общих представлений. Мне важнее знать ПДД.
Ах, да. Должен ли начинающий программист изучать ассемблер?denis_g
12.08.2015 16:20+3Под капотом это хорошо, удобно. Но понимание всегда лучше, чем заучивание и принятие «на веру». Если ты знаешь, как устроена память, не нужно будет потом часами вникать, например, почему же deepcopy такой медленный.
Поэтому вопрос, must know или не must know — это личный вопрос каждого начинающего программиста. Хочет понимать, как устроено — учит внутренности, не хочет учить внутренности — stackoverflow ему в помощь. Аналогично и с ассемблером.
gaffer
19.08.2015 23:23Программист, который действительно серьезно думает о том как стать лучше — да. Посмотрите ка на чем написаны TACP Кнута. Мix — это ассемблер и есть. Пусть и под выдуманную машину.
Aingis
12.08.2015 17:06+4#include <stdio.h> — не напишешь в пустом файле из головы, нужен шаблон.
int — разные форматы хранения чисел знать полезно, но не на самом начально этапе.
arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; — зачем писать [10], когда и так перечислено 10 элементов?
sum = 0 — почему у «sum» присвоен 0, а у «i» нет?
printf("Your sum is: %d\n", sum); — проще было бы «log("Your sum is:", sum)»
return 0; — строчка только чтобы удовлетворить правила.
Слишком много формализма.denis_g
12.08.2015 20:41+61) #include <stdio.h> — подключение библиотеки ввода-вывода, без понятий «ввод-вывод», «библиотека», «подключение библиотеки» в отрасли делать нечего.
2) int — целое число, целые числа проходят максимум в шестом классе общеобразовательной школы, кстати, тогда же проходят и дробные числа (float); освоение всей сути чисел с плавающей запятой можно спокойно отложить года на 2-3.
2) arr[10] — выделение памяти под 10 ящичков с числами, без понятия «выделение памяти» (хоть на стеке, хоть в куче) в отрасли делать нечего. Явно писать [10] нужно для того, чтобы выделить память именно под 10 ящиков. Кроме того, если не ошибаюсь, стандарт C99 поддерживает объявление и инициализацию массива без указания размера. Кроме того, можно использовать конструкцию «int arr[10] = {1, 2, 3}», чтобы создать 10 ящиков, в первые 3 положить числа 1, 2 и 3, а в остальные 7 — нули.
3) = — оператор присваивания (положить в ящик) — есть хоть один ЯП, который его не имеет?
4) {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} — запись чисел от 0 до 9 в ящики, которые были подготовлены в п. 2
5) Потому что в «int sum = 0» происходит создание ящика и запись туда значения, а в «int i» — только создание ящика (закрепляем понятия «выделение памяти», «оператор присваивания»). При желании, можно всегда присваивать переменным значения при инициализации, заодно и обезопасить себя в будущем (в Java, например, это вообще обязательно).
6) Насчет printf согласен, для обучения было бы проще избегать форматирования, однако тут мы узнаем понятия «символ переноса строки» и «форматирование строк».
7) C — это такой язык, в котором любая функция, если она не void, должна явно возвращать значение. Обязательный явный возврат значений вырабатывает полезную привычку не забывать писать return, а также позволяет при беглом взгляде на код сразу же найти точки выхода из функции (особенно при диковинных ветвлениях, которые так свойственны начинающим при изучении алгоритмов). Кроме того, возврат значения из функции main определяет код завершения работы программы. Понятие «код завершения работы программы» на ранних этапах обучения необязательно к изучению (в этом случае функцию main можно просто объявлять как void), но все равно полезно.
Тем, кто подобную информацию освоить не в состоянии, предлагаю использовать язык HQ9+. Обычные ученики 10-го класса обычной общеобразовательной школы вполне в состоянии прослушать мини-лекцию (1.5 урока) по адресации и статической маршрутизации в сетях IP и затем применить полученные знания на практике путем составления плана разбиения сети класса C на N подсетей с переменной маской подсети, а затем составления статических таблиц маршрутизации для произвольных узлов подсетей. Так что не надо считать начинающих программистов дебилами, неспособными за два-три урока освоить азы языка C.
P.S. Хотелось бы видеть подобную программу на любом другом хоть как-то типизируемом (на JS я тоже могу однострочник написать, ага) ЯП, мне тоже хочется покритиковать немножко ;)
P.P.S. Если что, я вообще пишу на Python и Javascript.
P.P.P.S. Да, с ассемблером тоже знаком.
P.P.P.P.S. www.lib.ru/CTOTOR/starterkit.txt — пригодится ;)f0rk
12.08.2015 21:03P.S. Хотелось бы видеть подобную программу на любом другом хоть как-то типизируемом (на JS я тоже могу однострочник написать, ага) ЯП, мне тоже хочется покритиковать немножко ;)
Пожалуйста:
main = putStrLn $ "Your sum is: " ++ (show $ foldl (+) 0 [1..9])
denis_g
12.08.2015 21:16+9А что такое $?
А зачем $ нужен?
А если я напишу a $ (b $ c $ d) $ e $ f $ g, где a, b, c, d, e, f, g — лямбды, что будет?
А что такое foldl?
А что такое (+)?
А почему он в скобках?
А что там делает 0?
А если туда другое число поставить?
А можно нумерацию в скобках с нуля?
А почему у %username% в PHP нет такого количества непонятных символов?
P.S. А код таки красивый ;)f0rk
13.08.2015 12:34+1А что такое $?
Это правоассоциативный оператор применения функции с низким приоритетом.
то есть f $ x — это то же самое что f(x).
А зачем $ нужен?
В большинстве случаев он используется для того что бы не писать скобки группирующие операции в выражении, кроме того иногда частично примененный $ удобно передать в функцию высшего порядка, например
вернет все степени двойки от 1 до 10. Здесь в map мы передаем список лямбд и функцию ($ 2), которая вызовет каждый элемент списка с двойкой в качестве аргумента.map ($ 2) [\x -> x ^ a | a <- [1..10]]
А если я напишу a $ (b $ c $ d) $ e $ f $ g, где a, b, c, d, e, f, g — лямбды, что будет?
Будет a((b(c(d)))(e(f(g)))).
А что такое foldl?
Левая свертка.
А что такое (+)?
Функция суммирования двух аргументов.
А почему он в скобках?
Потому что его нужно привести к префиксной форме для передачи в функцию.
А что там делает 0?
Это стартовое значение для функции свертки.
А если туда другое число поставить?
Результат будет отличаться на величину этого числа.
А можно нумерацию в скобках с нуля?
Можно.
А почему у %username% в PHP нет такого количества непонятных символов?
Не правда, есть. Там долларов еще больше чем в хаскеле.MaximChistov
13.08.2015 13:04+2Вам намекают на вопросы новичка которому выдали такое, вам-то конечно оно все понятно, да вот только это не для вас
m03r
12.08.2015 22:20+3А зачем
foldl (+) 0
? Есть жеsum
main = putStrLn $ "Your sum is: " ++ (show $ sum [1..9])
JIghtuse
13.08.2015 10:10sum ведь реализовать надо, а не использовать готовый.
m03r
13.08.2015 10:22Вроде бы в корневом комментарии речь шла о сложности синтаксиса, а не о том, что нужно реализовывать какую-то функцию «своими руками». Библиотечная
sum
упрощает дело (и, кстати, делает синтаксис более понятным).
bogolt
13.08.2015 08:51+1Раз уж вы решили не повторять код на си и не создавать массив ( в котором могли бы хранится любые другие значения не возврастающая прогрессия ) то вот там си аналог вашего кода:
#include <stdio.h> int main() { printf("Your sum is: %d\n", (0 + 9) * 10 / 2); }
зы: return 0 в функции мейн не обязателен уже давно насколько я помню.denis_g
13.08.2015 09:20Можно даже проще:
#include <stdio.h> void main() { printf("Your sum is: 42^W 45\n"); }
ImLiar
12.08.2015 23:51+2P.S. Хотелось бы видеть подобную программу на любом другом хоть как-то типизируемом (на JS я тоже могу однострочник написать, ага) ЯП, мне тоже хочется покритиковать немножко ;)
Немного скалы:
println("Your sum is: " + (1 to 10).sum)
denis_g
13.08.2015 00:08Сам себе отвечу на Go (так сказать, для коллекции):
package main import "fmt" func main() { arr := []int{0,1,2,3,4,5,6,7,8,9} sum := 0 for _, x := range(arr) { sum += x } fmt.Println("Your sum is:", sum) }
MacIn
27.08.2015 01:32подключение библиотеки ввода-вывода, без понятий «ввод-вывод», «библиотека», «подключение библиотеки» в отрасли делать нечего.
Хм… можно вспомнить, прости господи, Basic. Только не надо ставить минусы, потому что не нравится этот язык — я просто привел пример.
2) int — целое число, целые числа проходят максимум в шестом классе общеобразовательной школы, кстати, тогда же проходят и дробные числа (float)
Одно дело — знать, что такое целое и дробное, другое — понимать, почему типы разные для целого и дробного. На этапе обучения самым азам — это лишняя деталь. Достаточно понимать, что есть, скажем, «число» и «строка».
2) arr[10] — выделение памяти под 10 ящичков с числами, без понятия «выделение памяти» (хоть на стеке, хоть в куче) в отрасли делать нечего.
При чем тут отрасль? Могу тогда вам сказать, что без знания ассемблера (мнемокодов), машинного языка (бинарник), детального понимания электроники на уровне проектирования кристалла — в отрасли делать нечего.
Напомню, разговор шел об обучении азам, начиная с алгоритмизации.Назачемкозе баянпри обучении алгоритмизации вдаваться в детали реализации массива в конкретном языке? Есть другие, в которых массив можно создать динамически.
5) Потому что в «int sum = 0» происходит создание ящика и запись туда значения, а в «int i» — только создание ящика (закрепляем понятия «выделение памяти», «оператор присваивания»)
При обучении азам, алгоритмизации «создание ящика» — ненужная деталь. Это слишком низкий уровень. Для первичного обучения достаточно «у нас есть ящик i, в нем будет лежать номер ячейки, с которой мы работаем». И «укажем, что начинаем с ячейки 0», как отдельный шаг.
Обязательный явный возврат значений вырабатывает полезную привычку не забывать писать return
… который нужен именно в Си.
P.S. Хотелось бы видеть подобную программу на любом другом хоть как-то типизируемом (на JS я тоже могу однострочник написать, ага) ЯП, мне тоже хочется покритиковать немножко ;)
OK, чисто в порядке бреда (массив списком нельзя инициализировать):
dim i, sum, element for i = 0 to 9 read element sum = sum + element next i print "Your sum is:"; sum data 0,1,2,3,4,5,6,7,8,9
dim нужен только для типизации (можно указать AS INTEGER), так можно и опустить.
eugzol
15.08.2015 22:51И это ещё не упомянули вырвиглазный синтаксис for. Елки, помню когда лет в 10 читал книги по разным языкам программирования, если бы я остановился на всех вот этих C-like (C/C++/Java), никогда бы ничему не научился :)
lightman
12.08.2015 21:55-6А биты, байты, размерность переменных, переполнение, sizeof, символьные последовательности, ука.затели — это из разряда must know в любом случае.
Ваши взгляды на обязательные знания в программировании устарели лет этак на 20-30. В наше время можно окончить обучение на программиста, получить корочки и сертификаты, комитить в опенсоурс, работать, периодически меняя место на более высокооплачиваемое, дорасти до архитектора и выйти на пенсию, так и не узнав о том что такое
биты, байты, размерность переменных, переполнение, sizeof, символьные последовательности, указатели
Плохо это или хорошо — уже совсем другой вопрос. Но, факт, можно жить и без этого.denis_g
12.08.2015 22:16+5Нууу… Без одной почки, в общем-то, тоже можно жить ;)
Я выше более подробно изложил свою точку зрения. Да, я считаю, что те вещи, с которыми ты работаешь, нужно знать на пару уровней ниже, чем необходимо для работы. И это касается не только программирования, но и даже обычной шариковой ручки — чтобы потом не злиться, от того что она на потолке не пишет.lightman
13.08.2015 08:04Если говорить о ручке, то для успешного её использования вовсе не обязательно знать химический состав чернил, показатель их вязкости, правила перезаправки стержня и утрамбовки этой полупрозрачной гелевой штуки, предотвращающей чернила от вытекания.
Ты просто пользуешься ручкой как ин-стру-мен-том, на собственном опыте определяя границы её возможностей (по побелке потолка пишет плохо, по бумаге хорошо).
Для этого требуется лишь о-пыт. Понимание внутренних процессов не о-бя-за-тель-но!
Клеймить писателей ручками (пользователей современных высокоуровневых языков программирования) за это всё равно что-то старчески ворчать: «а вот в наше время писали перьями, да-а-а, там надо было методично макать перо в чернильницу, следя за степенью погружения, потом аккуратно переносить на бумагу, не поставив кляксу, да и писать, строго соблюдая усилия нажима и наклон пера. Совсем обленилась молодёжь со своими автоматическими ручками, ни за что из вас настоящих писателей не получится!denis_g
13.08.2015 09:12+1нужно знать на пару уровней ниже, чем необходимо для работы
В случае ручки:
а) в ручке есть стержень, в стержне паста, паста жидкая
б) стержень устроен так, что жидкость вверх не течет
в) вот эта картинка (на всякий случай)
на собственном опыте определяя границы её возможностей (по побелке потолка пишет плохо, по бумаге хорошо).
Ага, на собственном опыте перепробовал 100500 ручек, оказалось, все плохие, ни одна из них не пишет на потолке, сделал вывод, что китайцы дичь какую-то загнали.
Клеймить писателей ручками (пользователей современных высокоуровневых языков программирования) за это всё равно что[...]
Еще раз приведу свою цитату:
Поэтому вопрос, must know или не must know — это личный вопрос каждого начинающего программиста. Хочет понимать, как устроено — учит внутренности, не хочет учить внутренности — stackoverflow ему в помощь.
moveax3
26.08.2015 15:22дебильное сравнение
большинство высокоуровневых языков и их компиляторов работают и написаны на низкоуровневых языках(внезапно!)
покажите хоть одну ручку, сделанную из перьев и чернильниц
awoland
12.08.2015 11:09+4В Си («C») нет наследования, интерфейсов и пр. Всё вышеперечисленное относится с Си-Плюс-Плюс («C++»). А это несколько более другой язык.
Salabar
12.08.2015 11:13+2Я в курсе. Я именно про то, что ни один другой язык без этой шелухи не обходится.
leschenko
12.08.2015 11:28+9Pascal — очень простой чзык. Обходится без этой «шелухи».
Salabar
12.08.2015 11:39+5А еще он практически мертв и я бы не сказал, что он хоть сколько-то проще Си, если в последнем делать всё по книжке.
leschenko
12.08.2015 11:58+5Его используют для обучения алгоритмизации. При этом не заморачиваясь на особенности самого языка. Свою задачу он выполняет на все 100%.
Вот пример изучения C++ по книге.awoland
12.08.2015 12:04+6Выше уже заметили, что «C» и «C++» — суть разные языки. Не нужно путать. Классический ANSI C будет не сложнее Pascal.
И ещё не стоит смешивать вопросы изучения и знания языка программирования с вопросами знания и изучения фреймворков и стандартных библиотек (API) написанных на этих языках.
The_Floyd
12.08.2015 12:53+3Можно и С использовать не заморачиваясь над особенностями самого языка. В паскале, знаете ли, тоже есть указатели, структуры. Так же, как Вам уже написали, вы очень сильно заблуждаетесь на счет сходства С и С++. Не могу представить что такого сложного для понимания есть в С, чего нету в паскале.
MacIn
27.08.2015 12:04-1В паскале, знаете ли, тоже есть указатели, структуры.
Это значит, что ими можно пользоваться, но не значит, что нужно.
Если в Си мне надо передать переменную, которая будет изменяться, в процедуру, я должен разобраться с указателями. И использовать вырвиглазный дереференс для простого присвоения. Там попутно идет арифметика, Сишное представление массива как указателя на ячейку и т.д. В Паскале же переменная просто передается вовнутрь, нужно указать спецификатор «var» перед именем и все. В некоторых языках, том же Basic, все параметры по умолчанию сквозные — это еще лучше при обучении.
awoland
12.08.2015 12:03+4Pascal — язык, который был придуман и разработан Н.Виртом специально для обучения студентов программированию. Является прямым потомком и наследником Algol.
Salabar
12.08.2015 13:03+5ДЛЯ ОБУЧЕНИЯ Си от Паскаля отличается видом операторов, если объективно. Особенно когда ВНЕЗАПНО окажется, что в Паскале тоже есть указатели и динамическое выделение памяти. На крайняк можно написать маленькую среду, которая будет с помощью Валгринда отслеживать переполнения буфера и прочую няшность и разница испарится окончательно.
stychos
13.08.2015 03:24Ещё мне помнится, там было и вполне себе нормально развитое ООП, с наследованиями и виртуальными интерфейсами. Хотя я тогда ещё пешком под стол ходил, и может борландовский турбо-паскаль седьмой версии — это уже какой-нибудь обджект-паскаль.
MacIn
27.08.2015 11:52Нужно различать разные диалекты П. ООП (действительно, хороший) есть в Турбо-Паскале, интерфейсы (вот тут надо уточнить, какие именно имеются в виду) есть в Дельфи.
stychos
27.08.2015 12:58+1Интерфейсы в турбо-паскале точно уже были. Хотя вот какие именно, действительно надо уточнить.
MacIn
27.08.2015 11:51Особенно когда ВНЕЗАПНО окажется, что в Паскале тоже есть указатели и динамическое выделение памяти
Это значит, что ими можно пользоваться.
А вот строки в Паскале «из коробки» — бесценно при обучении, в сравнении с костылем Си.
DISaccount
12.08.2015 13:34+1Вы даже представить не можете мой восторг, когда я познал отсутствие секции var и ключевых begin и end. Это было первое знакомство с «С».
Alexey2005
12.08.2015 16:37+4Но этот восторг умирает на корню после первого же чужого проекта или библиотеки на C++, которые вы пытаетесь скачать и собрать. Главный плюс Pascal и сред на его основе — отсутствие проблем со сборкой.
Сборка C++ это ад. Нет, это хуже любого ада. Оно настолько негуманоидно, что можно потратить недели, разбираясь, почему же проект отказывается собираться. Вы переберёте все возможные ключи линкера и компилятора, а заодно по 5-6 версий каждого. Вы будете сутками напролёт изучать include-файлы, выясняя, где там что конфликтует или отсутствует. Вы заодно освоите Perl, Python, bash и синтаксис makefile, т.к. половина проектов при сборке умудряется юзать их все одновременно.
И, конечно, каждая неудачная итерация сборки будет отнимать несколько часов (в лучшем случае) времени. Такое ощущение, что всё это специально придумывали, чтоб проект не мог собрать никто кроме создателя.
А в Delphi красота: F9, и всё тут же работает. Даже очень крупные проекты больше 10 сек. не собираются, а простенькие программки до 20к строк вообще стартуют мгновенно.FoxCanFly
13.08.2015 11:29Грамотно настроенный для сборки проект на C++ собирается как нибудь типа cmake [path] && make
speakingfish
14.08.2015 15:57Видимо вы никогда не сталкивались с тем чтобы ваш код работал под delphi и free pascal/lazarus, под windows и linux, под intel и ARM. Поверьте, сложность сборки, работы с include/define, борьба с версиями fpc, легко дорастает до сложности сборки C++.
stychos
13.08.2015 03:25Я сначала также думал. Спустя какое-то время, я немного передумал — всё-таки паскаль в своё время привил хорошую манеру заранее заботиться о потребляемой памяти.
MacIn
27.08.2015 11:56-1begin/end — вкусовщина — меня, например, тошнит от фигурных скобок в Си, но я не выпячиваю это как «недостаток».
Что плохого в секции var? Во всех старых языках переменные объявляются в начале процедуры, до использования. Говорить о том, что «если выделять ближе к месту использования, то нагляднее» не приходится — хорошим тоном считается там, где это возможно, сокращение размера процедур, так что секция var все равно перед глазами.
MacIn
27.08.2015 12:05-1А еще он практически мертв
Именно поэтому Embarcadero регулярно выпускает новый Delphi. Потому что он мертв.
danpetruk
13.08.2015 09:53Передавать массив в си в качестве аргумента методу (или как там он называется) — очень не просто
averkin
12.08.2015 21:04Я, когда только начинал учиться, начал с С++. В процессе изучения, разумеется, реализовывал стандартные темплейты, затем, на их базе, изучал паттерны и проч… Конечно, мои библиотечки с STL не сравнятся, но работали не плохо )
Хорошая школа — С, С++ и т.д., автор прав.
Сейчас пишу на C# и весьма этим доволен.
hMartin
12.08.2015 12:09А мне посоветовали свифт покурить, в качестве заместительной терапии после php. Вот, весь в раздумиях нахожусь.
The_Floyd
12.08.2015 12:55+1Вообще из разных плоскостей языки. Покурите лучше руби с рельсами, или питон с джангой/фляком коль занимаетесь web-разработкой.
hMartin
12.08.2015 13:06Так вроде это тот же ObjC с своими приколами для Mac-dev.
upd: А, понял, вы про назначение языков. Да как раз и хотелось бы поробовать что-то отличное от веба. Посоветовали свифт, так как он, сишарп, джава: «отвечает тенденциям разработки в настоящее время».
burjui
12.08.2015 12:58+1Покурите, почему нет? Но я бы для изучения чего-то нового взял уже более-менее развитый, устоявшийся язык, с большим количеством библиотек. Ничто так не раздражает в молодых языках, как необходимость писать свои библиотеки: бывает, нужно решить относительно небольшую задачу, которуая на какой-нибудь Java решается за час, а у тебя уходит день или два, потому что никто ещё не написал клиент HTTP, библиотеку регулярок или ещё что-нибудь.
hMartin
12.08.2015 13:17Ну, я почему его тут упомянул, это же модифицированный ObjC с обратной поддержкой, так что в крайнем случае можно использоватьбиблиотеки родителя :)
MaximChistov
12.08.2015 13:36с использованием библиотек Objective C там, мягко говоря, проблемы. А еще мой код на нем примерно раз в 1-2 месяца перестает компилиться из-за очередных изменений синтаксиса…
mynameisdaniil
13.08.2015 00:26Покурите, покурите! Сейчас он в моду войдет — будет вам и работа, и документация и библиотеки. К тому же, система типов там прямо таки вытащена из Хаскелля ну и много других плюшек есть которые тщательно скрыты чтобы не пугать новичков. Освоите — потом в других нормальных языках легче будет.
Стоит так же заметить, что сам я не сварщик и свифт видел пару раз краем глаза у коллеги на компьютере, но этих пары раз мне хватило чтобы впечатлиться.
nehaev
12.08.2015 13:02+4Призывы что-то изучать — это хорошо, но не отменяет того факта, что статья крайне слабая.
По перечисленным признакам «семейства Си» (фигурные скобочки, статическая типизация, ООП) отвергнутая с порога Scala подходит больше, чем глава семейства :)
Зная C# легче разобраться с Java? И все потому, что оба этих языка принадлежат с «семейству Си»? А не потому ли, что они созданы для решения схожих задач и в них заложены одни и те же парадигмы? Кстати, зная C#/Java легко разобраться и в Python, и в JavaScript, а вот насчет сходу разобраться в C/C++ я совсем не уверен.
Вибираем язык по рейтингам? Ну так рейтинги надо смотреть в динамике. По графикам TIOBE видно, что многолетний тренд для языков «семейства Си» — на спад. Может наоборот стоит посмотреть на не так широко используемые в настоящее время языки, чья популярность стремительно растет?
nagato
12.08.2015 14:24+4Абсолютно не согласен с высказыванием о том, что знание си-подобного языка помогает перейти к новой парадигме, особенно к функциональной — для этого требуется совершенно иной способ мышления, который никак не поощряется императивными языки вроде си.
Pilat
12.08.2015 15:56+8Ни C#, ни Java не являются языками «Семейства С» никаким боком. То, что синтаксис похож — так он и у Perl и PHP похож.
«В качестве очень грубого определения можно сказать, что язык относится к семейству С, если в нём для выделения функциональных блоков используются фигурные скобки {}.» Гениальное определение.
С отличается от других языков тем, что имеет дело с физическими объектами. Целое число — это процессорное целое, строка — это байты. В C# и Java (и в некоторых других перечисленных) это объекты. C ценен тем, что позволяет программировать в терминах процессора, и опыт программирования на С позволяет, например, оценить затраты на упрощения, доступные в других языках.
«Если вы освоите один из языков семейства С, то это даст вам понимание фундаментальных основ программирования: переменных, значений, типов, присваивания, выражений, функций, параметров, возвращаемых значений, потока команд и т.д.» — всё это можно узнать из других языков. Но только C позволит понять, что такое на самом деле функция, что такое тип и что за ним лежит, как устроены параметры и передаваемые значения.
Ну и напоследок — между С и Java общего нет практически ничего. Кроме скобок.
random1st
12.08.2015 18:46+3Надо изучить ассемблер, чтобы получать кайф от С. Надо выучить C, чтобы получать кайф от Python. Надо выучить Python, чтобы получать кайф.
dom1n1k
12.08.2015 19:38+3Мне например Питон очень симпатичен на стерильных примерах из учебников, но когда я вижу образцы реального кода современных фреймворков и всего такого — он отторгается. Отвратительно, мусорно, нечитаемо и так далее. Я не понимаю эту кашу.
lightman
12.08.2015 22:05+1Хм, впервые вижу такой негативный отзыв об языке, который из кожи вон лезет, чтобы быть простым и читабельным.
Может быть вас смутило отсутствие типов?dom1n1k
12.08.2015 23:42Нет, именно визуально — каша.
Я не могу читать вот такое, мне скобки нужны! И операторные, и в логическом выражении.
if self.request.cookies is not None and name in self.request.cookies: return self.request.cookies[name].value
Раздражает обильное использование символа подчеркивания (кэмел мне милее).
Невероятно бесит манера комментировать функцию (строк на 10-15!) внутри её тела, а не перед.
Куцое словечко def теряется и замыливается — то ли дело человеческая function.
Я бы сказал, что Питон изо всех сил стремится к краткости, но краткость != удобочитаемость. Если из русского текста убрать все знаки препинания — получится короче, но совершенно нечитаемо. Кстати, примерно тем же, но в ещё более адской форме занимается CoffeeScript — там просто тихий ужас :)ef_end_y
13.08.2015 00:26+1(В питоне есть скобочки, но (если они не нужны), они опускаются) и читать становится проще
dom1n1k
13.08.2015 02:47То что скобки есть в самом языке (естественно, они там есть!) мало что дает, потому что в питоновой практике их принято опускать везде, где можно. То есть имеется стандарт де-факто.
Идти против шерсти и в своих файлах ставить их везде? Глупо. И сам в сообщество не интегрируешься (чужой-то код читать все равно надо), и оно тебя отторгнет.
DmitryAnatolich
13.08.2015 00:26+3мне скобки нужны!
Логические — сколько угодно. А операторные? Я вот заколебался писать паскалевские BEGIN-END при писанине процедур T-SQL. Если бы можно было обойтись отступами — код бы сократился на четверть точно. Про читаемость просто молчу.
кэмел мне милее
а андерскор читаемее. Ну_правда_ведь. НеТакЛи?
def теряется
Выберите себе подходящую цветовую тему в IDE. Что? В блокноте как? Ну, скажем, Вирт в Обероне сделал обязательным верхний регистр в операторах — чтобы ч/б листинги были читаемее.dom1n1k
13.08.2015 01:12+2begin-end это было в прошлом веке. Сегодня как-то более распространены {}
Андерскор не читаемее, потому что:
а) Когда его много, рябит в глазах в целом.
б) Он сильно «интерферирует» со знаком равенства (ну то есть присваиванием).
в) Хуже читаемость цепочек объектов/методов. Случайный пример из Flask:
Подчеркивание создает визуально бОльшую дырку, чем точка, поэтому в такой строке stack.top или functions.append сливается в одно слово, а на _ расспается на сегменты. Получается наизнанку._request_ctx_stack.top._after_request_functions.append(f)
Как установить свою цветовую схему на гитхабе?DmitryAnatolich
13.08.2015 06:12не читаемее
Но, по-моему, всё-таки, всё субъективно, ко всему привыкаешь. Опять-таки, Гвидо не придет к вам с топором, если вы будете использовать camelCase (наверное). Впрочем, к использованию Python, если подчеркивания так уж рябят, также никто не принуждает.
(Занудство: люди на ассемблере пишут, и ничего у них не рябит. Про Лисп с его тучей скобок вообще молчу. А всё почему? Потому что цветовая схема правильная.)
Как установить свою цветовую схему на гитхабе?
Можно как-нибудь так. Может, есть способ и поприличнее.
ef_end_y
13.08.2015 11:43+1ну, я сконвертировал ваш пример: requestCtxStack.top.afterRequestFunctions.append(f)
легче стал читаться?)
JIghtuse
13.08.2015 10:54Куцое словечко def теряется и замыливается — то ли дело человеческая function.
Подсветка синтаксиса вас спасёт. В некоторых языках вообще нет ключевого слова для обозначения функции — люди пользуются.
Раздражает обильное использование символа подчеркивания (кэмел мне милее).
Это фломастеры разного цвета. snake_case часто используется в Си, и на мой взгляд приятнее читается.
Насчёт примера. Не скажу, что всегда можно исправить, но в данном случае можно сделать как-нибудь так:
if self.request.cookies is None: return default return self.request.cookies.get(name, default)
Три строки вместо одной, но читабельнее.JIghtuse
13.08.2015 11:02+1Вообще в Python много мест, которые можно записать очень просто, но в силу незнакомства программистов со стандартной библиотекой код часто выглядит сложнее. Пример из Python Cookbook:
d = {} for key, value in pairs: if key not in d: d[key] = [] d[key].append(value)
С использованием defaultdict:
d = defaultdict(list) for key, value in pairs: d[key].append(value)
dom1n1k
13.08.2015 18:37snake_case смотрится нормально в языках, где не используются очень сложные и ветвистые объектные модели. C/C++ как раз такой.
А если в языке цепочки из 3-5 свойств/методов является нормой (JS, С#, Java, VB) — там сразу подчеркивания лучше свести к минимуму.
Turbo
13.08.2015 01:12-1Мне кажется для обучения нужно что-то нетипизированное, без контроля за памятью типа PHP или Python. И их проще применить на практике — типа сайтик свой склепать. А там где практика там и интерес к дальнейшему развитию в этом направлении. К Си сложнее привить интерес у обучающихся, как мне кажется.
З.Ы. Сам начинал с Паскаля и Си.VolCh
13.08.2015 07:31+1Python — сильно типизированный язык, а C и PHP — слабо типизированные.
Python и PHP — языки с автоматическим контролем любой памяти, а C — с ручным контролем для динамически выделяемой.
Основная разница между Python и PHP с одной стороны и C с другой — первые интерпретируемые с динамической типизацией, а последний — компилируемый со статической.
VolCh
13.08.2015 16:46+1Слышал выражение «Си-образные языки», где главный упор на сходстве скобочек, основных конструкций контроля потока выполнения, вычисления выражений. Кроме упомянутых к ним однозначно относятся Javascript и PHP.
masai
15.08.2015 13:59-1Несмотря на то, что я сам довольно много пишу на C и на языках с унаследованным синтаксисом, полагаю, что для первоначального обучения этот язык подходит плохо. Попробую объяснить причины. Ещё раз обращу внимание, что речь идёт о первоначальном обучении. Для профессиональных программистов требования будут совсем другие. И им определённо стоило бы выучить C хотя бы для общего развития.
0. Для начала надо определиться с тем, чему мы хотим обучить человека в его первом (и явно не последнем) курсе программирования. Нужна цель. Обычно это какие-то самые базовые знания: понятие данных, понятие алгоритма, алгоритмические конструкции, способы взаимодействия фрагментов кода и так далее.
1. Глубокое знание архитектуры компьютера на этом этапе будет только отвлекать. Первый курс какого-то естественного языка начинается с алфавита, а не с изучения культуры страны. Тут цель — научить сказать сперва хоть что-то, а не сразу стать Шекспиром/Шиллером/ещё кем-то. В C есть указатели, которые могут запутать новичка. Для их понимания нужно знать, что да как располагается в памяти компьютера, а это отвлекает от алгоритмов. Да, это важные знания, но должны ли они быть первыми важными знаниями, которые изучит человек? Как мне кажется, нужно брать более высокоуровневый язык. Пример более подходящего языка: Pascal (высокоуровневое программирование, но при желании можно и указателями воспользоваться).
2. Без указателей и выделения памяти в C не поработаешь толком с массивами. Одно неверное движение и программа работает не так, как надо. Как нет и сложных структур данных в стандартной библиотеке, таких, как словари, списки и так далее. Даже строк как отдельного типа в C нет. Порог вхождения новичка в структуры данных значительно повышается: вместо изучения того, как их применять, ему придётся сидеть с карандашом и аккуратно рисовать стрелочки-указатели. Это, безусловно, полезно, но изучить внутреннюю организацию структур данных можно и потом, когда уже понимаешь, что это, для чего нужно и какие требования к структуре предъявляются на практике. Пример более подходящего языка: Python (списки, словари, строки — естественная часть синтаксиса).
3. Если выбрать достаточно сложный или запутанный язык, то его синтаксис будет только отвлекать. Я помню, когда я учился в школе, у меня первое время не было учебников по C и Pascal, но я брал в библиотеке книги, в которых были программы на этих языках. Так вот, программы на Pascal я понимал не зная языка, а программы на C были для меня набором закорючек, пока я не выучил язык (довольно быстро, справедливости ради). В C есть ещё такая штука как undefined behavior. Да даже конкурс есть по непонятному программированию на C. Профессионалы опасные места знают и обходят уже подсознательно, новички — нет. Поэтому желательно, чтобы синтаксис языка не был двусмысленным. В идеале он вообще должен быть незаметен и минимизирован, чтобы рассказать один раз о нём и не возвращаться больше. Пример более подходящего языка: Scheme (из синтаксиса только скобочки, но тем не менее, в SICP эти скобочки довольно сложные вещи делают).
4. Важный момент при обучении программированию — наличие учебной литературы подходящего уровня. На постсоветском пространстве в школах был популярен Pascal (хорошо это или плохо обсуждать не будем), поэтому в книжках по решению олимпиадных задач фигурирует чаще всего именно он. Не то, чтобы авторы всегда были этому рады: то, что в другом языке делалось бы одной строкой, в нём иногда занимает несколько. Например, обращение порядка элементов массива. Или создание списка. Но если, скажем, школьник готовиться к олимпиаде, то Pascal он должен знать. Есть неплохая книжка у Вирта «Алгоритмы и структуры данных», в которых на пальцах про эти самые структуры данных и алгоритмы рассказывается. Это, конечно не Кормен и др. по уровню, но и целевая аудитория у неё другая. К слову, у Кормена псевдокод используется, а Кнут вообще взял ассемблер для несуществующей машины. Книжки про алгоритмы или олимпиадные задачи с примерами на C, конечно, есть. Но они обычно рассчитаны на человека, уже знакомого с программированием.
Язык C нужно обязательно изучать: он очень распространён, похожий синтаксис часто встречается, он относительно прост и позволяет понять многие важные концепции. Но на роль первого языка он подходит не очень хорошо.
Но я хочу сказать этим ответом вовсе не то, что C — плохой язык. Я лишь пытаюсь обратить внимание на то, что сначала нужно хорошо понять, а чему вообще нужно учить. И уже тут, в формулировке целей и требований, задолго до обсуждения языка, есть много спорных вещей. Я сформулировал свой взгляд на вещи, основанный на опыте (в том числе и обучения новичков), но он на истину в последней инстанции не претендует.
Буду рад конструктивным возражениям. Давайте вместе попробуем сформулировать цели первого курса программирования.speakingfish
15.08.2015 22:23+3Так вот, программы на Pascal я понимал не зная языка, а программы на C были для меня набором закорючек, пока я не выучил язык (довольно быстро, справедливости ради). В C есть ещё такая штука как undefined behavior.
В pascal вся работа с динамическими массивами — undefined behaviour. Только интерфейсами можно нормально пользоваться, но они с подсчётом ссылок. Как научить начинающего разруливать циклические ссылки? Для этого надо объяснять правила работы с указателями, правила организации древовидных структур и прочее. В результате уровень сложности начинает превышать сложность использования умных указателей в C++. Поэтому pascal не может быть языком начального уровня.
Для начального уровня нужно что-то со сборщиком мусора, отсутствием необходимости работы с указателями и нетребовательное к изучению 100500 сложных правил использования.
Лучше python или javascript, но javascript можно даже не учить специально — он в любом случае понадобится.
Java не подходит. В Java начинающий легко пишет:
protected Boolean active; synchronized(active) { }
Pascal же стоит, как и basic ранее, объявить языком, калечащим молодые умы.
zorge_van_daar
Нет бога кроме Ричи и Страуструп пророк его!