Может быть. На данный момент я пишу C исключительно, потому что работаю снизу вверх. У меня есть куча времени, чтобы убить, прежде чем я поступлю в колледж, поэтому я подумал: я мог бы (хотя бы в некоторой степени) хорошо разбираться в архитектуре программного обеспечения, прежде чем начать. Это делает (в некоторых случаях) концепции более высокого уровня более легкими для изучения, повышает вашу способность решать проблемы и т. Д. Когда я был намного моложе, я изучал PHP и VB6. Когда я перешел на C и сборку, мне было тяжело понять, что «строка» - это не одно значение, а массив отдельных значений - и я не мог просто сравнить одно с другим - я приходилось обходить каждый массив символов и находить разницу - и т. д. Такие мелочи заставили меня переосмыслить и заново понять, как на самом деле работают компьютеры. Я имею в виду, до того, как я обнаружил эту вещь о строках - я думал, что регистры процессора совершенно бесполезны (как вы могли бы поместить что-нибудь полезное в 32 бита!?).
При этом я могу поболтать о потенциальных выгодах изучения низкоуровневого программирования, несмотря на то, что вы никогда не будете его использовать. Но для меня, неважно по какой причине я придумаю - это в основном для общего интереса. Я думаю, что C это весело, и чем больше я добиваюсь этого, тем лучше я чувствую свои навыки. Если вы не нашли большого интереса в изучении таких вещей, как переполнение стека, вычислительная математика, низкоуровневое управление памятью (недействительные или нулевые указатели, повреждение и фрагментация кучи и т. Д.) И т. Д., - тогда нет никаких гарантий вы действительно выиграете от этого. Но вы могли бы.
Если вы изучите C, чтобы узнать об архитектуре - и о том, как на самом деле работает под капотом - возможно, попробуйте то, что я делаю. Я часто компилирую в ассемблерный код, чтобы увидеть, как компьютер на самом деле справляется с тем, что я прошу. Чтобы увидеть каждый отдельный шаг, который делается для каждой задачи. Собственно, так я и понял разницу между char *a = "a string"
и char a[] = "a string"
. Однако лучшим преимуществом для вас будет понимание того, насколько безобидными являются языки высокого уровня: P.
Для записи - каждому процессу дается стек вызовов. Это блок памяти, который имеет заранее определенный размер. Используется в основном для локальных переменных. Каждый раз, когда вы создаете локальную переменную, ее содержимое добавляется в конец стека - и когда функция возвращается (и эти переменные выходят из области видимости), эти данные отбрасываются. Переполнение стека происходит, когда в конец стека добавляется слишком много материала, и вы переполняете предварительно выделенное пространство памяти. Обычно это происходит в результате размещения ОГРОМНЫХ объектов в стеке или слишком большого количества рекурсии (функция, вызывающая себя сама). Также я думаю, что если вы просто слишком запутались в вызовах функций внутри вызовов функций, что в основном (в данном случае) совпадает с проблемой рекурсии.