ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
19 апреля
709456 Топик полностью
Ксения (30.10.2016 04:31 - 09:59, просмотров: 200) ответил Evgeny_CD на Самый обычный С++. Я говорю не о версии языка и (или) компилера, я говорю о методичке для программиста - так кодь, так не кодь.
Не встречала такой книги, где бы суть C++ была ясно описана. А книга Стауструпа - вообще гадость, только мозги засирает разбором экзотических случаев. Лично у меня в свое время "ломка" была от попытки C++ постичь :). Сколько ни читала про функции члены класса и им дружественные, тем темнее становился смысл, т.е. все эти новые определения и объекты ссылались в своих определения на себе подобные, но ни на что-либо из обычного C. Из-за этого порог понимания казался непреодолимым, т.к. объяснения не вытекали из предыдущего знания. Ситуацию еще сильнее усугубляло то, что у меня мышление "процедурное", т.к. мне для понимания языка нужно знать, какие действия та или иная инструкция совершает. А в случае C++ уцепиться было не за что. И это тягостное состояние продолжалось у меня до тех пор, пока меня не осенило, что весь этот С++ ООП ... вообще не выполняют никакого кода, а нужен лишь для "оформления". Сейчас я уже понимаю, что в строгом смысле это не так, но тогда это было катархисом прозрения :). После чего дело быстро сдвинулось с мертвой точки. Сейчас я вам расскажу суть C++, которая мало чего общего имеет с книжными объяснения. И вовсе не потому, что я считаю, что языка C++ вы до сих пор не знаете, а исключительно потому, что для точности формулировок я очень долго вызревала, хотя пользовалась C++ во всю. Как-то один сослуживец (большой ученый в возрасте, но ранее никогда не занимавшийся программированием) спросил меня: "Вот я изучаю учебник по Бэйсику, мне всё в этих объяснениях понятно, только одного в толк взять не могу - зачем нужны циклы? Не понимаю, мол, какой смысл считать одно и тоже, если оно с первого раза уже рассчитано". А ведь, как бы ни был смешон этот вопрос для программиста, он является фундаментальным, т.к. именно использование циклов отличает программу от калькулятора. Все мы понимаем, что циклы имеют смысл только потому, что существуют массивы однородных данных, которые можно выбирать из массива по порядковому номеру/индексу (есть исключения, но сейчас речь не о них). В этом кроется суть всей идеи программирования, когда решение задачи сводится к "обработке по частям", сводимая к тому, что некая процедура выполняется на движущемся конвейере, роль которого играет указатель или индекс, перемещающийся вдоль массива. Однако расплатой за это явилась однородность элементов массива, т.е. нельзя взгромоздить на конвейер детали разного габарита и требующие разной обработки. По этой причине в языках программирования со временем укоренились структуры, объединяющие в одной области/блоке памяти разнородный набор данных. И сделано это было в основном для того, чтобы заменить элементы массива структурами, а далее работать уже с массивом структур. Тем не менее, полностью обойти требование однородности данных этим методом не удавалось, т.к. для работы с массивом все равно требовалось, чтобы его элементы имели одинаковый размер (чтобы можно было легко вычислять смещение). Из-за этого структуры приходилось заводить на максимальный размер, хотя в каких-то случаях многие поля в структуре были избыточными. Типа того, как в анкете многие поля вынуждено остаются пустыми, если девичью фамилию не меняла и родственников на оккупированной территории не имела :). Так вот C++ это и есть очередная попытка преодолеть трудности перечисления. В этом случае однородность перечисляемых данных уже не требуется, но симулируется искусственными приемами (а в C# она уже и приемами не симулируется). Суть симуляции в том, что структуры строятся на форме базового класса/структуры (самого короткого, а то и совсем пустого варианта), расширяясь вниз. Из-за этого адрес любой такой структуры численно всегда совпадает с адресом базового блока, с которого она начинается. Это сделано было только для того, чтобы, независимо от размера и сложности структур, указатель на них всегда можно было сделать одного типа (по типу базовой структуры/класса), чтобы потом перечислять их в цикле, как будто-то бы они однородные. А еще для пущей однородности было разрешено вставлять в эти структуры кроме данных еще и код (хотя сам код все-таки хранится не в самой структуре, а размещался компилятором где-то на стороне). После этого структуры превратились в классы, т.е. структуры с кодом функций, обслуживающих специфику набора полей данной конкретной структуры. Таким образом, проблема работы с неоднородными данными с C++ эффективно решается, хотя за это тоже приходится расплачиваться. А расплата такова. Во-первых, структуры, ставшие классами, приходится аллокировать динамически, для чего приходится заводить некий дополнительный пул памяти, т.к. стеки для этой цели не годятся. При работе с микроконтроллерами это довольно противно, т.к. отъедается память, которой у микроконтроллера обычно мало. От частых запросов у динамической памяти блоков и возврата их после окончания использования, область динамической память рискует стать настолько "фрагментированной", что потом получить от нее большой непрерывный кусок уже не получится. Поэтому эту память приходится на ходу дефрагментировать (обычно за счет времени выполнения функций аллокации и деалокации), что непроизводительно тянет время. Во-вторых, перечисление приходится вести не по индексу, а по указателю. А потому приходится либо создавать массив для адресов перечисляемых экземпляров классов, либо использовать для перечисления "итераторы" - механизм, обычно возложенный на базовый класс, когда каждый новый порождаемый экземпляр класса запоминает, за кем он стоит в очереди :), а потом сообщает свой собственный адрес тому, кто займет очередь за ним. Все это может показаться противным (тем более что оно таким и является :)), тем не менее, программировать в среде Windows GUI (это там, где не консольные команды, а разные кнопочки, галочки и ползунки мышкой двигаешь), иначе просто невозможно. Т.е. речь идет даже не об удобстве C++ над C в подобного рода проектах, а именно о том, что без С++ их совершенно не осилить (за исключением разве что совсем простых случаев с единственным диалоговым окном). А при программировании микроконтроллеров я C++ не пользуюсь, т.к. те у меня они обычно мелкие - АВРки.