Главная страница раздела для программистов-любителей
Я начал приходить к мысли, что указатели в С++
позволяют оперировать с данными, минуя необходимость называть их по имени "Ваше
превосходительство Переменная Икс". Ведь называние по имени заставляет комп
лезть сперва в область памяти, где машине разъясняется, что Переменная Икс живёт
там-то и там-то... А только потом уже комп получает в своё распоряжение само
значение Генерала Икса. Это без указателей очень медлительно, ВЕРНО?
Нет не верно. Во всяком случае не совсем. Твое мышление очень мне знакомо. Еще
студентом я даже считал что если переменную обозвать короче, то и программа
станет выполняться быстрее. Это для смеха.
Основная ошибка не нужно так заботиться об эффективности программы (скорость и размер памяти) на раннем этапе не важен. Будешь ты пользоваться указателями или нет повлияет на эффективность программы очень минимальным образом. Всю возможную на этом этапе оптимизацию с лихвой "выберут" современные компиляторы. Если уж очень будет важно, задашь нужные оптимизирующие ключи при компиляции. Уверяю тебя в 99.9% реальных задач про это даже не охота вспоминать.
Главное, на что можно нацелиться в вопросе эффективности, это сам алгоритм. Например твой mp3 [популярный формат сжатия музыки] компрессор станет существенно эффективнее, если ты заменишь в нем вейвлетный алгоритм, скажем, на фрактальный [вейвлет, фрактал математические термины]. Или на применяемую технологию скажем, предложишь решить задачу на серверной стороне, вместо клиентской. Эти вопросы в разы более важные, чем оптимальность ссылок в коде.
Про скорость ссылок позаботились архитекторы процессора. Сейчас процессоры пашут в параллельной моде. Например для того чтобы сложить два числа C = A + B тебе нужно сначала выполнить их адресацию. Т.е. выбрать из памяти значения А и Б. Потом перегнать их в регистры процессора, потом сложить и результат засунуть обратно в память. Все это будет сделано за один такт процессора. Ибо понятно, что, например, выборку адресов можно проводить в параллель. Более того если за этой командой стоит что то вроде F = D + Е, то и это второе сложение в современном процессоре будет выполнено в параллель с первым. Конечно не везде процессор такой умный. Не всегда все можно распараллелить. Но очень многие такие очевидные вещи в процессоре делаются. Там есть специальный блок "предсказатель", который только и "смотрит вперед" на программу и занимается предсказанием чего бы там еще распараллелить. К тому же команды адресации делаются уж очень быстро.
Главное на что нужно нацелиться это удобство программирования, понимая под
этим быструю отладку, последующее сопровождение и модификацию кода. Поэтому если
нужно называть переменную, лучше ее назвать длинно, хорошо и понятно, не думая о
том насколько ее сложно будет представить в памяти компьютера. Об этом пусть
пекутся компилятор и процессор. Будут медленно работать купим новые.
PL-11 это очень старый и редкий язык, забудь про него. Был разработан в Церне. Его разработчик высказал фразу, которая мне очень запомнилась. "Мы говорим и пишем на полноценном (русском или английском) языке, почему же мы должны программировать на ломанном"?
Поэтому всегда думай про то что твою программу будет читать человек, а не компилятор. Компилятор есть программа и ее никто не спросит. Зато я, будучи обязанным поддерживать твой код, измучаюсь, если он будет плохо читаем. И что еще хуже пожалуюсь начальнику чтобы тебя уволили, за плохо написанный код ;) Ссылки и указатели не удобны потому что они вносят массу непонятностей, не для компилятора, а для человека, модифицирующего код. (Обычно им будешь ты сам, так что помни, что для себя стараешься).
Попробую привести пример наиболее часто
встречающейся ошибки из за использования указателей. Я такую проблему называю
"наступить себе на хвост". (Частая проблема при переносе кода с фортрана на С.)
------------------------------------------
Скажем ты размещаешь массив в памяти.
int pA[100]; // традиционно в C
int* pA = new int[100]; // или аллокацией памяти в C++
Потом где то в программе используешь этот массив таким образом.
int temp = pA[i];
А пользователи, скажем, жалуются что программа иногда падает. Очень долго ругая
того програмиста (его уже уволили), выясняем, что иногда(очень редко)
переменная i где то выше по тексту программы может принять значение 100.
(в С/C++, адресация считается с 0). Ну ошибся тот програмист,
(наверное Фортран очень любил, где адресация считается с 1).
Да бог с ним, человек имеет право на ошибку. Проблема в том что мы
потратили неделю на отладку и поиск причины. Все это время
пользователь ждал.
------------------------------------------
Теперь приведу пример когда програмист не поумнел,
но зато новый принцип
програмирования просто не дает ему сделать ошибку.
Вместо того чтобы использовать простой массив в памяти, мы используем
объект Array, специально для этого предназначенный.
Примерно так:
Array accountList = new Array(100);
int currentAccount = accountList.getElementAt(i);
Если вдруг в программе индекс i превысит 99, мы сразу получим
исключение и подробный вывод на экран. Это сделает для нас,
метод getElementAt(...) объекта Array.
Заметь, сейчас программа стала значительно сложнее, потому что
нам нужно еще запрограмировать сам объект Array.
А его метод getElementAt(...) так и вообще должен быть достаточно умным
чтобы проконтролировать превышение заданных границ массива.
Ну что то вроде:
if( i < 0 || i > 99 )
writeWarning("Error: The array is limited ....");
Тут мы превысили всякие лимиты на экономию памяти и ссылок. Наш код стал
этак в 10 раз длиннее и в 2 раза медленнее. Ну и ладно!
Зато (даже ценой снижения производительности программы) мы добились того
что еще на этапе разработки, сам разработчик заметил свою ошибку и устранил ее.
Потом мы использовали этот новый объект и переписали программу
заменив все массивы на объекты Array. При этом мы выловили еще кучу ошибок
предыдущего програмиста. Ибо он катастрофически мыслил по фортрановскому,
и везде превышал границы массивов.
В промышленном програмировании это оказалось гораздо важнее, нежели скорость
работы неправильно работающей программы. А клиенту мы посоветовали купить
процессор по мощнее, и передали новую программу. (Только уже на CD вместо
дискетки ;)
Вот так, мы отказались от эффективной и быстрой ардесации через [] оператор.
Может быть это не самый очевидный пример. Скорее он демонстрирует
преимущество объектного подхода. Ну как смог... Пример был на C++,
где за ссылками и указателями нужно следить самому. Но нектороые современные
языки
автоматически избавляют програмиста от этих хопот, просто запрещая
использование указателей в принципе.
GOTO
Нет таких книжек, где бы эту тему не обсуждали основательно. Классически
доказано что процедурный язык может быть самодостаточным без переходов GOTO.
Однако есть практика... А практика показала что так или иначе GOTO используется
везде. В первой версии JAVA не было GOTO. И одним из первых же требований к
совершенствованию языка было добавить этот оператор. Тут скорее реализуется
жизненный принцип: не может быть правил без исключений. А может быть люди не
совершенны, и им трудно отказаться в мыслях от GOTO. (они наверное все в прошлом
Фортранисты). Я использую оператор GOTO в единственном месте.(наверное так и не
переучился).
Если внутри цикла случается сложное условие.
for( int i = 0; i < 10; i++ )
{
if( что_то_нетак )
goto oops;
}
oops:
Конечно это можно было бы засунуть и в само условие
for(int i = 0; i < 10, что_то_нетак; i++ )....
Но это как то не читаемо.
ООП, которое наверное не скоро устареет...
ООП на наш век хватит. А там может быть машины самопрограмироваться начнут. Вот
тогда я пойду на улицу с гитарой... Сейчас ООП вещь просто необходимая. Может
быть первокурсникам еще есть время изучать Паскали и Алголы, чтобы потом
мучительно перестраивать свои мозги, но нам 40-летним, пора отбросить всякую
требуху и изучать сразу лучшее что достигло человечество.
ООП это в первую очередь другое мышление. Мир конечно устроен значительно сложнее, но лучшее что достигла человеческая мысль это разбивать реальный мир в нашем представлении на отдельные части объекты.
Объект это некоторая сущность, которая имеет свои СВОЙСТВА, определенное ПОВЕДЕНИЕ и жизненный ЦИКЛ. Например, бабочка это объект. У нее есть свойства быть красивой или легкой. Есть поведение она может летать, если ее спугнуть. Ее жизненный цикл 2 дня. Человек, машина, болт все это объекты.
Страутсруп[автор С++ расширения] первым понял, что программируя, мы всего лишь стремимся отразить в компьютерах окружающую нас реальность. И поэтому он ввел объектное расширение в С. Честь ему и хвала! А нам уже не нужно изучать старый С. Нужно начинать сразу с плюсов (++), чтобы сразу начать правильно мыслить. Когда мысль поставлена правильно уже не важно на чем писать С++ или Java (Кубейс или Сонар ;). [Кубейс и Сонар популярные музыкальные редакторы]
Я мечтаю когда-нибудь выучить Дональда Кнута[автор теории структур данных]...
Зачем его учить, он же не поэмы писал. К тому же все его умные структуры
данных давно запрограммированы в библиотеках. Например, тот же Array, который
может быть с контролем переполнения или без, с хешированием Б-деревьями, или еше
как.
Я ничего не отвергаю, читать классиков надо, но я сторонник практики. Вот
будет задача где без связного списка никуда, вот тогда и нужно взять с полки
Кнута.
Стыдно признаться, не знаю чем портал отличается
от сервера... Сервер это надёжный комп (даже порой не один) с гигантской
надёжной памятью?
Знаешь, в программировании как и в других областях человеческой деятельности.
Есть суть, а есть религия. Я считаю такие понятия как портал это религия.
Просто однажды чтобы выделиться из общей массы одному в голову пришло назваться
не рядовым Web сервером, вроде www.qqq.ru. А громко так www.yandex.ru интернет
порталом! Суть от этого не изменилась. Но как красиво стало вместо
бортпроводника стюардесса !
Но рано или поздно количество переросло в качество. Так что портал это уже сумма серверов и технологий, тут есть и сервер базы данных, и сервер приложений, на котором всякие портлеты-сервелеты крутятся, и почта и регистрация пользователей, и интернет магазин, и синхронное обновление информации. Ну и прочие понятия. Согласись, это уже не совсем веб-сервер, это нечто большее. Не просто молитва, но смысл жизни верующего.
к оглавлению раздела для программистов